diff --git a/.github/workflows/shared-component-publish.yaml b/.github/workflows/shared-component-publish.yaml index be8abe3760..2df2d7a652 100644 --- a/.github/workflows/shared-component-publish.yaml +++ b/.github/workflows/shared-component-publish.yaml @@ -21,8 +21,14 @@ jobs: cache: "yarn" node-version-file: ".node-version" registry-url: "https://registry.npmjs.org" - env: - NODE_AUTH_TOKEN: ${{ secrets.ELEMENT_NPM_TOKEN }} + + # Ensure npm 11.5.1 or later is installed + - name: Update npm + run: npm install -g npm@latest + + # Need to setup element web too as it needs the translations + - name: 🛠️ Setup EW + run: yarn install --pure-lockfile - name: 🛠️ Setup # When running `install` it also calls the `prepare` step which generates @@ -31,4 +37,4 @@ jobs: - name: 🚀 Publish to npm working-directory: packages/shared-components - run: npm publish --access public --provenance + run: npm publish --access public --tag test --provenance diff --git a/.github/workflows/shared-component-visual-tests.yaml b/.github/workflows/shared-component-visual-tests.yaml index 6462fb82dd..0377c96c7f 100644 --- a/.github/workflows/shared-component-visual-tests.yaml +++ b/.github/workflows/shared-component-visual-tests.yaml @@ -34,10 +34,6 @@ jobs: - name: Install element web dependencies run: yarn install --frozen-lockfile - - name: Build Element Web resources - # Needed to prepare language files - run: "yarn build:res" - - name: Install dependencies working-directory: packages/shared-components run: yarn install --frozen-lockfile diff --git a/.github/workflows/static_analysis.yaml b/.github/workflows/static_analysis.yaml index fff80c4008..60f03ead5c 100644 --- a/.github/workflows/static_analysis.yaml +++ b/.github/workflows/static_analysis.yaml @@ -35,10 +35,6 @@ jobs: - name: Typecheck run: "yarn run lint:types" - - name: Build Element Web resources - # Needed to prepare language files for shared components - run: "yarn build:res" - - name: Install Shared Component Dependencies run: "yarn --cwd packages/shared-components install" @@ -91,10 +87,6 @@ jobs: - name: Run Linter run: "yarn run lint:js" - - name: Build Element Web resources - # Needed to prepare language files for shared components - run: "yarn build:res" - - name: Install Shared Component Deps run: "yarn --cwd packages/shared-components install --frozen-lockfile" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f89db70318..4fd5f4f633 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,8 +29,8 @@ env: permissions: {} jobs: - jest: - name: Jest + jest_ew: + name: Jest (Element Web) runs-on: ubuntu-24.04 strategy: fail-fast: false @@ -93,13 +93,13 @@ jobs: complete: name: jest-tests - needs: jest + needs: jest_ew if: always() runs-on: ubuntu-24.04 permissions: statuses: write steps: - - if: needs.jest.result != 'skipped' && needs.jest.result != 'success' + - if: needs.jest_ew.result != 'skipped' && needs.jest_ew.result != 'success' run: exit 1 - name: Skip SonarCloud in merge queue @@ -112,3 +112,56 @@ jobs: context: SonarCloud Code Analysis sha: ${{ github.sha }} target_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + + jest_sc: + name: Jest (Shared Components) + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + with: + repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }} + + - name: Yarn cache + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6 + with: + node-version: "lts/*" + cache: "yarn" + + - name: Install EW Deps + run: "yarn install" + + - name: Install Shared Component Deps + working-directory: "packages/shared-components" + run: "yarn install" + + - name: Jest Cache + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: /tmp/jest_cache + key: ${{ hashFiles('**/yarn.lock') }} + + - name: Get number of CPU cores + id: cpu-cores + uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2 + + - name: Run tests + working-directory: "packages/shared-components" + run: | + yarn test \ + --coverage=${{ env.ENABLE_COVERAGE }} \ + --ci \ + --max-workers ${{ steps.cpu-cores.outputs.count }} \ + --cacheDirectory /tmp/jest_cache + env: + # tell jest to use coloured output + FORCE_COLOR: true + + - name: Upload Artifact + if: env.ENABLE_COVERAGE == 'true' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + with: + name: coverage-sharedcomponents + path: | + packages/shared-components/coverage + !packages/shared-components/coverage/lcov-report diff --git a/.gitignore b/.gitignore index 89247a57a3..3d6d723ac3 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ storybook-static /packages/shared-components/node_modules /packages/shared-components/dist +/packages/shared-components/src/i18nKeys.d.ts diff --git a/jest.config.ts b/jest.config.ts index e6c29b792d..46a40d4a2e 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -17,7 +17,7 @@ const config: Config = { // This is needed to be able to load dual CJS/ESM WASM packages e.g. rust crypto & matrix-wywiwyg customExportConditions: ["browser", "node"], }, - testMatch: ["/test/**/*-test.[tj]s?(x)", "/packages/*/src/**/*.test.[t]s?(x)"], + testMatch: ["/test/**/*-test.[tj]s?(x)"], globalSetup: "/test/globalSetup.ts", setupFiles: ["jest-canvas-mock", "web-streams-polyfill/polyfill"], setupFilesAfterEnv: ["/test/setupTests.ts"], @@ -40,6 +40,7 @@ const config: Config = { "^!!raw-loader!.*": "jest-raw-loader", "recorderWorkletFactory": "/__mocks__/empty.js", "^fetch-mock$": "/node_modules/fetch-mock", + "counterpart": "/node_modules/counterpart", }, transformIgnorePatterns: [ "/node_modules/(?!(mime|matrix-js-sdk|uuid|p-retry|is-network-error|react-merge-refs)).+$", diff --git a/package.json b/package.json index 47b00f243f..b8ac4c684c 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "@playwright/test": "1.56.1", "@types/react": "19.2.2", "@types/react-dom": "19.2.2", + "@types/serve-static": "1.15.10", "oidc-client-ts": "3.3.0", "jwt-decode": "4.0.0", "caniuse-lite": "1.0.30001751", @@ -82,6 +83,7 @@ "dependencies": { "@babel/runtime": "^7.12.5", "@element-hq/element-web-module-api": "1.5.0", + "@element-hq/web-shared-components": "file:packages/shared-components", "@fontsource/inconsolata": "^5", "@fontsource/inter": "^5", "@formatjs/intl-segmenter": "^11.5.7", @@ -103,7 +105,6 @@ "browserslist": "^4.23.2", "classnames": "^2.2.6", "commonmark": "^0.31.0", - "counterpart": "^0.18.6", "css-tree": "^3.0.0", "diff-dom": "^5.0.0", "diff-match-patch": "^1.0.5", diff --git a/packages/shared-components/.eslintrc.js b/packages/shared-components/.eslintrc.js index 0408f840e1..6532f7b92d 100644 --- a/packages/shared-components/.eslintrc.js +++ b/packages/shared-components/.eslintrc.js @@ -1,4 +1,5 @@ module.exports = { + root: true, plugins: ["matrix-org", "eslint-plugin-react-compiler"], extends: [ "plugin:matrix-org/babel", diff --git a/packages/shared-components/.prettierignore b/packages/shared-components/.prettierignore index 849ddff3b7..bbb6b1ef7f 100644 --- a/packages/shared-components/.prettierignore +++ b/packages/shared-components/.prettierignore @@ -1 +1,2 @@ dist/ +i18n/i18nKeys.d.ts diff --git a/packages/shared-components/babel.config.js b/packages/shared-components/babel.config.js new file mode 100644 index 0000000000..02ff2e43fe --- /dev/null +++ b/packages/shared-components/babel.config.js @@ -0,0 +1,21 @@ +module.exports = { + sourceMaps: true, + presets: [ + [ + "@babel/preset-env", + { + include: ["@babel/plugin-transform-class-properties"], + }, + ], + ["@babel/preset-typescript", { allowDeclareFields: true }], + "@babel/preset-react", + ], + plugins: [ + "@babel/plugin-proposal-export-default-from", + "@babel/plugin-transform-numeric-separator", + "@babel/plugin-transform-object-rest-spread", + "@babel/plugin-transform-optional-chaining", + "@babel/plugin-transform-nullish-coalescing-operator", + "@babel/plugin-transform-runtime", + ], +}; diff --git a/packages/shared-components/jest.config.ts b/packages/shared-components/jest.config.ts new file mode 100644 index 0000000000..2e88689024 --- /dev/null +++ b/packages/shared-components/jest.config.ts @@ -0,0 +1,58 @@ +/* +Copyright 2025 Element Creations Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import { env } from "process"; + +import type { Config } from "jest"; + +const config: Config = { + testEnvironment: "jsdom", + testEnvironmentOptions: { + url: "http://localhost/", + }, + testMatch: ["/src/**/*.test.[tj]s?(x)"], + setupFilesAfterEnv: ["/src/test/setupTests.ts"], + moduleNameMapper: { + // Support CSS module + "\\.(module.css)$": "identity-obj-proxy", + "\\.(css|scss|pcss)$": "/__mocks__/cssMock.js", + "\\.(gif|png|ttf|woff2)$": "/__mocks__/imageMock.js", + "\\.svg$": "/__mocks__/svg.js", + "\\$webapp/i18n/languages.json": "/../../__mocks__/languages.json", + "^react$": "/node_modules/react", + "^react-dom$": "/node_modules/react-dom", + "waveWorker\\.min\\.js": "/__mocks__/empty.js", + "context-filter-polyfill": "/__mocks__/empty.js", + "workers/(.+)Factory": "/__mocks__/workerFactoryMock.js", + }, + transformIgnorePatterns: [ + "/node_modules/(?!(mime|matrix-js-sdk|uuid|p-retry|is-network-error|react-merge-refs)).+$", + ], + collectCoverageFrom: [ + "/src/**/*.{js,ts,tsx}", + "/packages/**/*.{js,ts,tsx}", + // Coverage chokes on type definition files + "!/src/**/*.d.ts", + ], + coverageReporters: ["text-summary", "lcov"], + testResultsProcessor: "@casualbot/jest-sonar-reporter", + prettierPath: null, + moduleDirectories: ["node_modules", "./src/test/utils"], +}; + +// if we're running under GHA, enable the GHA reporter +if (env["GITHUB_ACTIONS"] !== undefined) { + const reporters: Config["reporters"] = [["github-actions", { silent: false }], "summary"]; + + // if we're running against the develop branch, also enable the slow test reporter + if (env["GITHUB_REF"] == "refs/heads/develop") { + reporters.push("/test/slowReporter.cjs"); + } + config.reporters = reporters; +} + +export default config; diff --git a/packages/shared-components/package.json b/packages/shared-components/package.json index 54592cdbac..3e3de423ed 100644 --- a/packages/shared-components/package.json +++ b/packages/shared-components/package.json @@ -1,6 +1,6 @@ { "name": "@element-hq/web-shared-components", - "version": "0.0.0-test.6", + "version": "0.0.0-test.7", "description": "Shared components for Element", "author": "New Vector Ltd.", "repository": { @@ -19,6 +19,10 @@ "types": "./dist/element-web-shared-components.d.ts", "default": "./dist/element-web-shared-components.mjs" } + }, + "./dist/element-web-shared-components.css": { + "require": "./dist/element-web-shared-components.css", + "import": "./dist/element-web-shared-components.css" } }, "types": "dist/element-web-shared-components.d.ts", @@ -30,8 +34,8 @@ "package.json" ], "scripts": { - "postinstall": "patch-package", - "prepare": "vite build", + "test": "jest", + "prepare": "patch-package && yarn --cwd ../.. build:res && ts-node scripts/gatherTranslationKeys.ts && vite build", "storybook": "storybook dev -p 6007", "build-storybook": "storybook build", "lint": "yarn lint:types && yarn lint:js", @@ -42,9 +46,13 @@ "test:storybook:update": "playwright-screenshots --entrypoint yarn --with-node-modules && playwright-screenshots --entrypoint /work/node_modules/.bin/test-storybook --with-node-modules --url http://host.docker.internal:6007/ --updateSnapshot" }, "dependencies": { + "classnames": "^2.5.1", + "counterpart": "^0.18.6", + "lodash": "^4.17.21", "matrix-web-i18n": "^3.4.0", "patch-package": "^8.0.1", - "counterpart": "^0.18.6" + "react-merge-refs": "^3.0.2", + "temporal-polyfill": "^0.3.0" }, "devDependencies": { "@storybook/addon-a11y": "^9.1.10", @@ -53,13 +61,21 @@ "@storybook/icons": "^1.6.0", "@storybook/react-vite": "^9.1.10", "@storybook/test-runner": "^0.23.0", + "@testing-library/dom": "^10.4.1", + "@testing-library/react": "^16.3.0", + "@types/counterpart": "^0.18.4", + "@types/lodash": "^4.17.20", + "@types/react": "^19.2.2", "concurrently": "^9.2.1", "eslint": "8", + "eslint-plugin-matrix-org": "^3.0.0", "eslint-plugin-storybook": "^10.0.0", + "jest": "^30.2.0", "jest-image-snapshot": "^6.5.1", "patch-package": "^8.0.1", "prettier": "^3.6.2", "storybook": "^9.1.10", + "ts-node": "^10.9.2", "typescript": "^5.9.3", "vite": "^7.1.9", "vite-plugin-dts": "^4.5.4", @@ -68,5 +84,9 @@ "engines": { "node": ">=20.0.0" }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e", + "peerDependencies": { + "@vector-im/compound-design-tokens": "^6.0.0", + "@vector-im/compound-web": "^8.2.5" + } } diff --git a/packages/shared-components/scripts/gatherTranslationKeys.ts b/packages/shared-components/scripts/gatherTranslationKeys.ts new file mode 100644 index 0000000000..b92d767179 --- /dev/null +++ b/packages/shared-components/scripts/gatherTranslationKeys.ts @@ -0,0 +1,61 @@ +/* +Copyright 2025 Element Creations Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +// Gathers all the translation keys from element-web's en_EN.json into a TypeScript type definition file +// that exports a type `TranslationKey` which is a union of all supported translation keys. +// This prevents having to import the json file and make typescript do the work as this results in vite-dts +// generating an import to the json file in the .d.ts which doesn't work at runtime: this way, the type +// gets put into the bundle. +// XXX: It should *not* be in the 'src' directory, being a generated file, but if it isn't then the type +// bundler won't bundle the types and will leave the file as a relative import, which will break. + +import * as fs from "fs"; +import * as path from "path"; + +const i18nStringsPath = path.resolve(__dirname, "../../../src/i18n/strings/en_EN.json"); +const outPath = path.resolve(__dirname, "../src/i18nKeys.d.ts"); + +function gatherKeys(obj: any, prefix: string[] = []): string[] { + if (typeof obj !== "object" || obj === null) return []; + let keys: string[] = []; + for (const key of Object.keys(obj)) { + const value = obj[key]; + + // add the path (for both leaves and intermediates as then we include plurals) + keys.push([...prefix, key].join("|")); + if (typeof value === "object" && value !== null) { + // If the value is an object, recurse + keys = keys.concat(gatherKeys(value, [...prefix, key])); + } + } + return keys; +} + +function main() { + const json = JSON.parse(fs.readFileSync(i18nStringsPath, "utf8")); + const keys = gatherKeys(json); + const typeDef = + "/*\n" + + " * Copyright 2025 Element Creations Ltd.\n" + + " *\n" + + " * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\n" + + " * Please see LICENSE files in the repository root for full details.\n" + + " */\n" + + "\n" + + "// This file is auto-generated by gatherTranslationKeys.ts\n" + + "// Do not edit manually.\n\n" + + "export type TranslationKey =\n" + + keys.map((k) => ` | \"${k}\"`).join("\n") + + ";\n"; + fs.mkdirSync(path.dirname(outPath), { recursive: true }); + fs.writeFileSync(outPath, typeDef, "utf8"); + console.log(`Wrote ${keys.length} keys to ${outPath}`); +} + +if (require.main === module) { + main(); +} diff --git a/packages/shared-components/src/audio/AudioPlayerView/AudioPlayerView.module.css b/packages/shared-components/src/audio/AudioPlayerView/AudioPlayerView.module.css index 905719eedf..fc8c26aef7 100644 --- a/packages/shared-components/src/audio/AudioPlayerView/AudioPlayerView.module.css +++ b/packages/shared-components/src/audio/AudioPlayerView/AudioPlayerView.module.css @@ -6,7 +6,7 @@ */ .audioPlayer { - padding: var(--cpd-space-4x) var(--cpd-space-3x) var(--cpd-space-3x) var(--cpd-space-3x); + padding: var(--cpd-space-4x) var(--cpd-space-3x) var(--cpd-space-3x) var(--cpd-space-3x) !important; } .mediaInfo { diff --git a/packages/shared-components/src/audio/AudioPlayerView/__snapshots__/AudioPlayerView.test.tsx.snap b/packages/shared-components/src/audio/AudioPlayerView/__snapshots__/AudioPlayerView.test.tsx.snap index 0687ea44a8..89b47dfecb 100644 --- a/packages/shared-components/src/audio/AudioPlayerView/__snapshots__/AudioPlayerView.test.tsx.snap +++ b/packages/shared-components/src/audio/AudioPlayerView/__snapshots__/AudioPlayerView.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`AudioPlayerView renders the audio player in default state 1`] = `
diff --git a/packages/shared-components/src/audio/Clock/__snapshots__/Clock.test.tsx.snap b/packages/shared-components/src/audio/Clock/__snapshots__/Clock.test.tsx.snap index 2fdcedd7c3..5ab0799d28 100644 --- a/packages/shared-components/src/audio/Clock/__snapshots__/Clock.test.tsx.snap +++ b/packages/shared-components/src/audio/Clock/__snapshots__/Clock.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`Clock renders the clock 1`] = `
diff --git a/packages/shared-components/src/audio/PlayPauseButton/PlayPauseButton.module.css b/packages/shared-components/src/audio/PlayPauseButton/PlayPauseButton.module.css index 74315673f1..859f84bba9 100644 --- a/packages/shared-components/src/audio/PlayPauseButton/PlayPauseButton.module.css +++ b/packages/shared-components/src/audio/PlayPauseButton/PlayPauseButton.module.css @@ -6,6 +6,6 @@ */ .button { - border-radius: 32px; - background-color: var(--cpd-color-bg-subtle-primary); + border-radius: 32px !important; + background-color: var(--cpd-color-bg-subtle-primary) !important; } diff --git a/packages/shared-components/src/audio/PlayPauseButton/__snapshots__/PlayPauseButton.test.tsx.snap b/packages/shared-components/src/audio/PlayPauseButton/__snapshots__/PlayPauseButton.test.tsx.snap index 503b5ac498..872de81cb9 100644 --- a/packages/shared-components/src/audio/PlayPauseButton/__snapshots__/PlayPauseButton.test.tsx.snap +++ b/packages/shared-components/src/audio/PlayPauseButton/__snapshots__/PlayPauseButton.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`PlayPauseButton renders the button in default state 1`] = `
diff --git a/packages/shared-components/src/audio/SeekBar/__snapshots__/SeekBar.test.tsx.snap b/packages/shared-components/src/audio/SeekBar/__snapshots__/SeekBar.test.tsx.snap index 49bfd5dbe7..e3cc92279e 100644 --- a/packages/shared-components/src/audio/SeekBar/__snapshots__/SeekBar.test.tsx.snap +++ b/packages/shared-components/src/audio/SeekBar/__snapshots__/SeekBar.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`Seekbar renders the clock 1`] = `
diff --git a/packages/shared-components/src/avatar/AvatarWithDetails/__snapshots__/AvatarWithDetails.test.tsx.snap b/packages/shared-components/src/avatar/AvatarWithDetails/__snapshots__/AvatarWithDetails.test.tsx.snap index e8a2e4579a..7b927f2c3b 100644 --- a/packages/shared-components/src/avatar/AvatarWithDetails/__snapshots__/AvatarWithDetails.test.tsx.snap +++ b/packages/shared-components/src/avatar/AvatarWithDetails/__snapshots__/AvatarWithDetails.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`AvatarWithDetails renders a textual event 1`] = `
diff --git a/packages/shared-components/src/event-tiles/TextualEventView/__snapshots__/TextualEventView.test.tsx.snap b/packages/shared-components/src/event-tiles/TextualEventView/__snapshots__/TextualEventView.test.tsx.snap index a0be215af7..37c53e56bd 100644 --- a/packages/shared-components/src/event-tiles/TextualEventView/__snapshots__/TextualEventView.test.tsx.snap +++ b/packages/shared-components/src/event-tiles/TextualEventView/__snapshots__/TextualEventView.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`TextualEventView renders a textual event 1`] = `
diff --git a/packages/shared-components/src/event-tiles/TextualEventView/index.ts b/packages/shared-components/src/event-tiles/TextualEventView/index.ts index 58796a3dd7..589130bd28 100644 --- a/packages/shared-components/src/event-tiles/TextualEventView/index.ts +++ b/packages/shared-components/src/event-tiles/TextualEventView/index.ts @@ -5,4 +5,4 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -export { TextualEventView } from "./TextualEventView"; +export { TextualEventView, type TextualEventViewSnapshot } from "./TextualEventView"; diff --git a/packages/shared-components/src/index.ts b/packages/shared-components/src/index.ts index 6967c175fd..68935afd3f 100644 --- a/packages/shared-components/src/index.ts +++ b/packages/shared-components/src/index.ts @@ -21,12 +21,17 @@ export * from "./utils/Box"; export * from "./utils/Flex"; // Utils -export { setLanguage } from "./utils/i18n"; +export * from "./utils/i18n"; export * from "./utils/humanize"; export * from "./utils/DateUtils"; export * from "./utils/numbers"; +export * from "./utils/FormattingUtils"; // MVVM export * from "./viewmodel"; export * from "./useMockedViewModel"; export * from "./useViewModel"; + +// i18n (we must export this directly in order to not confuse the type bundler, it seems, +// otherwise it will leave it as a relative import rather than bundling it) +export type * from "./i18nKeys.d.ts"; diff --git a/packages/shared-components/src/message-body/MediaBody/MediaBody.module.css b/packages/shared-components/src/message-body/MediaBody/MediaBody.module.css index 7cf125f303..49d8ed8f4a 100644 --- a/packages/shared-components/src/message-body/MediaBody/MediaBody.module.css +++ b/packages/shared-components/src/message-body/MediaBody/MediaBody.module.css @@ -7,7 +7,7 @@ .mediaBody { background-color: var(--cpd-color-bg-subtle-secondary); - border-radius: var(--cpd-space-2x); + border-radius: var(--cpd-space-2x) !important; max-width: 243px; /* use max-width instead of width so it fits within right panels */ font: var(--cpd-font-body-md-regular); diff --git a/packages/shared-components/src/message-body/MediaBody/__snapshots__/MediaBody.test.tsx.snap b/packages/shared-components/src/message-body/MediaBody/__snapshots__/MediaBody.test.tsx.snap index 9d1011254b..d86c677390 100644 --- a/packages/shared-components/src/message-body/MediaBody/__snapshots__/MediaBody.test.tsx.snap +++ b/packages/shared-components/src/message-body/MediaBody/__snapshots__/MediaBody.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`MediaBody renders the media body 1`] = `
diff --git a/packages/shared-components/src/pill-input/Pill/__snapshots__/Pill.test.tsx.snap b/packages/shared-components/src/pill-input/Pill/__snapshots__/Pill.test.tsx.snap index e467ec9ab7..348b3026c5 100644 --- a/packages/shared-components/src/pill-input/Pill/__snapshots__/Pill.test.tsx.snap +++ b/packages/shared-components/src/pill-input/Pill/__snapshots__/Pill.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`Pill renders the pill 1`] = `
diff --git a/packages/shared-components/src/pill-input/PillInput/__snapshots__/PillInput.test.tsx.snap b/packages/shared-components/src/pill-input/PillInput/__snapshots__/PillInput.test.tsx.snap index 7675610f6c..37a1d08c8b 100644 --- a/packages/shared-components/src/pill-input/PillInput/__snapshots__/PillInput.test.tsx.snap +++ b/packages/shared-components/src/pill-input/PillInput/__snapshots__/PillInput.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`PillInput renders only the input without children 1`] = `
diff --git a/packages/shared-components/src/rich-list/RichItem/__snapshots__/RichItem.test.tsx.snap b/packages/shared-components/src/rich-list/RichItem/__snapshots__/RichItem.test.tsx.snap index 84f6669b7a..6ccc190d8c 100644 --- a/packages/shared-components/src/rich-list/RichItem/__snapshots__/RichItem.test.tsx.snap +++ b/packages/shared-components/src/rich-list/RichItem/__snapshots__/RichItem.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`RichItem renders the item in default state 1`] = `
diff --git a/packages/shared-components/src/rich-list/RichList/__snapshots__/RichList.test.tsx.snap b/packages/shared-components/src/rich-list/RichList/__snapshots__/RichList.test.tsx.snap index 5569c63a9c..41f5407d3c 100644 --- a/packages/shared-components/src/rich-list/RichList/__snapshots__/RichList.test.tsx.snap +++ b/packages/shared-components/src/rich-list/RichList/__snapshots__/RichList.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`RichItem renders the list 1`] = `
diff --git a/packages/shared-components/src/test/setupTests.ts b/packages/shared-components/src/test/setupTests.ts new file mode 100644 index 0000000000..43ffc0c071 --- /dev/null +++ b/packages/shared-components/src/test/setupTests.ts @@ -0,0 +1,22 @@ +/* +Copyright 2025 Element Creations Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import fetchMock from "fetch-mock-jest"; + +import { setLanguage } from "../../src/utils/i18n"; +import en from "../../../../src/i18n/strings/en_EN.json"; + +export function setupLanguageMock(): void { + fetchMock + .get("/i18n/languages.json", { + en: "en_EN.json", + }) + .get("end:en_EN.json", en); +} +setupLanguageMock(); + +setLanguage("en"); diff --git a/packages/shared-components/src/test/utils/jest-matrix-react.tsx b/packages/shared-components/src/test/utils/jest-matrix-react.tsx new file mode 100644 index 0000000000..30d673aa22 --- /dev/null +++ b/packages/shared-components/src/test/utils/jest-matrix-react.tsx @@ -0,0 +1,47 @@ +/* +Copyright 2025 Element Creations Ltd. +Copyright 2024 New Vector Ltd. +Copyright 2022 The Matrix.org Foundation C.I.C. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +// Copied from element-web/test/test-utils because, seemingly, if we +// set that as the modules directory to use it directly, it fails to +// actually put the right thing in the context somehow. + +import React, { type ReactElement } from "react"; +// eslint-disable-next-line no-restricted-imports +import { render, type RenderOptions } from "@testing-library/react"; +import { TooltipProvider } from "@vector-im/compound-web"; + +const wrapWithTooltipProvider = (Wrapper: RenderOptions["wrapper"]) => { + return ({ children }: { children: React.ReactNode }) => { + if (Wrapper) { + return ( + + {children} + + ); + } else { + return {children}; + } + }; +}; + +const customRender = (ui: ReactElement, options: RenderOptions = {}): ReturnType => { + return render(ui, { + ...options, + wrapper: wrapWithTooltipProvider(options?.wrapper) as RenderOptions["wrapper"], + }) as ReturnType; +}; + +// eslint-disable-next-line no-restricted-imports +export * from "@testing-library/react"; + +/** + * This custom render function wraps your component with a TooltipProvider. + * See https://testing-library.com/docs/react-testing-library/setup/#custom-render + */ +export { customRender as render }; diff --git a/packages/shared-components/src/utils/i18n.test.ts b/packages/shared-components/src/utils/i18n.test.ts new file mode 100644 index 0000000000..a578f7bcfe --- /dev/null +++ b/packages/shared-components/src/utils/i18n.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import counterpart from "counterpart"; + +import { registerTranslations, setMissingEntryGenerator, getLocale, setLocale } from "./i18n"; + +describe("i18n utils", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("should wrap registerTranslations", () => { + jest.spyOn(counterpart, "registerTranslations"); + + registerTranslations("en", { test: "This is a test" }); + expect(counterpart.registerTranslations).toHaveBeenCalledWith("en", { test: "This is a test" }); + }); + + it("should wrap setMissingEntryGenerator", () => { + jest.spyOn(counterpart, "setMissingEntryGenerator"); + + const dummyFn = jest.fn(); + + setMissingEntryGenerator(dummyFn); + expect(counterpart.setMissingEntryGenerator).toHaveBeenCalledWith(dummyFn); + }); + + it("should wrap getLocale", () => { + jest.spyOn(counterpart, "getLocale"); + + getLocale(); + expect(counterpart.getLocale).toHaveBeenCalled(); + }); + + it("should wrap setLocale", () => { + jest.spyOn(counterpart, "setLocale"); + + setLocale("en"); + expect(counterpart.setLocale).toHaveBeenCalledWith("en"); + }); +}); diff --git a/packages/shared-components/src/utils/i18n.tsx b/packages/shared-components/src/utils/i18n.tsx index 21c37d7121..2ce1f78005 100644 --- a/packages/shared-components/src/utils/i18n.tsx +++ b/packages/shared-components/src/utils/i18n.tsx @@ -22,10 +22,10 @@ * @return a React component if any non-strings were used in substitutions, otherwise a string */ import React from "react"; -import { type TranslationKey as _TranslationKey, KEY_SEPARATOR } from "matrix-web-i18n"; +import { KEY_SEPARATOR } from "matrix-web-i18n"; import counterpart from "counterpart"; -import type Translations from "../../../../src/i18n/strings/en_EN.json"; +import type { TranslationKey } from "../index"; // @ts-ignore - $webapp is a webpack resolve alias pointing to the output directory, see webpack config import webpackLangJsonUrl from "$webapp/i18n/languages.json"; @@ -45,16 +45,23 @@ counterpart.setSeparator(KEY_SEPARATOR); const FALLBACK_LOCALE = "en"; counterpart.setFallbackLocale(FALLBACK_LOCALE); -/** - * A type representing the union of possible keys into the translation file using `|` delimiter to access nested fields. - * @example `common|error` to access `error` within the `common` sub-object. - * { - * "common": { - * "error": "Error" - * } - * } - */ -export type TranslationKey = _TranslationKey; +// export wrappers around these functions because if we used counterpart directly from +// element-web, it operates on a different instance of counterpart +export function registerTranslations(locale: string, data: object): void { + counterpart.registerTranslations(locale, data); +} + +export function setMissingEntryGenerator(callback: (value: string) => void): void { + counterpart.setMissingEntryGenerator(callback); +} + +export function getLocale(): string { + return counterpart.getLocale(); +} + +export function setLocale(value: string): string { + return counterpart.setLocale(value); +} // Function which only purpose is to mark that a string is translatable // Does not actually do anything. It's helpful for automatic extraction of translatable strings diff --git a/packages/shared-components/tsconfig.json b/packages/shared-components/tsconfig.json index aa1237f4a1..977d20132e 100644 --- a/packages/shared-components/tsconfig.json +++ b/packages/shared-components/tsconfig.json @@ -17,7 +17,7 @@ "lib": ["es2022", "es2024.promise", "dom", "dom.iterable"], "strict": true, "paths": { - "jest-matrix-react": ["../../test/test-utils/jest-matrix-react"], + "jest-matrix-react": ["./src/test/utils/jest-matrix-react"], "rollup/parseAst": ["./node_modules/rollup/dist/parseAst"] } }, diff --git a/packages/shared-components/vite.config.js b/packages/shared-components/vite.config.js index 46322bd884..83c999d87f 100644 --- a/packages/shared-components/vite.config.js +++ b/packages/shared-components/vite.config.js @@ -26,7 +26,7 @@ export default defineConfig({ rollupOptions: { // make sure to externalize deps that shouldn't be bundled // into your library - external: ["react", "react-dom"], + external: ["react", "react-dom", "@vector-im/compound-design-tokens", "@vector-im/compound-web"], output: { // Provide global variables to use in the UMD build // for externalized deps @@ -43,5 +43,12 @@ export default defineConfig({ $webapp: resolve(__dirname, "..", "..", "webapp"), }, }, - plugins: [dts({ rollupTypes: true, include: ["src/**/*.{ts,tsx}"], copyDtsFiles: true })], + plugins: [ + dts({ + rollupTypes: true, + include: ["src/**/*.{ts,tsx}"], + exclude: ["src/**/*.test.{ts,tsx}"], + copyDtsFiles: true, + }), + ], }); diff --git a/packages/shared-components/yarn.lock b/packages/shared-components/yarn.lock index 2beefab6d2..2f38c9a622 100644 --- a/packages/shared-components/yarn.lock +++ b/packages/shared-components/yarn.lock @@ -7,7 +7,7 @@ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.4.4.tgz#2856c55443d3d461693f32d2b96fb6ea92e1ffa9" integrity sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg== -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== @@ -17,11 +17,11 @@ picocolors "^1.1.1" "@babel/compat-data@^7.27.2": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.4.tgz#96fdf1af1b8859c8474ab39c295312bfb7c24b04" - integrity sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw== + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.5.tgz#a8a4962e1567121ac0b3b487f52107443b455c7f" + integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA== -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.22.5", "@babel/core@^7.23.9", "@babel/core@^7.28.0", "@babel/core@^7.7.5": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.22.5", "@babel/core@^7.23.9", "@babel/core@^7.27.4", "@babel/core@^7.7.5": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.4.tgz#12a550b8794452df4c8b084f95003bce1742d496" integrity sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA== @@ -42,7 +42,28 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.22.5", "@babel/generator@^7.28.3", "@babel/generator@^7.7.2": +"@babel/core@^7.28.0": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.5.tgz#4c81b35e51e1b734f510c99b07dfbc7bbbb48f7e" + integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.5" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-module-transforms" "^7.28.3" + "@babel/helpers" "^7.28.4" + "@babel/parser" "^7.28.5" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" + "@jridgewell/remapping" "^2.3.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.22.5", "@babel/generator@^7.27.5", "@babel/generator@^7.7.2": version "7.28.3" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e" integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw== @@ -53,6 +74,17 @@ "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" +"@babel/generator@^7.28.3", "@babel/generator@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298" + integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ== + dependencies: + "@babel/parser" "^7.28.5" + "@babel/types" "^7.28.5" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + "@babel/helper-compilation-targets@^7.27.2": version "7.27.2" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" @@ -96,10 +128,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== -"@babel/helper-validator-identifier@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" - integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== +"@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== "@babel/helper-validator-option@^7.27.1": version "7.27.1" @@ -114,7 +146,14 @@ "@babel/template" "^7.27.2" "@babel/types" "^7.28.4" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.5", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.3", "@babel/parser@^7.28.4": +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.27.2", "@babel/parser@^7.28.3", "@babel/parser@^7.28.4", "@babel/parser@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08" + integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== + dependencies: + "@babel/types" "^7.28.5" + +"@babel/parser@^7.14.7", "@babel/parser@^7.18.5", "@babel/parser@^7.23.9": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.4.tgz#da25d4643532890932cc03f7705fe19637e03fa8" integrity sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg== @@ -170,7 +209,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.7.2": +"@babel/plugin-syntax-jsx@^7.27.1", "@babel/plugin-syntax-jsx@^7.7.2": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== @@ -233,13 +272,18 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.7.2": +"@babel/plugin-syntax-typescript@^7.27.1", "@babel/plugin-syntax-typescript@^7.7.2": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18" integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" +"@babel/runtime@^7.12.5": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" + integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== + "@babel/template@^7.22.5", "@babel/template@^7.27.2", "@babel/template@^7.3.3": version "7.27.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" @@ -249,7 +293,7 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" -"@babel/traverse@^7.18.5", "@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4": +"@babel/traverse@^7.18.5": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.4.tgz#8d456101b96ab175d487249f60680221692b958b" integrity sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ== @@ -262,7 +306,28 @@ "@babel/types" "^7.28.4" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.27.1", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.3.3": +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b" + integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.5" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.28.5" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.5" + debug "^4.3.1" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" + integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + +"@babel/types@^7.22.5", "@babel/types@^7.27.3", "@babel/types@^7.3.3": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.4.tgz#0a4e618f4c60a7cd6c11cb2d48060e4dbe38ac3a" integrity sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q== @@ -275,136 +340,295 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@emnapi/core@^1.4.3": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.6.0.tgz#517f65d1c8270d5d5aa1aad660d5acb897430dca" + integrity sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg== + dependencies: + "@emnapi/wasi-threads" "1.1.0" + tslib "^2.4.0" + +"@emnapi/runtime@^1.4.3": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.6.0.tgz#8fe297e0090f6e89a57a1f31f1c440bdbc3c01d8" + integrity sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA== + dependencies: + tslib "^2.4.0" + +"@emnapi/wasi-threads@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz#60b2102fddc9ccb78607e4a3cf8403ea69be41bf" + integrity sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ== + dependencies: + tslib "^2.4.0" + "@esbuild/aix-ppc64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz#ee6b7163a13528e099ecf562b972f2bcebe0aa97" integrity sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw== +"@esbuild/aix-ppc64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz#2ae33300598132cc4cf580dbbb28d30fed3c5c49" + integrity sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg== + "@esbuild/android-arm64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz#115fc76631e82dd06811bfaf2db0d4979c16e2cb" integrity sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg== +"@esbuild/android-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz#927708b3db5d739d6cb7709136924cc81bec9b03" + integrity sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ== + "@esbuild/android-arm@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.10.tgz#8d5811912da77f615398611e5bbc1333fe321aa9" integrity sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w== +"@esbuild/android-arm@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.11.tgz#571f94e7f4068957ec4c2cfb907deae3d01b55ae" + integrity sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg== + "@esbuild/android-x64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.10.tgz#e3e96516b2d50d74105bb92594c473e30ddc16b1" integrity sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg== +"@esbuild/android-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.11.tgz#8a3bf5cae6c560c7ececa3150b2bde76e0fb81e6" + integrity sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g== + "@esbuild/darwin-arm64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz#6af6bb1d05887dac515de1b162b59dc71212ed76" integrity sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA== +"@esbuild/darwin-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz#0a678c4ac4bf8717e67481e1a797e6c152f93c84" + integrity sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w== + "@esbuild/darwin-x64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz#99ae82347fbd336fc2d28ffd4f05694e6e5b723d" integrity sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg== +"@esbuild/darwin-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz#70f5e925a30c8309f1294d407a5e5e002e0315fe" + integrity sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ== + "@esbuild/freebsd-arm64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz#0c6d5558a6322b0bdb17f7025c19bd7d2359437d" integrity sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg== +"@esbuild/freebsd-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz#4ec1db687c5b2b78b44148025da9632397553e8a" + integrity sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA== + "@esbuild/freebsd-x64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz#8c35873fab8c0857a75300a3dcce4324ca0b9844" integrity sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA== +"@esbuild/freebsd-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz#4c81abd1b142f1e9acfef8c5153d438ca53f44bb" + integrity sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw== + "@esbuild/linux-arm64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz#3edc2f87b889a15b4cedaf65f498c2bed7b16b90" integrity sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ== +"@esbuild/linux-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz#69517a111acfc2b93aa0fb5eaeb834c0202ccda5" + integrity sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA== + "@esbuild/linux-arm@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz#86501cfdfb3d110176d80c41b27ed4611471cde7" integrity sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg== +"@esbuild/linux-arm@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz#58dac26eae2dba0fac5405052b9002dac088d38f" + integrity sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw== + "@esbuild/linux-ia32@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz#e6589877876142537c6864680cd5d26a622b9d97" integrity sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ== +"@esbuild/linux-ia32@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz#b89d4efe9bdad46ba944f0f3b8ddd40834268c2b" + integrity sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw== + "@esbuild/linux-loong64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz#11119e18781f136d8083ea10eb6be73db7532de8" integrity sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg== +"@esbuild/linux-loong64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz#11f603cb60ad14392c3f5c94d64b3cc8b630fbeb" + integrity sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw== + "@esbuild/linux-mips64el@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz#3052f5436b0c0c67a25658d5fc87f045e7def9e6" integrity sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA== +"@esbuild/linux-mips64el@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz#b7d447ff0676b8ab247d69dac40a5cf08e5eeaf5" + integrity sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ== + "@esbuild/linux-ppc64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz#2f098920ee5be2ce799f35e367b28709925a8744" integrity sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA== +"@esbuild/linux-ppc64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz#b3a28ed7cc252a61b07ff7c8fd8a984ffd3a2f74" + integrity sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw== + "@esbuild/linux-riscv64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz#fa51d7fd0a22a62b51b4b94b405a3198cf7405dd" integrity sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA== +"@esbuild/linux-riscv64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz#ce75b08f7d871a75edcf4d2125f50b21dc9dc273" + integrity sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww== + "@esbuild/linux-s390x@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz#a27642e36fc282748fdb38954bd3ef4f85791e8a" integrity sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew== +"@esbuild/linux-s390x@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz#cd08f6c73b6b6ff9ccdaabbd3ff6ad3dca99c263" + integrity sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw== + "@esbuild/linux-x64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz#9d9b09c0033d17529570ced6d813f98315dfe4e9" integrity sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA== +"@esbuild/linux-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz#3c3718af31a95d8946ebd3c32bb1e699bdf74910" + integrity sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ== + "@esbuild/netbsd-arm64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz#25c09a659c97e8af19e3f2afd1c9190435802151" integrity sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A== +"@esbuild/netbsd-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz#b4c767082401e3a4e8595fe53c47cd7f097c8077" + integrity sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg== + "@esbuild/netbsd-x64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz#7fa5f6ffc19be3a0f6f5fd32c90df3dc2506937a" integrity sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig== +"@esbuild/netbsd-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz#f2a930458ed2941d1f11ebc34b9c7d61f7a4d034" + integrity sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A== + "@esbuild/openbsd-arm64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz#8faa6aa1afca0c6d024398321d6cb1c18e72a1c3" integrity sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw== +"@esbuild/openbsd-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz#b4ae93c75aec48bc1e8a0154957a05f0641f2dad" + integrity sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg== + "@esbuild/openbsd-x64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz#a42979b016f29559a8453d32440d3c8cd420af5e" integrity sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw== +"@esbuild/openbsd-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz#b42863959c8dcf9b01581522e40012d2c70045e2" + integrity sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw== + "@esbuild/openharmony-arm64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz#fd87bfeadd7eeb3aa384bbba907459ffa3197cb1" integrity sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag== +"@esbuild/openharmony-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz#b2e717141c8fdf6bddd4010f0912e6b39e1640f1" + integrity sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ== + "@esbuild/sunos-x64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz#3a18f590e36cb78ae7397976b760b2b8c74407f4" integrity sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ== +"@esbuild/sunos-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz#9fbea1febe8778927804828883ec0f6dd80eb244" + integrity sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA== + "@esbuild/win32-arm64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz#e71741a251e3fd971408827a529d2325551f530c" integrity sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw== +"@esbuild/win32-arm64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz#501539cedb24468336073383989a7323005a8935" + integrity sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q== + "@esbuild/win32-ia32@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz#c6f010b5d3b943d8901a0c87ea55f93b8b54bf94" integrity sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw== +"@esbuild/win32-ia32@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz#8ac7229aa82cef8f16ffb58f1176a973a7a15343" + integrity sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA== + "@esbuild/win32-x64@0.25.10": version "0.25.10" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz#e4b3e255a1b4aea84f6e1d2ae0b73f826c3785bd" integrity sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw== +"@esbuild/win32-x64@0.25.11": + version "0.25.11" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz#5ecda6f3fe138b7e456f4e429edde33c823f392f" + integrity sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0": version "4.9.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz#7308df158e064f0dd8b8fdb58aa14fa2a7f913b3" @@ -523,6 +747,18 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== +"@jest/console@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-30.2.0.tgz#c52fcd5b58fdd2e8eb66b2fd8ae56f2f64d05b28" + integrity sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ== + dependencies: + "@jest/types" "30.2.0" + "@types/node" "*" + chalk "^4.1.2" + jest-message-util "30.2.0" + jest-util "30.2.0" + slash "^3.0.0" + "@jest/console@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" @@ -535,6 +771,40 @@ jest-util "^29.7.0" slash "^3.0.0" +"@jest/core@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-30.2.0.tgz#813d59faa5abd5510964a8b3a7b17cc77b775275" + integrity sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ== + dependencies: + "@jest/console" "30.2.0" + "@jest/pattern" "30.0.1" + "@jest/reporters" "30.2.0" + "@jest/test-result" "30.2.0" + "@jest/transform" "30.2.0" + "@jest/types" "30.2.0" + "@types/node" "*" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + ci-info "^4.2.0" + exit-x "^0.2.2" + graceful-fs "^4.2.11" + jest-changed-files "30.2.0" + jest-config "30.2.0" + jest-haste-map "30.2.0" + jest-message-util "30.2.0" + jest-regex-util "30.0.1" + jest-resolve "30.2.0" + jest-resolve-dependencies "30.2.0" + jest-runner "30.2.0" + jest-runtime "30.2.0" + jest-snapshot "30.2.0" + jest-util "30.2.0" + jest-validate "30.2.0" + jest-watcher "30.2.0" + micromatch "^4.0.8" + pretty-format "30.2.0" + slash "^3.0.0" + "@jest/core@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" @@ -576,6 +846,21 @@ dependencies: "@jest/types" "30.2.0" +"@jest/diff-sequences@30.0.1": + version "30.0.1" + resolved "https://registry.yarnpkg.com/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz#0ededeae4d071f5c8ffe3678d15f3a1be09156be" + integrity sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw== + +"@jest/environment@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-30.2.0.tgz#1e673cdb8b93ded707cf6631b8353011460831fa" + integrity sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g== + dependencies: + "@jest/fake-timers" "30.2.0" + "@jest/types" "30.2.0" + "@types/node" "*" + jest-mock "30.2.0" + "@jest/environment@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" @@ -586,6 +871,13 @@ "@types/node" "*" jest-mock "^29.7.0" +"@jest/expect-utils@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-30.2.0.tgz#4f95413d4748454fdb17404bf1141827d15e6011" + integrity sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA== + dependencies: + "@jest/get-type" "30.1.0" + "@jest/expect-utils@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" @@ -593,6 +885,14 @@ dependencies: jest-get-type "^29.6.3" +"@jest/expect@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-30.2.0.tgz#9a5968499bb8add2bbb09136f69f7df5ddbf3185" + integrity sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA== + dependencies: + expect "30.2.0" + jest-snapshot "30.2.0" + "@jest/expect@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" @@ -601,6 +901,18 @@ expect "^29.7.0" jest-snapshot "^29.7.0" +"@jest/fake-timers@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-30.2.0.tgz#0941ddc28a339b9819542495b5408622dc9e94ec" + integrity sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw== + dependencies: + "@jest/types" "30.2.0" + "@sinonjs/fake-timers" "^13.0.0" + "@types/node" "*" + jest-message-util "30.2.0" + jest-mock "30.2.0" + jest-util "30.2.0" + "@jest/fake-timers@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" @@ -613,6 +925,21 @@ jest-mock "^29.7.0" jest-util "^29.7.0" +"@jest/get-type@30.1.0": + version "30.1.0" + resolved "https://registry.yarnpkg.com/@jest/get-type/-/get-type-30.1.0.tgz#4fcb4dc2ebcf0811be1c04fd1cb79c2dba431cbc" + integrity sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA== + +"@jest/globals@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-30.2.0.tgz#2f4b696d5862664b89c4ee2e49ae24d2bb7e0988" + integrity sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw== + dependencies: + "@jest/environment" "30.2.0" + "@jest/expect" "30.2.0" + "@jest/types" "30.2.0" + jest-mock "30.2.0" + "@jest/globals@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" @@ -631,6 +958,35 @@ "@types/node" "*" jest-regex-util "30.0.1" +"@jest/reporters@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-30.2.0.tgz#a36b28fcbaf0c4595250b108e6f20e363348fd91" + integrity sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "30.2.0" + "@jest/test-result" "30.2.0" + "@jest/transform" "30.2.0" + "@jest/types" "30.2.0" + "@jridgewell/trace-mapping" "^0.3.25" + "@types/node" "*" + chalk "^4.1.2" + collect-v8-coverage "^1.0.2" + exit-x "^0.2.2" + glob "^10.3.10" + graceful-fs "^4.2.11" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^6.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^5.0.0" + istanbul-reports "^3.1.3" + jest-message-util "30.2.0" + jest-util "30.2.0" + jest-worker "30.2.0" + slash "^3.0.0" + string-length "^4.0.2" + v8-to-istanbul "^9.0.1" + "@jest/reporters@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" @@ -675,6 +1031,25 @@ dependencies: "@sinclair/typebox" "^0.27.8" +"@jest/snapshot-utils@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz#387858eb90c2f98f67bff327435a532ac5309fbe" + integrity sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug== + dependencies: + "@jest/types" "30.2.0" + chalk "^4.1.2" + graceful-fs "^4.2.11" + natural-compare "^1.4.0" + +"@jest/source-map@30.0.1": + version "30.0.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-30.0.1.tgz#305ebec50468f13e658b3d5c26f85107a5620aaa" + integrity sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.25" + callsites "^3.1.0" + graceful-fs "^4.2.11" + "@jest/source-map@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" @@ -684,6 +1059,16 @@ callsites "^3.0.0" graceful-fs "^4.2.9" +"@jest/test-result@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-30.2.0.tgz#9c0124377fb7996cdffb86eda3dbc56eacab363d" + integrity sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg== + dependencies: + "@jest/console" "30.2.0" + "@jest/types" "30.2.0" + "@types/istanbul-lib-coverage" "^2.0.6" + collect-v8-coverage "^1.0.2" + "@jest/test-result@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" @@ -694,6 +1079,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-sequencer@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz#bf0066bc72e176d58f5dfa7f212b6e7eee44f221" + integrity sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q== + dependencies: + "@jest/test-result" "30.2.0" + graceful-fs "^4.2.11" + jest-haste-map "30.2.0" + slash "^3.0.0" + "@jest/test-sequencer@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" @@ -704,6 +1099,27 @@ jest-haste-map "^29.7.0" slash "^3.0.0" +"@jest/transform@30.2.0": + version "30.2.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-30.2.0.tgz#54bef1a4510dcbd58d5d4de4fe2980a63077ef2a" + integrity sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA== + dependencies: + "@babel/core" "^7.27.4" + "@jest/types" "30.2.0" + "@jridgewell/trace-mapping" "^0.3.25" + babel-plugin-istanbul "^7.0.1" + chalk "^4.1.2" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.11" + jest-haste-map "30.2.0" + jest-regex-util "30.0.1" + jest-util "30.2.0" + micromatch "^4.0.8" + pirates "^4.0.7" + slash "^3.0.0" + write-file-atomic "^5.0.1" + "@jest/transform@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" @@ -775,17 +1191,25 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@jridgewell/resolve-uri@^3.1.0": +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5": version "1.5.5" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28": +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": version "0.3.31" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== @@ -860,6 +1284,15 @@ resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz#d4f6937353bc4568292654efb0a0e0532adbcba2" integrity sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw== +"@napi-rs/wasm-runtime@^0.2.11": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" + integrity sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ== + dependencies: + "@emnapi/core" "^1.4.3" + "@emnapi/runtime" "^1.4.3" + "@tybys/wasm-util" "^0.10.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -886,6 +1319,11 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@pkgr/core@^0.2.9": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" + integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== + "@rollup/plugin-inject@^5.0.5": version "5.0.5" resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz#616f3a73fe075765f91c5bec90176608bed277a3" @@ -1087,7 +1525,7 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.41.tgz#aa51a6c1946df2c5a11494a2cdb9318e026db16c" integrity sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g== -"@sinonjs/commons@^3.0.0": +"@sinonjs/commons@^3.0.0", "@sinonjs/commons@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== @@ -1101,10 +1539,17 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@sinonjs/fake-timers@^13.0.0": + version "13.0.5" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz#36b9dbc21ad5546486ea9173d6bea063eb1717d5" + integrity sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw== + dependencies: + "@sinonjs/commons" "^3.0.1" + "@storybook/addon-a11y@^9.1.10": - version "9.1.10" - resolved "https://registry.yarnpkg.com/@storybook/addon-a11y/-/addon-a11y-9.1.10.tgz#d0ad3acc2dfddede56efcc16f0a44c0377bf880d" - integrity sha512-RhYYtk8nePxVNfP/voW8vS7AiQxWWBgOLNMTeDr9Anjh06mpSWZ/U/zEUNC9TrId5BxnyZJW5Lkg0JUMwvyfjw== + version "9.1.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-a11y/-/addon-a11y-9.1.16.tgz#d7abc9339bd04ce4c5e4b10875e5ee41352c9432" + integrity sha512-DpUqAMOgkC/K/DgB9osqbBYmiWWj7V444HeYLHcx7GdPtg2guq1jAcalsOnQeU3wXgUE+wNuyMm6qZKm7of11g== dependencies: "@storybook/global" "^5.0.0" axe-core "^4.2.0" @@ -1117,30 +1562,30 @@ "@figspec/react" "^1.0.0" "@storybook/addon-docs@^9.1.10": - version "9.1.10" - resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-9.1.10.tgz#9dcfaa05aa6c8a092798da515bb912b3237f17a6" - integrity sha512-LYK3oXy/0PgY39FhkYVd9D0bzatLGTsMhaPPwSjBOmZgK0f0yBLqaePy7urUFeHYm/rjwAaRmDJNBqUnGTVoig== + version "9.1.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-9.1.16.tgz#0127eff2ff1b223f46a00f70fd259975fec7028d" + integrity sha512-JfaUD6fC7ySLg5duRdaWZ0FUUXrgUvqbZe/agCbSyOaIHOtJdhGaPjOC3vuXTAcV8/8/wWmbu0iXFMD08iKvdw== dependencies: "@mdx-js/react" "^3.0.0" - "@storybook/csf-plugin" "9.1.10" + "@storybook/csf-plugin" "9.1.16" "@storybook/icons" "^1.4.0" - "@storybook/react-dom-shim" "9.1.10" + "@storybook/react-dom-shim" "9.1.16" react "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" react-dom "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" ts-dedent "^2.0.0" -"@storybook/builder-vite@9.1.10": - version "9.1.10" - resolved "https://registry.yarnpkg.com/@storybook/builder-vite/-/builder-vite-9.1.10.tgz#bf6c24c64f6912a94d0bc289ad69a06af118010c" - integrity sha512-0ogI+toZJYaFptcFpRcRPOZ9/NrFUYhiaI09ggeEB1FF9ygHMVsobp4eaj4HjZI6V3x7cQwkd2ZmxAMQDBQuMA== +"@storybook/builder-vite@9.1.16": + version "9.1.16" + resolved "https://registry.yarnpkg.com/@storybook/builder-vite/-/builder-vite-9.1.16.tgz#58e00c16c8ba7d4c94f828753386bba1932c95b4" + integrity sha512-CyvYA5w1BKeSVaRavKi+euWxLffshq0v9Rz/5E9MKCitbYtjwkDH6UMIYmcbTs906mEBuYqrbz3nygDP0ppodw== dependencies: - "@storybook/csf-plugin" "9.1.10" + "@storybook/csf-plugin" "9.1.16" ts-dedent "^2.0.0" -"@storybook/csf-plugin@9.1.10": - version "9.1.10" - resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-9.1.10.tgz#9eaed7b8e0df62bd9d091501d79d262b5c1c4250" - integrity sha512-247F/JU0Naxm/RIUnQYpqXeCL0wG8UNJkZe+/GkLjdqzsyML0lb+8OwBsWFfG8zfj6fkjmRU2mF44TnNkzoQcg== +"@storybook/csf-plugin@9.1.16": + version "9.1.16" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-9.1.16.tgz#beeaae4b6e2597e4f43407a7b9c6870e8d6ff79d" + integrity sha512-GKlNNlmWeFBQxhQY5hZOSnFGbeKq69jal0dYNWoSImTjor28eYRHb9iQkDzRpijLPizBaB9MlxLsLrgFDp7adA== dependencies: unplugin "^1.3.1" @@ -1154,33 +1599,33 @@ resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.6.0.tgz#9fa6eb9c82922b79f75a2cf83c38af30ba7fd696" integrity sha512-hcFZIjW8yQz8O8//2WTIXylm5Xsgc+lW9ISLgUk1xGmptIJQRdlhVIXCpSyLrQaaRiyhQRaVg7l3BD9S216BHw== -"@storybook/react-dom-shim@9.1.10": - version "9.1.10" - resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-9.1.10.tgz#60e7898a8a7a03152b24a20c50af4cb35b0b98b6" - integrity sha512-cxy8GTj73RMJIFPrgqdnMXePGX5iFohM5pDCZ63Te5m5GtzKqsILRXtBBLO6Ouexm/ZYRVznkKiwNKX/Fu24fQ== +"@storybook/react-dom-shim@9.1.16": + version "9.1.16" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-9.1.16.tgz#c98298b1f08e699f1a06483c42fdfc4864cf4493" + integrity sha512-MsI4qTxdT6lMXQmo3IXhw3EaCC+vsZboyEZBx4pOJ+K/5cDJ6ZoQ3f0d4yGpVhumDxaxlnNAg954+f8WWXE1rQ== "@storybook/react-vite@^9.1.10": - version "9.1.10" - resolved "https://registry.yarnpkg.com/@storybook/react-vite/-/react-vite-9.1.10.tgz#a1702ef103e811bcb864669c9526e1a3deea86e4" - integrity sha512-k0wWlfoWakoHL3NZ1+38oxRH3WYyprFFX+WUb/4W8axrvpKogvdnxKCul/YB1HH5FcTagIfguamsPjKwB1ZkJg== + version "9.1.16" + resolved "https://registry.yarnpkg.com/@storybook/react-vite/-/react-vite-9.1.16.tgz#8672b6da54accdfd3dc329bd82ec2bcf1cfdf9e8" + integrity sha512-WRKSq0XfQ/Qx66aKisQCfa/1UKwN9HjVbY6xrmsX7kI5zBdITxIcKInq6PWoPv91SJD7+Et956yX+F86R1aEXw== dependencies: "@joshwooding/vite-plugin-react-docgen-typescript" "0.6.1" "@rollup/pluginutils" "^5.0.2" - "@storybook/builder-vite" "9.1.10" - "@storybook/react" "9.1.10" + "@storybook/builder-vite" "9.1.16" + "@storybook/react" "9.1.16" find-up "^7.0.0" magic-string "^0.30.0" react-docgen "^8.0.0" resolve "^1.22.8" tsconfig-paths "^4.2.0" -"@storybook/react@9.1.10": - version "9.1.10" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-9.1.10.tgz#39ffc1a0c6f91f6510550365409ee2178fc0cd65" - integrity sha512-flG3Gn3EHZnxn92C7vrA2U4aGqpOKdf85fL43+J/2k9HF5AIyOFGlcv4LGVyKZ3LOAow/nGBVSXL9961h+ICRA== +"@storybook/react@9.1.16": + version "9.1.16" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-9.1.16.tgz#38f8b4bdb7060575171183af2737198fe03aa2b6" + integrity sha512-M/SkHJJdtiGpodBJq9+DYmSkEOD+VqlPxKI+FvbHESTNs//1IgqFIjEWetd8quhd9oj/gvo4ICBAPu+UmD6M9w== dependencies: "@storybook/global" "^5.0.0" - "@storybook/react-dom-shim" "9.1.10" + "@storybook/react-dom-shim" "9.1.16" "@storybook/test-runner@^0.23.0": version "0.23.0" @@ -1296,6 +1741,20 @@ dependencies: "@swc/counter" "^0.1.3" +"@testing-library/dom@^10.4.1": + version "10.4.1" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.1.tgz#d444f8a889e9a46e9a3b4f3b88e0fcb3efb6cf95" + integrity sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.3.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + picocolors "1.1.1" + pretty-format "^27.0.2" + "@testing-library/jest-dom@^6.6.3": version "6.9.1" resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz#7613a04e146dd2976d24ddf019730d57a89d56c2" @@ -1308,16 +1767,55 @@ picocolors "^1.1.1" redent "^3.0.0" +"@testing-library/react@^16.3.0": + version "16.3.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-16.3.0.tgz#3a85bb9bdebf180cd76dba16454e242564d598a6" + integrity sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw== + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/user-event@^14.6.1": version "14.6.1" resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.6.1.tgz#13e09a32d7a8b7060fe38304788ebf4197cd2149" integrity sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw== +"@tsconfig/node10@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" + integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@tybys/wasm-util@^0.10.0": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz#ecddd3205cf1e2d5274649ff0eedd2991ed7f414" + integrity sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg== + dependencies: + tslib "^2.4.0" + "@types/argparse@1.0.38": version "1.0.38" resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== +"@types/aria-query@^5.0.1": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== + "@types/babel__core@^7.1.14", "@types/babel__core@^7.20.5": version "7.20.5" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" @@ -1352,11 +1850,17 @@ "@babel/types" "^7.28.2" "@types/chai@^5.2.2": - version "5.2.2" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-5.2.2.tgz#6f14cea18180ffc4416bc0fd12be05fdd73bdd6b" - integrity sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg== + version "5.2.3" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-5.2.3.tgz#8e9cd9e1c3581fa6b341a5aed5588eb285be0b4a" + integrity sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA== dependencies: "@types/deep-eql" "*" + assertion-error "^2.0.1" + +"@types/counterpart@^0.18.4": + version "0.18.4" + resolved "https://registry.yarnpkg.com/@types/counterpart/-/counterpart-0.18.4.tgz#e3e331b7e0d5496873d417839f3b2bbcf555bb73" + integrity sha512-aqBg5oAGo/qh/+wxUfuMadDu2WO0MEWOblyzwaM1Ske2xilUxBfgPqapAFVAfrVTDMVwa0UMarzGot8m64IAzA== "@types/deep-eql@*": version "4.0.2" @@ -1399,6 +1903,11 @@ dependencies: "@types/istanbul-lib-report" "*" +"@types/lodash@^4.17.20": + version "4.17.20" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.20.tgz#1ca77361d7363432d29f5e55950d9ec1e1c6ea93" + integrity sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA== + "@types/mdx@^2.0.0": version "2.0.13" resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd" @@ -1411,12 +1920,19 @@ dependencies: undici-types "~7.14.0" +"@types/react@^19.2.2": + version "19.2.2" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.2.tgz#ba123a75d4c2a51158697160a4ea2ff70aa6bf36" + integrity sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA== + dependencies: + csstype "^3.0.2" + "@types/resolve@^1.20.2": version "1.20.6" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8" integrity sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ== -"@types/stack-utils@^2.0.0": +"@types/stack-utils@^2.0.0", "@types/stack-utils@^2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== @@ -1506,11 +2022,108 @@ "@typescript-eslint/types" "8.46.0" eslint-visitor-keys "^4.2.1" -"@ungap/structured-clone@^1.2.0": +"@ungap/structured-clone@^1.2.0", "@ungap/structured-clone@^1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== +"@unrs/resolver-binding-android-arm-eabi@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz#9f5b04503088e6a354295e8ea8fe3cb99e43af81" + integrity sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw== + +"@unrs/resolver-binding-android-arm64@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz#7414885431bd7178b989aedc4d25cccb3865bc9f" + integrity sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g== + +"@unrs/resolver-binding-darwin-arm64@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz#b4a8556f42171fb9c9f7bac8235045e82aa0cbdf" + integrity sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g== + +"@unrs/resolver-binding-darwin-x64@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz#fd4d81257b13f4d1a083890a6a17c00de571f0dc" + integrity sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ== + +"@unrs/resolver-binding-freebsd-x64@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz#d2513084d0f37c407757e22f32bd924a78cfd99b" + integrity sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw== + +"@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz#844d2605d057488d77fab09705f2866b86164e0a" + integrity sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw== + +"@unrs/resolver-binding-linux-arm-musleabihf@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz#204892995cefb6bd1d017d52d097193bc61ddad3" + integrity sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw== + +"@unrs/resolver-binding-linux-arm64-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz#023eb0c3aac46066a10be7a3f362e7b34f3bdf9d" + integrity sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ== + +"@unrs/resolver-binding-linux-arm64-musl@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz#9e6f9abb06424e3140a60ac996139786f5d99be0" + integrity sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w== + +"@unrs/resolver-binding-linux-ppc64-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz#b111417f17c9d1b02efbec8e08398f0c5527bb44" + integrity sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA== + +"@unrs/resolver-binding-linux-riscv64-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz#92ffbf02748af3e99873945c9a8a5ead01d508a9" + integrity sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ== + +"@unrs/resolver-binding-linux-riscv64-musl@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz#0bec6f1258fc390e6b305e9ff44256cb207de165" + integrity sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew== + +"@unrs/resolver-binding-linux-s390x-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz#577843a084c5952f5906770633ccfb89dac9bc94" + integrity sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg== + +"@unrs/resolver-binding-linux-x64-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz#36fb318eebdd690f6da32ac5e0499a76fa881935" + integrity sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w== + +"@unrs/resolver-binding-linux-x64-musl@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz#bfb9af75f783f98f6a22c4244214efe4df1853d6" + integrity sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA== + +"@unrs/resolver-binding-wasm32-wasi@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz#752c359dd875684b27429500d88226d7cc72f71d" + integrity sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ== + dependencies: + "@napi-rs/wasm-runtime" "^0.2.11" + +"@unrs/resolver-binding-win32-arm64-msvc@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz#ce5735e600e4c2fbb409cd051b3b7da4a399af35" + integrity sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw== + +"@unrs/resolver-binding-win32-ia32-msvc@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz#72fc57bc7c64ec5c3de0d64ee0d1810317bc60a6" + integrity sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ== + +"@unrs/resolver-binding-win32-x64-msvc@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777" + integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g== + "@vitest/expect@3.2.4": version "3.2.4" resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.2.4.tgz#8362124cd811a5ee11c5768207b9df53d34f2433" @@ -1631,7 +2244,14 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.14.0, acorn@^8.15.0, acorn@^8.9.0: +acorn-walk@^8.1.1: + version "8.3.4" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" + +acorn@^8.11.0, acorn@^8.14.0, acorn@^8.15.0, acorn@^8.4.1, acorn@^8.9.0: version "8.15.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -1701,7 +2321,7 @@ alien-signals@^0.4.9: resolved "https://registry.yarnpkg.com/alien-signals/-/alien-signals-0.4.14.tgz#9ff8f72a272300a51692f54bd9bbbada78fbf539" integrity sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q== -ansi-escapes@^4.2.1: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -1737,7 +2357,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^5.0.0: +ansi-styles@^5.0.0, ansi-styles@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== @@ -1747,7 +2367,7 @@ ansi-styles@^6.1.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041" integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== -anymatch@^3.0.3: +anymatch@^3.0.3, anymatch@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== @@ -1767,6 +2387,11 @@ archy@^1.0.0: resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7, argparse@~1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1779,6 +2404,13 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +aria-query@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + aria-query@^5.0.0: version "5.3.2" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59" @@ -1829,9 +2461,9 @@ available-typed-arrays@^1.0.7: possible-typed-array-names "^1.0.0" axe-core@^4.2.0: - version "4.10.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.3.tgz#04145965ac7894faddbac30861e5d8f11bfd14fc" - integrity sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg== + version "4.11.0" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.11.0.tgz#16f74d6482e343ff263d4f4503829e9ee91a86b6" + integrity sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ== axios@^1.6.1: version "1.12.2" @@ -1842,6 +2474,19 @@ axios@^1.6.1: form-data "^4.0.4" proxy-from-env "^1.1.0" +babel-jest@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-30.2.0.tgz#fd44a1ec9552be35ead881f7381faa7d8f3b95ac" + integrity sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw== + dependencies: + "@jest/transform" "30.2.0" + "@types/babel__core" "^7.20.5" + babel-plugin-istanbul "^7.0.1" + babel-preset-jest "30.2.0" + chalk "^4.1.2" + graceful-fs "^4.2.11" + slash "^3.0.0" + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -1866,6 +2511,24 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" +babel-plugin-istanbul@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz#d8b518c8ea199364cf84ccc82de89740236daf92" + integrity sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.3" + istanbul-lib-instrument "^6.0.2" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz#94c250d36b43f95900f3a219241e0f4648191ce2" + integrity sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA== + dependencies: + "@types/babel__core" "^7.20.5" + babel-plugin-jest-hoist@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" @@ -1876,7 +2539,7 @@ babel-plugin-jest-hoist@^29.6.3: "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" -babel-preset-current-node-syntax@^1.0.0: +babel-preset-current-node-syntax@^1.0.0, babel-preset-current-node-syntax@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz#20730d6cdc7dda5d89401cab10ac6a32067acde6" integrity sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg== @@ -1897,6 +2560,14 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" +babel-preset-jest@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz#04717843e561347781d6d7f69c81e6bcc3ed11ce" + integrity sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ== + dependencies: + babel-plugin-jest-hoist "30.2.0" + babel-preset-current-node-syntax "^1.2.0" + babel-preset-jest@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" @@ -1915,10 +2586,10 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -baseline-browser-mapping@^2.8.9: - version "2.8.14" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.14.tgz#b73b0ae23efcb967e30b381c09a1a001777ec927" - integrity sha512-GM9c0cWWR8Ga7//Ves/9KRgTS8nLausCkP3CGiFLrnwA2CDUluXgaQqvrULoR2Ujrd/mz/lkX87F5BHFsNr5sQ== +baseline-browser-mapping@^2.8.19: + version "2.8.21" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.21.tgz#2f9cccde871bfa4aec9dbf92d0ee746e4f1892e4" + integrity sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q== better-opn@^3.0.2: version "3.0.2" @@ -2034,15 +2705,15 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@^4.24.0: - version "4.26.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.26.3.tgz#40fbfe2d1cd420281ce5b1caa8840049c79afb56" - integrity sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w== + version "4.27.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.27.0.tgz#755654744feae978fbb123718b2f139bc0fa6697" + integrity sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw== dependencies: - baseline-browser-mapping "^2.8.9" - caniuse-lite "^1.0.30001746" - electron-to-chromium "^1.5.227" - node-releases "^2.0.21" - update-browserslist-db "^1.1.3" + baseline-browser-mapping "^2.8.19" + caniuse-lite "^1.0.30001751" + electron-to-chromium "^1.5.238" + node-releases "^2.0.26" + update-browserslist-db "^1.1.4" bser@2.1.1: version "2.1.1" @@ -2110,7 +2781,7 @@ call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4: call-bind-apply-helpers "^1.0.2" get-intrinsic "^1.3.0" -callsites@^3.0.0: +callsites@^3.0.0, callsites@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== @@ -2120,15 +2791,15 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.2.0: +camelcase@^6.2.0, camelcase@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001746: - version "1.0.30001749" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001749.tgz#21a43b923577932097fe32bcaabb6da7f4677632" - integrity sha512-0rw2fJOmLfnzCRbkm8EyHL8SvI2Apu5UbnQuTsJ0ClgrH8hcwFooJ1s5R0EP8o8aVrFu8++ae29Kt9/gZAZp/Q== +caniuse-lite@^1.0.30001751: + version "1.0.30001752" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001752.tgz#afa28d0830709507162bc6ed3f7cb23b00926a99" + integrity sha512-vKUk7beoukxE47P5gcVNKkDRzXdVofotshHwfR9vmpeFKxmI5PBpgOMC18LUJUA/DvJ70Y7RveasIBraqsyO/g== chai@^5.2.0: version "5.3.3" @@ -2183,6 +2854,11 @@ ci-info@^3.2.0, ci-info@^3.7.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== +ci-info@^4.2.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.3.1.tgz#355ad571920810b5623e11d40232f443f16f1daa" + integrity sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA== + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.7" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.7.tgz#bd094bfef42634ccfd9e13b9fc73274997111e39" @@ -2197,6 +2873,16 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== +cjs-module-lexer@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-2.1.0.tgz#586e87d4341cb2661850ece5190232ccdebcff8b" + integrity sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA== + +classnames@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" + integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -2230,6 +2916,11 @@ collect-v8-coverage@^1.0.0: resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== +collect-v8-coverage@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz#cc1f01eb8d02298cbc9a437c74c70ab4e5210b80" + integrity sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -2388,7 +3079,7 @@ create-jest@^29.7.0: jest-util "^29.7.0" prompts "^2.0.1" -create-require@^1.1.1: +create-require@^1.1.0, create-require@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== @@ -2425,6 +3116,11 @@ css.escape@^1.5.1: resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + cwd@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/cwd/-/cwd-0.10.0.tgz#172400694057c22a13b0cf16162c7e4b7a7fe567" @@ -2455,7 +3151,7 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== -dedent@^1.0.0: +dedent@^1.0.0, dedent@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.0.tgz#c1f9445335f0175a96587be245a282ff451446ca" integrity sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ== @@ -2470,7 +3166,7 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -deepmerge@^4.2.2: +deepmerge@^4.2.2, deepmerge@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== @@ -2510,6 +3206,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + des.js@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" @@ -2518,7 +3219,7 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" -detect-newline@^3.0.0: +detect-newline@^3.0.0, detect-newline@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== @@ -2528,6 +3229,11 @@ diff-sequences@^29.6.3: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + diffable-html@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/diffable-html/-/diffable-html-4.1.0.tgz#e7a2d1de187c4e23a59751b4e4c17483a058c696" @@ -2551,6 +3257,11 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== + dom-accessibility-api@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz#993e925cc1d73f2c662e7d75dd5a5445259a8fd8" @@ -2608,10 +3319,10 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -electron-to-chromium@^1.5.227: - version "1.5.233" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.233.tgz#05db98476cee317527d6c48934571e13ad6b6f58" - integrity sha512-iUdTQSf7EFXsDdQsp8MwJz5SVk4APEFqXU/S47OtQ0YLqacSwPXdZ5vRlMX3neb07Cy2vgioNuRnWUXFwuslkg== +electron-to-chromium@^1.5.238: + version "1.5.244" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz#b9b61e3d24ef4203489951468614f2a360763820" + integrity sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw== elliptic@^6.5.3, elliptic@^6.6.1: version "6.6.1" @@ -2702,7 +3413,39 @@ esbuild-register@^3.5.0: dependencies: debug "^4.3.4" -"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", esbuild@^0.25.0: +"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0": + version "0.25.11" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.11.tgz#0f31b82f335652580f75ef6897bba81962d9ae3d" + integrity sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q== + optionalDependencies: + "@esbuild/aix-ppc64" "0.25.11" + "@esbuild/android-arm" "0.25.11" + "@esbuild/android-arm64" "0.25.11" + "@esbuild/android-x64" "0.25.11" + "@esbuild/darwin-arm64" "0.25.11" + "@esbuild/darwin-x64" "0.25.11" + "@esbuild/freebsd-arm64" "0.25.11" + "@esbuild/freebsd-x64" "0.25.11" + "@esbuild/linux-arm" "0.25.11" + "@esbuild/linux-arm64" "0.25.11" + "@esbuild/linux-ia32" "0.25.11" + "@esbuild/linux-loong64" "0.25.11" + "@esbuild/linux-mips64el" "0.25.11" + "@esbuild/linux-ppc64" "0.25.11" + "@esbuild/linux-riscv64" "0.25.11" + "@esbuild/linux-s390x" "0.25.11" + "@esbuild/linux-x64" "0.25.11" + "@esbuild/netbsd-arm64" "0.25.11" + "@esbuild/netbsd-x64" "0.25.11" + "@esbuild/openbsd-arm64" "0.25.11" + "@esbuild/openbsd-x64" "0.25.11" + "@esbuild/openharmony-arm64" "0.25.11" + "@esbuild/sunos-x64" "0.25.11" + "@esbuild/win32-arm64" "0.25.11" + "@esbuild/win32-ia32" "0.25.11" + "@esbuild/win32-x64" "0.25.11" + +esbuild@^0.25.0: version "0.25.10" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.10.tgz#37f5aa5cd14500f141be121c01b096ca83ac34a9" integrity sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ== @@ -2754,6 +3497,11 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +eslint-plugin-matrix-org@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-matrix-org/-/eslint-plugin-matrix-org-3.0.0.tgz#0e5eaa556b6780dcd616b1381baec252df78b56d" + integrity sha512-xOPMeyLxOgoB2SsPhJmIc+drorZmXozSBo3X9whk/62DvbVpJcnththOCGx8ljYScADLb+baNOeN+wKZqwkldw== + eslint-plugin-storybook@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-10.0.0.tgz#da3ceb6887339048cc6b772109c82146e39e4af7" @@ -2893,7 +3641,7 @@ except@^0.1.3: dependencies: indexof "0.0.1" -execa@^5.0.0: +execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -2908,6 +3656,11 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +exit-x@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/exit-x/-/exit-x-0.2.2.tgz#1f9052de3b8d99a696b10dad5bced9bdd5c3aa64" + integrity sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ== + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -2925,6 +3678,18 @@ expect-playwright@^0.8.0: resolved "https://registry.yarnpkg.com/expect-playwright/-/expect-playwright-0.8.0.tgz#6d4ebe0bdbdd3c1693d880d97153b96a129ae4e8" integrity sha512-+kn8561vHAY+dt+0gMqqj1oY+g5xWrsuGMk4QGxotT2WS545nVqqjs37z6hrYfIuucwqthzwJfCJUEYqixyljg== +expect@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-30.2.0.tgz#d4013bed267013c14bc1199cec8aa57cee9b5869" + integrity sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw== + dependencies: + "@jest/expect-utils" "30.2.0" + "@jest/get-type" "30.1.0" + jest-matcher-utils "30.2.0" + jest-message-util "30.2.0" + jest-mock "30.2.0" + jest-util "30.2.0" + expect@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" @@ -2984,7 +3749,7 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -fb-watchman@^2.0.0: +fb-watchman@^2.0.0, fb-watchman@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== @@ -3171,7 +3936,7 @@ fsevents@2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -fsevents@^2.3.2, fsevents@~2.3.2, fsevents@~2.3.3: +fsevents@^2.3.2, fsevents@^2.3.3, fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -3249,7 +4014,7 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@^10.0.0: +glob@^10.0.0, glob@^10.3.10: version "10.4.5" resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== @@ -3308,7 +4073,7 @@ gopd@^1.0.1, gopd@^1.2.0: resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -3459,7 +4224,7 @@ import-lazy@~4.0.0: resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== -import-local@^3.0.2: +import-local@^3.0.2, import-local@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== @@ -3518,7 +4283,7 @@ is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.16.0: +is-core-module@^2.16.0, is-core-module@^2.16.1: version "2.16.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== @@ -3540,7 +4305,7 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-generator-fn@^2.0.0: +is-generator-fn@^2.0.0, is-generator-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== @@ -3678,7 +4443,7 @@ istanbul-lib-instrument@^5.0.4: istanbul-lib-coverage "^3.2.0" semver "^6.3.0" -istanbul-lib-instrument@^6.0.0: +istanbul-lib-instrument@^6.0.0, istanbul-lib-instrument@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== @@ -3719,6 +4484,15 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" +istanbul-lib-source-maps@^5.0.0: + version "5.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz#acaef948df7747c8eb5fbf1265cb980f6353a441" + integrity sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A== + dependencies: + "@jridgewell/trace-mapping" "^0.3.23" + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + istanbul-reports@^3.0.2, istanbul-reports@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.2.0.tgz#cb4535162b5784aa623cee21a7252cf2c807ac93" @@ -3736,6 +4510,15 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jest-changed-files@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-30.2.0.tgz#602266e478ed554e1e1469944faa7efd37cee61c" + integrity sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ== + dependencies: + execa "^5.1.1" + jest-util "30.2.0" + p-limit "^3.1.0" + jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" @@ -3745,6 +4528,32 @@ jest-changed-files@^29.7.0: jest-util "^29.7.0" p-limit "^3.1.0" +jest-circus@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-30.2.0.tgz#98b8198b958748a2f322354311023d1d02e7603f" + integrity sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg== + dependencies: + "@jest/environment" "30.2.0" + "@jest/expect" "30.2.0" + "@jest/test-result" "30.2.0" + "@jest/types" "30.2.0" + "@types/node" "*" + chalk "^4.1.2" + co "^4.6.0" + dedent "^1.6.0" + is-generator-fn "^2.1.0" + jest-each "30.2.0" + jest-matcher-utils "30.2.0" + jest-message-util "30.2.0" + jest-runtime "30.2.0" + jest-snapshot "30.2.0" + jest-util "30.2.0" + p-limit "^3.1.0" + pretty-format "30.2.0" + pure-rand "^7.0.0" + slash "^3.0.0" + stack-utils "^2.0.6" + jest-circus@^29.6.4, jest-circus@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" @@ -3771,6 +4580,22 @@ jest-circus@^29.6.4, jest-circus@^29.7.0: slash "^3.0.0" stack-utils "^2.0.3" +jest-cli@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-30.2.0.tgz#1780f8e9d66bf84a10b369aea60aeda7697dcc67" + integrity sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA== + dependencies: + "@jest/core" "30.2.0" + "@jest/test-result" "30.2.0" + "@jest/types" "30.2.0" + chalk "^4.1.2" + exit-x "^0.2.2" + import-local "^3.2.0" + jest-config "30.2.0" + jest-util "30.2.0" + jest-validate "30.2.0" + yargs "^17.7.2" + jest-cli@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" @@ -3788,6 +4613,36 @@ jest-cli@^29.7.0: jest-validate "^29.7.0" yargs "^17.3.1" +jest-config@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-30.2.0.tgz#29df8c50e2ad801cc59c406b50176c18c362a90b" + integrity sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA== + dependencies: + "@babel/core" "^7.27.4" + "@jest/get-type" "30.1.0" + "@jest/pattern" "30.0.1" + "@jest/test-sequencer" "30.2.0" + "@jest/types" "30.2.0" + babel-jest "30.2.0" + chalk "^4.1.2" + ci-info "^4.2.0" + deepmerge "^4.3.1" + glob "^10.3.10" + graceful-fs "^4.2.11" + jest-circus "30.2.0" + jest-docblock "30.2.0" + jest-environment-node "30.2.0" + jest-regex-util "30.0.1" + jest-resolve "30.2.0" + jest-runner "30.2.0" + jest-util "30.2.0" + jest-validate "30.2.0" + micromatch "^4.0.8" + parse-json "^5.2.0" + pretty-format "30.2.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + jest-config@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" @@ -3816,6 +4671,16 @@ jest-config@^29.7.0: slash "^3.0.0" strip-json-comments "^3.1.1" +jest-diff@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-30.2.0.tgz#e3ec3a6ea5c5747f605c9e874f83d756cba36825" + integrity sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A== + dependencies: + "@jest/diff-sequences" "30.0.1" + "@jest/get-type" "30.1.0" + chalk "^4.1.2" + pretty-format "30.2.0" + jest-diff@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" @@ -3826,6 +4691,13 @@ jest-diff@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" +jest-docblock@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-30.2.0.tgz#42cd98d69f887e531c7352309542b1ce4ee10256" + integrity sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA== + dependencies: + detect-newline "^3.1.0" + jest-docblock@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" @@ -3833,6 +4705,17 @@ jest-docblock@^29.7.0: dependencies: detect-newline "^3.0.0" +jest-each@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-30.2.0.tgz#39e623ae71641c2ac3ee69b3ba3d258fce8e768d" + integrity sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ== + dependencies: + "@jest/get-type" "30.1.0" + "@jest/types" "30.2.0" + chalk "^4.1.2" + jest-util "30.2.0" + pretty-format "30.2.0" + jest-each@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" @@ -3844,6 +4727,19 @@ jest-each@^29.7.0: jest-util "^29.7.0" pretty-format "^29.7.0" +jest-environment-node@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-30.2.0.tgz#3def7980ebd2fd86e74efd4d2e681f55ab38da0f" + integrity sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA== + dependencies: + "@jest/environment" "30.2.0" + "@jest/fake-timers" "30.2.0" + "@jest/types" "30.2.0" + "@types/node" "*" + jest-mock "30.2.0" + jest-util "30.2.0" + jest-validate "30.2.0" + jest-environment-node@^29.6.4, jest-environment-node@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" @@ -3861,6 +4757,24 @@ jest-get-type@^29.6.3: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== +jest-haste-map@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-30.2.0.tgz#808e3889f288603ac70ff0ac047598345a66022e" + integrity sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw== + dependencies: + "@jest/types" "30.2.0" + "@types/node" "*" + anymatch "^3.1.3" + fb-watchman "^2.0.2" + graceful-fs "^4.2.11" + jest-regex-util "30.0.1" + jest-util "30.2.0" + jest-worker "30.2.0" + micromatch "^4.0.8" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.3" + jest-haste-map@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" @@ -3903,6 +4817,14 @@ jest-junit@^16.0.0: uuid "^8.3.2" xml "^1.0.1" +jest-leak-detector@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz#292fdca7b7c9cf594e1e570ace140b01d8beb736" + integrity sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ== + dependencies: + "@jest/get-type" "30.1.0" + pretty-format "30.2.0" + jest-leak-detector@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" @@ -3911,6 +4833,16 @@ jest-leak-detector@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" +jest-matcher-utils@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz#69a0d4c271066559ec8b0d8174829adc3f23a783" + integrity sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg== + dependencies: + "@jest/get-type" "30.1.0" + chalk "^4.1.2" + jest-diff "30.2.0" + pretty-format "30.2.0" + jest-matcher-utils@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" @@ -3921,6 +4853,21 @@ jest-matcher-utils@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" +jest-message-util@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-30.2.0.tgz#fc97bf90d11f118b31e6131e2b67fc4f39f92152" + integrity sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@jest/types" "30.2.0" + "@types/stack-utils" "^2.0.3" + chalk "^4.1.2" + graceful-fs "^4.2.11" + micromatch "^4.0.8" + pretty-format "30.2.0" + slash "^3.0.0" + stack-utils "^2.0.6" + jest-message-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" @@ -3936,6 +4883,15 @@ jest-message-util@^29.7.0: slash "^3.0.0" stack-utils "^2.0.3" +jest-mock@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-30.2.0.tgz#69f991614eeb4060189459d3584f710845bff45e" + integrity sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw== + dependencies: + "@jest/types" "30.2.0" + "@types/node" "*" + jest-util "30.2.0" + jest-mock@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" @@ -3957,7 +4913,7 @@ jest-playwright-preset@^4.0.0: rimraf "^3.0.2" uuid "^8.3.2" -jest-pnp-resolver@^1.2.2: +jest-pnp-resolver@^1.2.2, jest-pnp-resolver@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== @@ -3988,6 +4944,14 @@ jest-regex-util@^29.0.0, jest-regex-util@^29.6.3: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== +jest-resolve-dependencies@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz#3370e2c0b49cc560f6a7e8ec3a59dd99525e1a55" + integrity sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w== + dependencies: + jest-regex-util "30.0.1" + jest-snapshot "30.2.0" + jest-resolve-dependencies@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" @@ -3996,6 +4960,20 @@ jest-resolve-dependencies@^29.7.0: jest-regex-util "^29.6.3" jest-snapshot "^29.7.0" +jest-resolve@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-30.2.0.tgz#2e2009cbd61e8f1f003355d5ec87225412cebcd7" + integrity sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A== + dependencies: + chalk "^4.1.2" + graceful-fs "^4.2.11" + jest-haste-map "30.2.0" + jest-pnp-resolver "^1.2.3" + jest-util "30.2.0" + jest-validate "30.2.0" + slash "^3.0.0" + unrs-resolver "^1.7.11" + jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" @@ -4011,6 +4989,34 @@ jest-resolve@^29.7.0: resolve.exports "^2.0.0" slash "^3.0.0" +jest-runner@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-30.2.0.tgz#c62b4c3130afa661789705e13a07bdbcec26a114" + integrity sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ== + dependencies: + "@jest/console" "30.2.0" + "@jest/environment" "30.2.0" + "@jest/test-result" "30.2.0" + "@jest/transform" "30.2.0" + "@jest/types" "30.2.0" + "@types/node" "*" + chalk "^4.1.2" + emittery "^0.13.1" + exit-x "^0.2.2" + graceful-fs "^4.2.11" + jest-docblock "30.2.0" + jest-environment-node "30.2.0" + jest-haste-map "30.2.0" + jest-leak-detector "30.2.0" + jest-message-util "30.2.0" + jest-resolve "30.2.0" + jest-runtime "30.2.0" + jest-util "30.2.0" + jest-watcher "30.2.0" + jest-worker "30.2.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + jest-runner@^29.6.4, jest-runner@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" @@ -4038,6 +5044,34 @@ jest-runner@^29.6.4, jest-runner@^29.7.0: p-limit "^3.1.0" source-map-support "0.5.13" +jest-runtime@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-30.2.0.tgz#395ea792cde048db1b0cd1a92dc9cb9f1921bf8a" + integrity sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg== + dependencies: + "@jest/environment" "30.2.0" + "@jest/fake-timers" "30.2.0" + "@jest/globals" "30.2.0" + "@jest/source-map" "30.0.1" + "@jest/test-result" "30.2.0" + "@jest/transform" "30.2.0" + "@jest/types" "30.2.0" + "@types/node" "*" + chalk "^4.1.2" + cjs-module-lexer "^2.1.0" + collect-v8-coverage "^1.0.2" + glob "^10.3.10" + graceful-fs "^4.2.11" + jest-haste-map "30.2.0" + jest-message-util "30.2.0" + jest-mock "30.2.0" + jest-regex-util "30.0.1" + jest-resolve "30.2.0" + jest-snapshot "30.2.0" + jest-util "30.2.0" + slash "^3.0.0" + strip-bom "^4.0.0" + jest-runtime@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" @@ -4073,6 +5107,33 @@ jest-serializer-html@^7.1.0: dependencies: diffable-html "^4.1.0" +jest-snapshot@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-30.2.0.tgz#266fbbb4b95fc4665ce6f32f1f38eeb39f4e26d0" + integrity sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA== + dependencies: + "@babel/core" "^7.27.4" + "@babel/generator" "^7.27.5" + "@babel/plugin-syntax-jsx" "^7.27.1" + "@babel/plugin-syntax-typescript" "^7.27.1" + "@babel/types" "^7.27.3" + "@jest/expect-utils" "30.2.0" + "@jest/get-type" "30.1.0" + "@jest/snapshot-utils" "30.2.0" + "@jest/transform" "30.2.0" + "@jest/types" "30.2.0" + babel-preset-current-node-syntax "^1.2.0" + chalk "^4.1.2" + expect "30.2.0" + graceful-fs "^4.2.11" + jest-diff "30.2.0" + jest-matcher-utils "30.2.0" + jest-message-util "30.2.0" + jest-util "30.2.0" + pretty-format "30.2.0" + semver "^7.7.2" + synckit "^0.11.8" + jest-snapshot@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" @@ -4099,6 +5160,18 @@ jest-snapshot@^29.7.0: pretty-format "^29.7.0" semver "^7.5.3" +jest-util@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-30.2.0.tgz#5142adbcad6f4e53c2776c067a4db3c14f913705" + integrity sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA== + dependencies: + "@jest/types" "30.2.0" + "@types/node" "*" + chalk "^4.1.2" + ci-info "^4.2.0" + graceful-fs "^4.2.11" + picomatch "^4.0.2" + jest-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" @@ -4111,6 +5184,18 @@ jest-util@^29.7.0: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-validate@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-30.2.0.tgz#273eaaed4c0963b934b5b31e96289edda6e0a2ef" + integrity sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw== + dependencies: + "@jest/get-type" "30.1.0" + "@jest/types" "30.2.0" + camelcase "^6.3.0" + chalk "^4.1.2" + leven "^3.1.0" + pretty-format "30.2.0" + jest-validate@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" @@ -4136,6 +5221,20 @@ jest-watch-typeahead@^2.0.0: string-length "^5.0.1" strip-ansi "^7.0.1" +jest-watcher@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-30.2.0.tgz#f9c055de48e18c979e7756a3917e596e2d69b07b" + integrity sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg== + dependencies: + "@jest/test-result" "30.2.0" + "@jest/types" "30.2.0" + "@types/node" "*" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + emittery "^0.13.1" + jest-util "30.2.0" + string-length "^4.0.2" + jest-watcher@^29.0.0, jest-watcher@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" @@ -4150,6 +5249,17 @@ jest-watcher@^29.0.0, jest-watcher@^29.7.0: jest-util "^29.7.0" string-length "^4.0.1" +jest-worker@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-30.2.0.tgz#fd5c2a36ff6058ec8f74366ec89538cc99539d26" + integrity sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g== + dependencies: + "@types/node" "*" + "@ungap/structured-clone" "^1.3.0" + jest-util "30.2.0" + merge-stream "^2.0.0" + supports-color "^8.1.1" + jest-worker@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" @@ -4170,6 +5280,16 @@ jest@^29.6.4: import-local "^3.0.2" jest-cli "^29.7.0" +jest@^30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-30.2.0.tgz#9f0a71e734af968f26952b5ae4b724af82681630" + integrity sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A== + dependencies: + "@jest/core" "30.2.0" + "@jest/types" "30.2.0" + import-local "^3.2.0" + jest-cli "30.2.0" + jju@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" @@ -4412,7 +5532,19 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -magic-string@^0.30.0, magic-string@^0.30.17, magic-string@^0.30.3: +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== + +magic-string@^0.30.0, magic-string@^0.30.17: + version "0.30.21" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91" + integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.5" + +magic-string@^0.30.3: version "0.30.19" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.19.tgz#cebe9f104e565602e5d2098c5f2e79a77cc86da9" integrity sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw== @@ -4433,6 +5565,11 @@ make-dir@^4.0.0: dependencies: semver "^7.5.3" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -4584,6 +5721,11 @@ nanoid@^3.3.11: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== +napi-postinstall@^0.3.0: + version "0.3.4" + resolved "https://registry.yarnpkg.com/napi-postinstall/-/napi-postinstall-0.3.4.tgz#7af256d6588b5f8e952b9190965d6b019653bbb9" + integrity sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -4601,10 +5743,10 @@ node-preload@^0.2.1: dependencies: process-on-spawn "^1.0.0" -node-releases@^2.0.21: - version "2.0.23" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.23.tgz#2ecf3d7ba571ece05c67c77e5b7b1b6fb9e18cea" - integrity sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg== +node-releases@^2.0.26: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== node-stdlib-browser@^1.2.0: version "1.3.1" @@ -4954,7 +6096,7 @@ pbkdf2@^3.1.2, pbkdf2@^3.1.5: sha.js "^2.4.12" to-buffer "^1.2.1" -picocolors@^1.1.1: +picocolors@1.1.1, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -4969,7 +6111,7 @@ picomatch@^4.0.2, picomatch@^4.0.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== -pirates@^4.0.4: +pirates@^4.0.4, pirates@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== @@ -5066,6 +6208,24 @@ prettier@^3.6.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393" integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== +pretty-format@30.2.0: + version "30.2.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-30.2.0.tgz#2d44fe6134529aed18506f6d11509d8a62775ebe" + integrity sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA== + dependencies: + "@jest/schemas" "30.0.5" + ansi-styles "^5.2.0" + react-is "^18.3.1" + +pretty-format@^27.0.2: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" @@ -5132,6 +6292,11 @@ pure-rand@^6.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== +pure-rand@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-7.0.1.tgz#6f53a5a9e3e4a47445822af96821ca509ed37566" + integrity sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ== + qs@^6.12.3: version "6.14.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930" @@ -5175,9 +6340,9 @@ react-docgen-typescript@^2.2.2: integrity sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg== react-docgen@^8.0.0: - version "8.0.1" - resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-8.0.1.tgz#45fb50048d49d63c9ae73b3286b88e9aa64e6cf9" - integrity sha512-kQKsqPLplY3Hx4jGnM3jpQcG3FQDt7ySz32uTHt3C9HAe45kNXG+3o16Eqn3Fw1GtMfHoN3b4J/z2e6cZJCmqQ== + version "8.0.2" + resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-8.0.2.tgz#450efcac75813e3d614d7bd15eb4066e2e7bcbf5" + integrity sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA== dependencies: "@babel/core" "^7.28.0" "@babel/traverse" "^7.28.0" @@ -5197,11 +6362,21 @@ react-docgen@^8.0.0: dependencies: scheduler "^0.27.0" -react-is@^18.0.0: +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-is@^18.0.0, react-is@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== +react-merge-refs@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-3.0.2.tgz#483b4e8029f89d805c4e55c8d22e9b8f77e3b58e" + integrity sha512-MSZAfwFfdbEvwkKWP5EI5chuLYnNUxNS7vyS0i1Jp+wtd8J4Ga2ddzhaE68aMol2Z4vCnRM/oGOo1a3V75UPlw== + "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0": version "19.2.0" resolved "https://registry.yarnpkg.com/react/-/react-19.2.0.tgz#d33dd1721698f4376ae57a54098cb47fc75d93a5" @@ -5300,7 +6475,7 @@ resolve.exports@^2.0.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.3.tgz#41955e6f1b4013b7586f873749a635dea07ebe3f" integrity sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A== -resolve@^1.17.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.8, resolve@~1.22.1, resolve@~1.22.2: +resolve@^1.17.0, resolve@^1.20.0, resolve@~1.22.1, resolve@~1.22.2: version "1.22.10" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== @@ -5309,6 +6484,15 @@ resolve@^1.17.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.8, resolve@~1.2 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.22.1, resolve@^1.22.8: + version "1.22.11" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" + integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== + dependencies: + is-core-module "^2.16.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + reusify@^1.0.4: version "1.1.0" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" @@ -5403,7 +6587,7 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2: +semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2, semver@^7.7.2: version "7.7.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== @@ -5588,7 +6772,7 @@ ssim.js@^3.1.1: resolved "https://registry.yarnpkg.com/ssim.js/-/ssim.js-3.5.0.tgz#d7276b9ee99b57a5ff0db34035f02f35197e62df" integrity sha512-Aj6Jl2z6oDmgYFFbQqK7fght19bXdOxY7Tj03nF+03M9gCBAjeIiO8/PlEGMfKDwYpw4q6iBqVq2YuREorGg/g== -stack-utils@^2.0.3: +stack-utils@^2.0.3, stack-utils@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== @@ -5596,9 +6780,9 @@ stack-utils@^2.0.3: escape-string-regexp "^2.0.0" storybook@^9.1.10: - version "9.1.10" - resolved "https://registry.yarnpkg.com/storybook/-/storybook-9.1.10.tgz#c06cfd8b77522cf17bd22d82d1e83af96362a78e" - integrity sha512-4+U7gF9hMpGilQmdVJwQaVZZEkD7XwC4ZDmBa51mobaPYelELEMoMfNM2hLyvB2x12gk1IJui1DnwOE4t+MXhw== + version "9.1.16" + resolved "https://registry.yarnpkg.com/storybook/-/storybook-9.1.16.tgz#fe92ac733781aa919104ecf090fd6615deaa6c69" + integrity sha512-339U14K6l46EFyRvaPS2ZlL7v7Pb+LlcXT8KAETrGPxq8v1sAjj2HAOB6zrlAK3M+0+ricssfAwsLCwt7Eg8TQ== dependencies: "@storybook/global" "^5.0.0" "@testing-library/jest-dom" "^6.6.3" @@ -5636,7 +6820,7 @@ string-argv@~0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== -string-length@^4.0.1: +string-length@^4.0.1, string-length@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== @@ -5737,16 +6921,16 @@ strip-indent@^3.0.0: min-indent "^1.0.0" strip-indent@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.1.0.tgz#8658a77cece02a4f27064bdb0a459257edb565f6" - integrity sha512-OA95x+JPmL7kc7zCu+e+TeYxEiaIyndRx0OrBcK2QPPH09oAndr2ALvymxWA+Lx1PYYvFUm4O63pRkdJAaW96w== + version "4.1.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.1.1.tgz#aba13de189d4ad9a17f6050e76554ac27585c7af" + integrity sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA== strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@8.1.1, supports-color@^8.0.0, supports-color@~8.1.1: +supports-color@8.1.1, supports-color@^8.0.0, supports-color@^8.1.1, supports-color@~8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -5772,6 +6956,25 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +synckit@^0.11.8: + version "0.11.11" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.11.tgz#c0b619cf258a97faa209155d9cd1699b5c998cb0" + integrity sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw== + dependencies: + "@pkgr/core" "^0.2.9" + +temporal-polyfill@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/temporal-polyfill/-/temporal-polyfill-0.3.0.tgz#7fe90e913ac5ec8e0d508fb50d04dd7a74cec23e" + integrity sha512-qNsTkX9K8hi+FHDfHmf22e/OGuXmfBm9RqNismxBrnSmZVJKegQ+HYYXT+R7Ha8F/YSm2Y34vmzD4cxMu2u95g== + dependencies: + temporal-spec "0.3.0" + +temporal-spec@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/temporal-spec/-/temporal-spec-0.3.0.tgz#8c4210c575fb28ba0a1c2e02ad68d1be5956a11f" + integrity sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ== + test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -5857,6 +7060,25 @@ ts-dedent@^2.0.0: resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== +ts-node@^10.9.2: + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + tsconfig-paths@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" @@ -5866,7 +7088,7 @@ tsconfig-paths@^4.2.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.0.1, tslib@^2.1.0: +tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -5957,10 +7179,37 @@ unplugin@^1.3.1: acorn "^8.14.0" webpack-virtual-modules "^0.6.2" -update-browserslist-db@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" - integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== +unrs-resolver@^1.7.11: + version "1.11.1" + resolved "https://registry.yarnpkg.com/unrs-resolver/-/unrs-resolver-1.11.1.tgz#be9cd8686c99ef53ecb96df2a473c64d304048a9" + integrity sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg== + dependencies: + napi-postinstall "^0.3.0" + optionalDependencies: + "@unrs/resolver-binding-android-arm-eabi" "1.11.1" + "@unrs/resolver-binding-android-arm64" "1.11.1" + "@unrs/resolver-binding-darwin-arm64" "1.11.1" + "@unrs/resolver-binding-darwin-x64" "1.11.1" + "@unrs/resolver-binding-freebsd-x64" "1.11.1" + "@unrs/resolver-binding-linux-arm-gnueabihf" "1.11.1" + "@unrs/resolver-binding-linux-arm-musleabihf" "1.11.1" + "@unrs/resolver-binding-linux-arm64-gnu" "1.11.1" + "@unrs/resolver-binding-linux-arm64-musl" "1.11.1" + "@unrs/resolver-binding-linux-ppc64-gnu" "1.11.1" + "@unrs/resolver-binding-linux-riscv64-gnu" "1.11.1" + "@unrs/resolver-binding-linux-riscv64-musl" "1.11.1" + "@unrs/resolver-binding-linux-s390x-gnu" "1.11.1" + "@unrs/resolver-binding-linux-x64-gnu" "1.11.1" + "@unrs/resolver-binding-linux-x64-musl" "1.11.1" + "@unrs/resolver-binding-wasm32-wasi" "1.11.1" + "@unrs/resolver-binding-win32-arm64-msvc" "1.11.1" + "@unrs/resolver-binding-win32-ia32-msvc" "1.11.1" + "@unrs/resolver-binding-win32-x64-msvc" "1.11.1" + +update-browserslist-db@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz#7802aa2ae91477f255b86e0e46dbc787a206ad4a" + integrity sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -6001,6 +7250,11 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-to-istanbul@^9.0.1: version "9.3.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" @@ -6192,6 +7446,14 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" +write-file-atomic@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" + integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^4.0.1" + ws@^8.18.0: version "8.18.3" resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" @@ -6245,7 +7507,7 @@ yargs-parser@^21.1.1: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@17.7.2, yargs@^17.3.1: +yargs@17.7.2, yargs@^17.3.1, yargs@^17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== @@ -6275,6 +7537,11 @@ yargs@^15.0.2: y18n "^4.0.0" yargs-parser "^18.1.2" +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" diff --git a/playwright/e2e/composer/CIDER.spec.ts b/playwright/e2e/composer/CIDER.spec.ts index fcfbd1aad3..af6843f89a 100644 --- a/playwright/e2e/composer/CIDER.spec.ts +++ b/playwright/e2e/composer/CIDER.spec.ts @@ -76,6 +76,57 @@ test.describe("Composer", () => { await expect(page.locator(".mx_EventTile_body", { hasText: "😇" })).toBeVisible(); }); + test.describe("render emoji picker with larger viewport height", async () => { + test.use({ viewport: { width: 1280, height: 720 } }); + test("render emoji picker", { tag: "@screenshot" }, async ({ page, app }) => { + await app.getComposer(false).getByRole("button", { name: "Emoji" }).click(); + await expect(page.getByTestId("mx_EmojiPicker")).toMatchScreenshot("emoji-picker.png"); + }); + }); + + test.describe("render emoji picker with small viewport height", async () => { + test.use({ viewport: { width: 1280, height: 360 } }); + test("render emoji picker", { tag: "@screenshot" }, async ({ page, app }) => { + await app.getComposer(false).getByRole("button", { name: "Emoji" }).click(); + await expect(page.getByTestId("mx_EmojiPicker")).toMatchScreenshot("emoji-picker-small.png"); + }); + }); + + test("should have focus lock in emoji picker", async ({ page, app }) => { + const emojiButton = app.getComposer(false).getByRole("button", { name: "Emoji" }); + + // Open emoji picker by clicking the button + await emojiButton.click(); + + // Wait for emoji picker to be visible + const emojiPicker = page.getByTestId("mx_EmojiPicker"); + await expect(emojiPicker).toBeVisible(); + + // Get initial focused element (should be search input) + const searchInput = emojiPicker.getByRole("textbox", { name: "Search" }); + await expect(searchInput).toBeFocused(); + + // Try to tab multiple times - focus should stay within emoji picker + await page.keyboard.press("Tab"); + await page.keyboard.press("Tab"); + await page.keyboard.press("Tab"); + await page.keyboard.press("Tab"); + await page.keyboard.press("Tab"); + + // Verify we're still within the emoji picker (not back to composer) + const focusedElement = await page.evaluate(() => document.activeElement?.closest(".mx_EmojiPicker")); + expect(focusedElement).not.toBeNull(); + + // Close with Escape key + await page.keyboard.press("Escape"); + + // Verify emoji picker is closed + await expect(emojiPicker).not.toBeVisible(); + + // Verify focus returns to emoji button + await expect(emojiButton).toBeFocused(); + }); + test.describe("when Control+Enter is required to send", () => { test.beforeEach(async ({ app }) => { await app.settings.setValue("MessageComposerInput.ctrlEnterToSend", null, SettingLevel.ACCOUNT, true); diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--bubble-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--bubble-layout-linux.png index 03d2084fdb..ad46ca44d5 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--bubble-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--bubble-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--group-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--group-layout-linux.png index d1edd45eb8..9a0f8b807c 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--group-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--group-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--irc-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--irc-layout-linux.png index ad25839e87..cadaf0ef73 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--irc-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--dark-theme--irc-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--bubble-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--bubble-layout-linux.png index 933c790e3d..5d240ebd76 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--bubble-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--bubble-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--group-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--group-layout-linux.png index bba9a07cf1..97a9852d28 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--group-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--group-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--irc-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--irc-layout-linux.png index 585d8cb5ee..b8dddbfd87 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--irc-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--high-contrast--irc-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--bubble-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--bubble-layout-linux.png index 7cd3f0c871..06f850704d 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--bubble-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--bubble-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--group-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--group-layout-linux.png index 195c907273..7fbee72774 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--group-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--group-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--irc-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--irc-layout-linux.png index fccee422d7..df986e20f5 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--irc-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--irc-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--bubble-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--bubble-layout-linux.png index d54c186e2d..d6bcac6994 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--bubble-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--bubble-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--group-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--group-layout-linux.png index 92ad8df33f..38743dd61c 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--group-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--group-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--irc-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--irc-layout-linux.png index c2972f34db..bba959643a 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--irc-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player--light-theme--monospace-font--irc-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-bubble-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-bubble-layout-linux.png index 4e77b7d094..b837798b3d 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-bubble-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-bubble-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-bubble-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-bubble-layout-linux.png index d5f4e7a7ca..30a8f94cbd 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-bubble-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-bubble-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-group-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-group-layout-linux.png index e9fca0d76b..8540165f4c 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-group-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-group-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-irc-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-irc-layout-linux.png index f9fe2e8c94..681d54cd26 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-irc-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-chain-irc-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-group-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-group-layout-linux.png index 52357bc9e4..c34d8925d7 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-group-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-group-layout-linux.png differ diff --git a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-irc-layout-linux.png b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-irc-layout-linux.png index 11e9499298..4d452abd29 100644 Binary files a/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-irc-layout-linux.png and b/playwright/snapshots/audio-player/audio-player.spec.ts/Selected-EventTile-of-audio-player-with-a-reply-irc-layout-linux.png differ diff --git a/playwright/snapshots/composer/CIDER.spec.ts/emoji-picker-linux.png b/playwright/snapshots/composer/CIDER.spec.ts/emoji-picker-linux.png new file mode 100644 index 0000000000..8c0daa555c Binary files /dev/null and b/playwright/snapshots/composer/CIDER.spec.ts/emoji-picker-linux.png differ diff --git a/playwright/snapshots/composer/CIDER.spec.ts/emoji-picker-small-linux.png b/playwright/snapshots/composer/CIDER.spec.ts/emoji-picker-small-linux.png new file mode 100644 index 0000000000..e3911831de Binary files /dev/null and b/playwright/snapshots/composer/CIDER.spec.ts/emoji-picker-small-linux.png differ diff --git a/playwright/snapshots/invite/invite-dialog.spec.ts/send-your-first-message-view-linux.png b/playwright/snapshots/invite/invite-dialog.spec.ts/send-your-first-message-view-linux.png index ec2d8d5443..36ba4b247d 100644 Binary files a/playwright/snapshots/invite/invite-dialog.spec.ts/send-your-first-message-view-linux.png and b/playwright/snapshots/invite/invite-dialog.spec.ts/send-your-first-message-view-linux.png differ diff --git a/playwright/snapshots/right-panel/file-panel.spec.ts/file-tiles-list-linux.png b/playwright/snapshots/right-panel/file-panel.spec.ts/file-tiles-list-linux.png index 86bebf9f1c..6c95b0d774 100644 Binary files a/playwright/snapshots/right-panel/file-panel.spec.ts/file-tiles-list-linux.png and b/playwright/snapshots/right-panel/file-panel.spec.ts/file-tiles-list-linux.png differ diff --git a/playwright/testcontainers/mas.ts b/playwright/testcontainers/mas.ts index 472c3f7763..2716abf580 100644 --- a/playwright/testcontainers/mas.ts +++ b/playwright/testcontainers/mas.ts @@ -10,7 +10,7 @@ import { type StartedPostgreSqlContainer, } from "@element-hq/element-web-playwright-common/lib/testcontainers"; -const TAG = "main@sha256:3d139198268dd06c42fe0fc7ffea5df0f2924704867f68e0a8eb3e542f91b9e8"; +const TAG = "main@sha256:0809c1870789e6c24f1344006b60d8bc9f8ca26f4ae4ba0d7957a1caf77e2be3"; /** * MatrixAuthenticationServiceContainer which freezes the docker digest to diff --git a/playwright/testcontainers/synapse.ts b/playwright/testcontainers/synapse.ts index f8dfa821ed..5331769eaf 100644 --- a/playwright/testcontainers/synapse.ts +++ b/playwright/testcontainers/synapse.ts @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. import { SynapseContainer as BaseSynapseContainer } from "@element-hq/element-web-playwright-common/lib/testcontainers"; -const TAG = "develop@sha256:5a505af08294414dd832517ee0eafadc1faa33a675e577ca073c6fa731c7e5a8"; +const TAG = "develop@sha256:450b176d61e75b73d1acbbfab1de5ec3ebe08ba0f08ec00da872f7b5aaa23e54"; /** * SynapseContainer which freezes the docker digest to stabilise tests, diff --git a/res/css/views/emojipicker/_EmojiPicker.pcss b/res/css/views/emojipicker/_EmojiPicker.pcss index 7542424605..bc14c2e958 100644 --- a/res/css/views/emojipicker/_EmojiPicker.pcss +++ b/res/css/views/emojipicker/_EmojiPicker.pcss @@ -8,7 +8,8 @@ Please see LICENSE files in the repository root for full details. .mx_EmojiPicker { width: 340px; - height: 450px; + height: min(450px, 80vh); + max-height: 80vh; border-radius: 4px; @@ -181,7 +182,7 @@ Please see LICENSE files in the repository root for full details. } } -.mx_EmojiPicker_body .mx_EmojiPicker_item_wrapper[tabindex="0"] .mx_EmojiPicker_item { +.mx_EmojiPicker_body_showHighlight .mx_EmojiPicker_item_wrapper [tabindex="0"] .mx_EmojiPicker_item { background-color: $focus-bg-color; } diff --git a/res/css/views/messages/_MPollBody.pcss b/res/css/views/messages/_MPollBody.pcss index 9889bb81bb..09160c083a 100644 --- a/res/css/views/messages/_MPollBody.pcss +++ b/res/css/views/messages/_MPollBody.pcss @@ -8,13 +8,18 @@ Please see LICENSE files in the repository root for full details. .mx_MPollBody { margin-top: 8px; + min-width: 0; /* Override fieldset default min-width: min-content */ + width: 100%; /* Ensure fieldset takes full available width */ + border: none; /* Remove default fieldset border */ + padding: 0; /* Remove default fieldset padding */ - h2 { + legend { font-weight: var(--cpd-font-weight-semibold); font-size: $font-15px; line-height: $font-24px; margin-top: 0; margin-bottom: 8px; + letter-spacing: var(--cpd-font-letter-spacing-heading-lg); .mx_MPollBody_edited { color: $roomtopic-color; @@ -23,7 +28,7 @@ Please see LICENSE files in the repository root for full details. } } - h2::before { + legend::before { content: ""; position: relative; display: inline-block; diff --git a/res/css/views/rooms/_EventBubbleTile.pcss b/res/css/views/rooms/_EventBubbleTile.pcss index 1607c45924..d98babab21 100644 --- a/res/css/views/rooms/_EventBubbleTile.pcss +++ b/res/css/views/rooms/_EventBubbleTile.pcss @@ -153,7 +153,7 @@ Please see LICENSE files in the repository root for full details. .mx_MediaBody { /* leave space for the timestamp */ - padding-right: 48px; + padding-right: 48px !important; } .mx_MImageBody { diff --git a/scripts/docker-package.sh b/scripts/docker-package.sh index 14444de556..29b9c4e75e 100755 --- a/scripts/docker-package.sh +++ b/scripts/docker-package.sh @@ -17,4 +17,10 @@ else fi DIST_VERSION=$("$DIR"/normalize-version.sh "$DIST_VERSION") + +yarn --cwd packages/shared-components install +yarn --cwd packages/shared-components link + +yarn link @element-hq/web-shared-components + VERSION=$DIST_VERSION yarn build diff --git a/scripts/layered.sh b/scripts/layered.sh index 3da209812d..0efdd7d226 100755 --- a/scripts/layered.sh +++ b/scripts/layered.sh @@ -44,3 +44,11 @@ fi yarn link matrix-js-sdk [ -d matrix-analytics-events ] && yarn link @matrix-org/analytics-events yarn install --frozen-lockfile $@ + +# Link shared components +pushd packages/shared-components +yarn link +yarn install --frozen-lockfile +popd + +yarn link @element-hq/web-shared-components diff --git a/sonar-project.properties b/sonar-project.properties index 205d82fe6c..3706897f63 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -6,12 +6,12 @@ sonar.organization=element-hq sonar.sources=src,res,packages/shared-components/src sonar.tests=test,playwright,src,packages -sonar.test.inclusions=test/*,playwright/*,src/**/*.test.*,packages/*/src/**/*.test.* +sonar.test.inclusions=test/*,playwright/*,src/**/*.test.*,packages/*/src/**/*.test.*,packages/*/src/test/**/* sonar.exclusions=__mocks__,docs,element.io,nginx sonar.cpd.exclusions=src/i18n/strings/*.json sonar.typescript.tsconfigPath=./tsconfig.json -sonar.javascript.lcov.reportPaths=coverage/lcov.info +sonar.javascript.lcov.reportPaths=coverage/lcov.info,packages/shared-components/coverage/lcov.info sonar.coverage.exclusions=\ test/**/*,\ playwright/**/*,\ @@ -21,5 +21,6 @@ sonar.coverage.exclusions=\ src/components/views/dialogs/devtools/**/*,\ src/utils/SessionLock.ts,\ src/**/*.d.ts,\ - src/vector/mobile_guide/**/* + src/vector/mobile_guide/**/* \ + packages/shared-components/src/test/**/* sonar.testExecutionReportPaths=coverage/jest-sonar-report.xml diff --git a/src/DateUtils.ts b/src/DateUtils.ts index 3af7e6d864..e3c7c348fa 100644 --- a/src/DateUtils.ts +++ b/src/DateUtils.ts @@ -13,7 +13,7 @@ import { type Optional } from "matrix-events-sdk"; import { _t, getUserLanguage } from "./languageHandler"; import { getUserTimezone } from "./TimezoneHandler"; -export { formatSeconds } from "../packages/shared-components/src/utils/DateUtils"; +export { formatSeconds } from "@element-hq/web-shared-components"; export const MINUTE_MS = 60000; export const HOUR_MS = MINUTE_MS * 60; diff --git a/src/accessibility/KeyboardShortcuts.ts b/src/accessibility/KeyboardShortcuts.ts index dd85dd8341..2872e1a1a2 100644 --- a/src/accessibility/KeyboardShortcuts.ts +++ b/src/accessibility/KeyboardShortcuts.ts @@ -9,7 +9,8 @@ Please see LICENSE files in the repository root for full details. */ // Import i18n.tsx instead of languageHandler to avoid circular deps -import { _td, type TranslationKey } from "../../packages/shared-components/src/utils/i18n"; +import { _td, type TranslationKey } from "@element-hq/web-shared-components"; + import { IS_MAC, IS_ELECTRON, Key } from "../Keyboard"; import { type IBaseSetting } from "../settings/Settings"; import { type KeyCombo } from "../KeyBindingsManager"; diff --git a/src/async-components/structures/ErrorView.tsx b/src/async-components/structures/ErrorView.tsx index eadad84ec5..9c0ba96dc0 100644 --- a/src/async-components/structures/ErrorView.tsx +++ b/src/async-components/structures/ErrorView.tsx @@ -8,9 +8,9 @@ Please see LICENSE files in the repository root for full details. import React, { type JSX, type ReactNode } from "react"; import { Text, Heading, Button, Separator } from "@vector-im/compound-web"; import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out"; +import { Flex } from "@element-hq/web-shared-components"; import SdkConfig from "../../SdkConfig"; -import { Flex } from "../../../packages/shared-components/src/utils/Flex"; import { _t } from "../../languageHandler"; import { Icon as AppleIcon } from "../../../res/themes/element/img/compound/apple.svg"; import { Icon as MicrosoftIcon } from "../../../res/themes/element/img/compound/microsoft.svg"; diff --git a/src/audio/Playback.ts b/src/audio/Playback.ts index 356e41ca84..fa0bceffdf 100644 --- a/src/audio/Playback.ts +++ b/src/audio/Playback.ts @@ -9,13 +9,13 @@ Please see LICENSE files in the repository root for full details. import EventEmitter from "events"; import { SimpleObservable } from "matrix-widget-api"; import { logger } from "matrix-js-sdk/src/logger"; +import { clamp } from "@element-hq/web-shared-components"; import { UPDATE_EVENT } from "../stores/AsyncStore"; import { arrayFastResample } from "../utils/arrays"; import { type IDestroyable } from "../utils/IDestroyable"; import { PlaybackClock } from "./PlaybackClock"; import { createAudioContext, decodeOgg } from "./compat"; -import { clamp } from "../../packages/shared-components/src/utils/numbers"; import { DEFAULT_WAVEFORM, PLAYBACK_WAVEFORM_SAMPLES } from "./consts"; import { PlaybackEncoder } from "../PlaybackEncoder"; @@ -202,6 +202,7 @@ export class Playback extends EventEmitter implements IDestroyable, PlaybackInte private onPlaybackEnd = async (): Promise => { await this.context.suspend(); this.emit(PlaybackState.Stopped); + this.clock.flagStop(); }; public async play(): Promise { @@ -248,9 +249,8 @@ export class Playback extends EventEmitter implements IDestroyable, PlaybackInte this.emit(PlaybackState.Paused); } - public async stop(): Promise { - await this.onPlaybackEnd(); - this.clock.flagStop(); + public stop(): Promise { + return this.onPlaybackEnd(); } public async toggle(): Promise { diff --git a/src/audio/RecorderWorklet.ts b/src/audio/RecorderWorklet.ts index 456ababe3f..5d6ce32630 100644 --- a/src/audio/RecorderWorklet.ts +++ b/src/audio/RecorderWorklet.ts @@ -1,16 +1,14 @@ /* -Copyrimport { type IAmplitudePayload, type ITimingPayload, PayloadEvent, WORKLET_NAME } from "./consts"; -import { percentageOf } from "../../packages/shared-components/src/utils/numbers"; - -// from AudioWorkletGlobalScope: https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletGlobalScope" 2024 New Vector Ltd. +Copyright 2024 New Vector Ltd. Copyright 2021 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ +import { percentageOf } from "@element-hq/web-shared-components"; + import { type IAmplitudePayload, type ITimingPayload, PayloadEvent, WORKLET_NAME } from "./consts"; -import { percentageOf } from "../../packages/shared-components/src/utils/numbers"; // from AudioWorkletGlobalScope: https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletGlobalScope declare const currentTime: number; diff --git a/src/audio/VoiceRecording.ts b/src/audio/VoiceRecording.ts index effb7df96b..705b96375a 100644 --- a/src/audio/VoiceRecording.ts +++ b/src/audio/VoiceRecording.ts @@ -11,6 +11,7 @@ import encoderPath from "opus-recorder/dist/encoderWorker.min.js"; import { SimpleObservable } from "matrix-widget-api"; import EventEmitter from "events"; import { logger } from "matrix-js-sdk/src/logger"; +import { clamp } from "@element-hq/web-shared-components"; import MediaDeviceHandler from "../MediaDeviceHandler"; import { type IDestroyable } from "../utils/IDestroyable"; @@ -19,7 +20,6 @@ import { PayloadEvent, WORKLET_NAME } from "./consts"; import { UPDATE_EVENT } from "../stores/AsyncStore"; import { createAudioContext } from "./compat"; import { FixedRollingArray } from "../utils/FixedRollingArray"; -import { clamp } from "../../packages/shared-components/src/utils/numbers"; import recorderWorkletFactory from "./recorderWorkletFactory"; const CHANNELS = 1; // stereo isn't important diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx index bdbd8b4a08..03538a21bf 100644 --- a/src/components/structures/ContextMenu.tsx +++ b/src/components/structures/ContextMenu.tsx @@ -12,6 +12,7 @@ import React, { type JSX, type CSSProperties, type RefObject, type SyntheticEven import ReactDOM from "react-dom"; import classNames from "classnames"; import FocusLock from "react-focus-lock"; +import { TooltipProvider } from "@vector-im/compound-web"; import { type Writeable } from "../../@types/common"; import UIStore from "../../stores/UIStore"; @@ -404,7 +405,7 @@ export default class ContextMenu extends React.PureComponent{body}; + body = {body}; } // filter props that are invalid for DOM elements @@ -425,15 +426,17 @@ export default class ContextMenu extends React.PureComponent {background} -
- {body} -
+ +
+ {body} +
+
)} diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index c2aa7f2f10..f9210ec96b 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -329,8 +329,8 @@ const SpaceSetupFirstRooms: React.FC<{ return createRoom(space.client, { createOpts: { preset: isPublic ? Preset.PublicChat : Preset.PrivateChat, - name, }, + name, spinner: false, encryption: false, andView: false, @@ -423,7 +423,7 @@ const SpaceSetupPublicShare: React.FC = ({

{_t("create_space|share_heading", { - name: justCreatedOpts?.createOpts?.name || space.name, + name: justCreatedOpts?.name || space.name, })}

{_t("create_space|share_description")}
@@ -449,7 +449,7 @@ const SpaceSetupPrivateScope: React.FC<{

{_t("create_space|private_personal_heading")}

{_t("create_space|private_personal_description", { - name: justCreatedOpts?.createOpts?.name || space.name, + name: justCreatedOpts?.name || space.name, })}
@@ -686,7 +686,7 @@ export default class SpaceRoomView extends React.PureComponent { diff --git a/src/components/utils/ListView.tsx b/src/components/utils/ListView.tsx index f99b7ab944..ca45b703a3 100644 --- a/src/components/utils/ListView.tsx +++ b/src/components/utils/ListView.tsx @@ -42,7 +42,7 @@ export interface IListViewProps index: number, item: Item, context: ListContext, - onFocus: (e: React.FocusEvent) => void, + onFocus: (item: Item, e: React.FocusEvent) => void, ) => JSX.Element; /** @@ -230,19 +230,26 @@ export function ListView(props: IListViewProps): JSX.Element => { - const onFocus = (e: React.FocusEvent): void => { - // If one of the item components has been focused directly, set the focused and tabIndex state - // and stop propagation so the ListViews onFocus doesn't also handle it. - const key = getItemKey(item); - setIsFocused(true); - setTabIndexKey(key); - e.stopPropagation(); - }; - return getItemComponent(index, item, context, onFocus); + /** + * Focus handler passed to each item component. + * Don't declare inside getItemComponent to avoid re-creating on each render. + */ + const onFocusForGetItemComponent = useCallback( + (item: Item, e: React.FocusEvent) => { + // If one of the item components has been focused directly, set the focused and tabIndex state + // and stop propagation so the ListViews onFocus doesn't also handle it. + const key = getItemKey(item); + setIsFocused(true); + setTabIndexKey(key); + e.stopPropagation(); }, - [getItemComponent, getItemKey], + [getItemKey], + ); + + const getItemComponentInternal = useCallback( + (index: number, item: Item, context: ListContext): JSX.Element => + getItemComponent(index, item, context, onFocusForGetItemComponent), + [getItemComponent, onFocusForGetItemComponent], ); /** * Handles focus events on the list. diff --git a/src/components/views/audio_messages/LegacySeekBar.tsx b/src/components/views/audio_messages/LegacySeekBar.tsx index 8177abf1be..fe9e1dacd8 100644 --- a/src/components/views/audio_messages/LegacySeekBar.tsx +++ b/src/components/views/audio_messages/LegacySeekBar.tsx @@ -7,10 +7,10 @@ Please see LICENSE files in the repository root for full details. */ import React, { type ChangeEvent, type CSSProperties, type ReactNode } from "react"; +import { percentageOf } from "@element-hq/web-shared-components"; import { type PlaybackInterface } from "../../../audio/Playback"; import { MarkedExecution } from "../../../utils/MarkedExecution"; -import { percentageOf } from "../../../../packages/shared-components/src/utils/numbers"; import { _t } from "../../../languageHandler"; interface IProps { diff --git a/src/components/views/audio_messages/LiveRecordingClock.tsx b/src/components/views/audio_messages/LiveRecordingClock.tsx index 8c3d2d2668..9ea00c2d67 100644 --- a/src/components/views/audio_messages/LiveRecordingClock.tsx +++ b/src/components/views/audio_messages/LiveRecordingClock.tsx @@ -7,9 +7,9 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; +import { Clock } from "@element-hq/web-shared-components"; import { type IRecordingUpdate } from "../../../audio/VoiceRecording"; -import { Clock } from "../../../../packages/shared-components/src/audio/Clock"; import { MarkedExecution } from "../../../utils/MarkedExecution"; import { type VoiceMessageRecording } from "../../../audio/VoiceMessageRecording"; diff --git a/src/components/views/audio_messages/PlaybackClock.tsx b/src/components/views/audio_messages/PlaybackClock.tsx index b4a51ba464..78ac81f25c 100644 --- a/src/components/views/audio_messages/PlaybackClock.tsx +++ b/src/components/views/audio_messages/PlaybackClock.tsx @@ -7,8 +7,8 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; +import { Clock } from "@element-hq/web-shared-components"; -import { Clock } from "../../../../packages/shared-components/src/audio/Clock"; import { type Playback, PlaybackState } from "../../../audio/Playback"; import { UPDATE_EVENT } from "../../../stores/AsyncStore"; diff --git a/src/components/views/audio_messages/PlaybackWaveform.tsx b/src/components/views/audio_messages/PlaybackWaveform.tsx index 4694946cc1..215011e6cb 100644 --- a/src/components/views/audio_messages/PlaybackWaveform.tsx +++ b/src/components/views/audio_messages/PlaybackWaveform.tsx @@ -7,11 +7,11 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; +import { percentageOf } from "@element-hq/web-shared-components"; import { arraySeed, arrayTrimFill } from "../../../utils/arrays"; import Waveform from "./Waveform"; import { type Playback } from "../../../audio/Playback"; -import { percentageOf } from "../../../../packages/shared-components/src/utils/numbers"; import { PLAYBACK_WAVEFORM_SAMPLES } from "../../../audio/consts"; interface IProps { diff --git a/src/components/views/beacon/BeaconListItem.tsx b/src/components/views/beacon/BeaconListItem.tsx index 4c5b777011..fb2dc2e17d 100644 --- a/src/components/views/beacon/BeaconListItem.tsx +++ b/src/components/views/beacon/BeaconListItem.tsx @@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details. import React, { type HTMLProps, useContext } from "react"; import { type Beacon, BeaconEvent, LocationAssetType } from "matrix-js-sdk/src/matrix"; +import { humanizeTime } from "@element-hq/web-shared-components"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import { useEventEmitterState } from "../../../hooks/useEventEmitter"; @@ -18,7 +19,6 @@ import BeaconStatus from "./BeaconStatus"; import { BeaconDisplayStatus } from "./displayStatus"; import StyledLiveBeaconIcon from "./StyledLiveBeaconIcon"; import ShareLatestLocation from "./ShareLatestLocation"; -import { humanizeTime } from "../../../../packages/shared-components/src/utils/humanize"; interface Props { beacon: Beacon; diff --git a/src/components/views/context_menus/MessageContextMenu.tsx b/src/components/views/context_menus/MessageContextMenu.tsx index 8d6f6cc6eb..39139be0db 100644 --- a/src/components/views/context_menus/MessageContextMenu.tsx +++ b/src/components/views/context_menus/MessageContextMenu.tsx @@ -735,7 +735,7 @@ export default class MessageContextMenu extends React.Component if (this.state.reactionPickerDisplayed) { const buttonRect = (this.reactButtonRef.current as HTMLElement)?.getBoundingClientRect(); reactionPicker = ( - + ); diff --git a/src/components/views/dialogs/CreateRoomDialog.tsx b/src/components/views/dialogs/CreateRoomDialog.tsx index d3771d102d..821182aff0 100644 --- a/src/components/views/dialogs/CreateRoomDialog.tsx +++ b/src/components/views/dialogs/CreateRoomDialog.tsx @@ -126,7 +126,7 @@ export default class CreateRoomDialog extends React.Component { const opts: IOpts = {}; const createOpts: IOpts["createOpts"] = (opts.createOpts = {}); opts.roomType = this.props.type; - createOpts.name = this.state.name; + opts.name = this.state.name; if (this.state.joinRule === JoinRule.Public) { createOpts.visibility = Visibility.Public; @@ -139,7 +139,7 @@ export default class CreateRoomDialog extends React.Component { } if (this.state.topic) { - createOpts.topic = this.state.topic; + opts.topic = this.state.topic; } if (this.state.noFederate) { createOpts.creation_content = { "m.federate": false }; diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index b0eaf707b2..9931dd9368 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -12,6 +12,7 @@ import { KnownMembership } from "matrix-js-sdk/src/types"; import { type MatrixCall } from "matrix-js-sdk/src/webrtc/call"; import { logger } from "matrix-js-sdk/src/logger"; import { uniqBy } from "lodash"; +import { RichList, RichItem, PillInput, Pill } from "@element-hq/web-shared-components"; import { Icon as EmailPillAvatarIcon } from "../../../../res/img/icon-email-pill-avatar.svg"; import { _t, _td } from "../../../languageHandler"; @@ -63,10 +64,6 @@ import AskInviteAnywayDialog, { type UnknownProfiles } from "./AskInviteAnywayDi import { SdkContextClass } from "../../../contexts/SDKContext"; import { type UserProfilesStore } from "../../../stores/UserProfilesStore"; import InviteProgressBody from "./InviteProgressBody.tsx"; -import { RichList } from "../../../../packages/shared-components/src/rich-list/RichList"; -import { RichItem } from "../../../../packages/shared-components/src/rich-list/RichItem"; -import { PillInput } from "../../../../packages/shared-components/src/pill-input/PillInput"; -import { Pill } from "../../../../packages/shared-components/src/pill-input/Pill"; // we have a number of types defined from the Matrix spec which can't reasonably be altered here. /* eslint-disable camelcase */ diff --git a/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx b/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx index 94d9a30e54..f1f81a2bf2 100644 --- a/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx +++ b/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx @@ -12,8 +12,8 @@ import { debounce } from "lodash"; import classNames from "classnames"; import React, { type ChangeEvent, type FormEvent } from "react"; import { type SecretStorage } from "matrix-js-sdk/src/matrix"; +import { Flex } from "@element-hq/web-shared-components"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; import { _t } from "../../../../languageHandler"; import { EncryptionCard } from "../../settings/encryption/EncryptionCard"; import { EncryptionCardButtons } from "../../settings/encryption/EncryptionCardButtons"; diff --git a/src/components/views/elements/SettingsDropdown.tsx b/src/components/views/elements/SettingsDropdown.tsx index 4aa746ea15..db78e7cc36 100644 --- a/src/components/views/elements/SettingsDropdown.tsx +++ b/src/components/views/elements/SettingsDropdown.tsx @@ -6,13 +6,13 @@ Please see LICENSE files in the repository root for full details. */ import React, { type JSX, useCallback, useId, useState } from "react"; +import { _t } from "@element-hq/web-shared-components"; import SettingsStore from "../../../settings/SettingsStore"; import { type SettingLevel } from "../../../settings/SettingLevel"; import { SETTINGS, type StringSettingKey } from "../../../settings/Settings"; import { useSettingValueAt } from "../../../hooks/useSettings.ts"; import Dropdown, { type DropdownProps } from "./Dropdown.tsx"; -import { _t } from "../../../../packages/shared-components/src/utils/i18n.tsx"; interface Props { settingKey: StringSettingKey; diff --git a/src/components/views/emojipicker/Category.tsx b/src/components/views/emojipicker/Category.tsx index 9ffe1dce14..75734a5d16 100644 --- a/src/components/views/emojipicker/Category.tsx +++ b/src/components/views/emojipicker/Category.tsx @@ -61,17 +61,17 @@ class Category extends React.PureComponent { return (
{emojisForRow.map((emoji) => ( - +
+ +
))}
); @@ -118,6 +118,7 @@ class Category extends React.PureComponent { overflowMargin={0} renderItem={this.renderEmojiRow} role="grid" + aria-multiselectable /> ); diff --git a/src/components/views/emojipicker/Emoji.tsx b/src/components/views/emojipicker/Emoji.tsx index 26d15d4dc6..8cc104f9a5 100644 --- a/src/components/views/emojipicker/Emoji.tsx +++ b/src/components/views/emojipicker/Emoji.tsx @@ -15,13 +15,17 @@ import { RovingAccessibleButton } from "../../../accessibility/RovingTabIndex"; interface IProps { emoji: IEmoji; + /** + * Set of which emojis are already selected and should be decorated as such. + * If specified, emoji will use a checkbox role with aria-checked set appropriately. + */ selectedEmojis?: Set; onClick(ev: ButtonEvent, emoji: IEmoji): void; onMouseEnter(emoji: IEmoji): void; onMouseLeave(emoji: IEmoji): void; disabled?: boolean; id?: string; - role?: string; + className?: string; } class Emoji extends React.PureComponent { @@ -34,9 +38,10 @@ class Emoji extends React.PureComponent { onClick={(ev: ButtonEvent) => onClick(ev, emoji)} onMouseEnter={() => onMouseEnter(emoji)} onMouseLeave={() => onMouseLeave(emoji)} - className="mx_EmojiPicker_item_wrapper" - disabled={this.props.disabled} - role={this.props.role} + className={this.props.className} + disabled={this.props.disabled || undefined} + role={selectedEmojis ? "checkbox" : undefined} + aria-checked={this.props.disabled ? undefined : isSelected} focusOnMouseOver >
diff --git a/src/components/views/emojipicker/EmojiPicker.tsx b/src/components/views/emojipicker/EmojiPicker.tsx index c225bfcfae..3760cbc4c7 100644 --- a/src/components/views/emojipicker/EmojiPicker.tsx +++ b/src/components/views/emojipicker/EmojiPicker.tsx @@ -9,6 +9,8 @@ Please see LICENSE files in the repository root for full details. import React, { type Dispatch } from "react"; import { DATA_BY_CATEGORY, getEmojiFromUnicode, type Emoji as IEmoji } from "@matrix-org/emojibase-bindings"; +import { clamp } from "@element-hq/web-shared-components"; +import classNames from "classnames"; import { _t } from "../../../languageHandler"; import * as recent from "../../../emojipicker/recent"; @@ -26,7 +28,6 @@ import { Type, } from "../../../accessibility/RovingTabIndex"; import { Key } from "../../../Keyboard"; -import { clamp } from "../../../../packages/shared-components/src/utils/numbers"; import { type ButtonEvent } from "../elements/AccessibleButton"; export const CATEGORY_HEADER_HEIGHT = 20; @@ -50,6 +51,8 @@ interface IState { // should be enough to never have blank rows of emojis as // 3 rows of overflow are also rendered. The actual value is updated on scroll. viewportHeight: number; + // Track if user has interacted with arrow keys or search + showHighlight: boolean; } class EmojiPicker extends React.Component { @@ -66,6 +69,7 @@ class EmojiPicker extends React.Component { filter: "", scrollTop: 0, viewportHeight: 280, + showHighlight: false, }; // Convert recent emoji characters to emoji data, removing unknowns and duplicates @@ -152,24 +156,42 @@ class EmojiPicker extends React.Component { this.updateVisibility(); }; + // Given a roving emoji button returns the role=row element containing it + private getRow(rovingNode?: Element): Element | undefined { + return this.getGridcell(rovingNode)?.parentElement ?? undefined; + } + + // Given a roving emoji button returns the role=gridcell element containing it + private getGridcell(rovingNode?: Element): Element | undefined { + return rovingNode?.parentElement ?? undefined; + } + + // Given a role=gridcell node returns the roving emoji button contained within + private getRovingNode(gridcellNode?: Element): Element | undefined { + return gridcellNode?.children[0]; + } + private keyboardNavigation(ev: React.KeyboardEvent, state: RovingState, dispatch: Dispatch): void { - const node = state.activeNode; - const parent = node?.parentElement; - if (!parent || !state.activeNode) return; - const rowIndex = Array.from(parent.children).indexOf(node); + const rowElement = this.getRow(state.activeNode); + const gridcellNode = this.getGridcell(state.activeNode); + if (!rowElement || !gridcellNode || !state.activeNode) return; + + // Index of element within row container + const columnIndex = Array.from(rowElement.children).indexOf(gridcellNode); + // Index of element within the list of roving nodes const refIndex = state.nodes.indexOf(state.activeNode); let focusNode: HTMLElement | undefined; - let newParent: HTMLElement | undefined; + let newRowElement: Element | undefined; switch (ev.key) { case Key.ARROW_LEFT: focusNode = state.nodes[refIndex - 1]; - newParent = focusNode?.parentElement ?? undefined; + newRowElement = this.getRow(focusNode); break; case Key.ARROW_RIGHT: focusNode = state.nodes[refIndex + 1]; - newParent = focusNode?.parentElement ?? undefined; + newRowElement = this.getRow(focusNode); break; case Key.ARROW_UP: @@ -177,22 +199,30 @@ class EmojiPicker extends React.Component { // For up/down we find the prev/next parent by inspecting the refs either side of our row const node = ev.key === Key.ARROW_UP - ? state.nodes[refIndex - rowIndex - 1] - : state.nodes[refIndex - rowIndex + EMOJIS_PER_ROW]; - newParent = node?.parentElement ?? undefined; - const newTarget = newParent?.children[clamp(rowIndex, 0, newParent.children.length - 1)]; - focusNode = state.nodes.find((r) => r === newTarget); + ? state.nodes[refIndex - columnIndex - 1] + : state.nodes[refIndex - columnIndex + EMOJIS_PER_ROW]; + newRowElement = this.getRow(node); + if (newRowElement) { + const newColumnIndex = clamp(columnIndex, 0, newRowElement.children.length - 1); + const newTarget = this.getRovingNode(newRowElement?.children[newColumnIndex]); + focusNode = state.nodes.find((r) => r === newTarget); + } break; } } if (focusNode) { + // Only move actual DOM focus if an emoji already has focus + // If the input has focus, keep using aria-activedescendant for virtual focus + if (document.activeElement !== document.querySelector(".mx_EmojiPicker_search input")) { + focusNode?.focus(); + } dispatch({ type: Type.SetFocus, payload: { node: focusNode }, }); - if (parent !== newParent) { + if (rowElement !== newRowElement) { focusNode?.scrollIntoView({ behavior: "auto", block: "center", @@ -207,6 +237,20 @@ class EmojiPicker extends React.Component { private onKeyDown = (ev: React.KeyboardEvent, state: RovingState, dispatch: Dispatch): void => { if (state.activeNode && [Key.ARROW_DOWN, Key.ARROW_RIGHT, Key.ARROW_LEFT, Key.ARROW_UP].includes(ev.key)) { + // If highlight is not shown yet, show it and reset to first emoji + if (!this.state.showHighlight) { + this.setState({ showHighlight: true }); + // Reset to first emoji when showing highlight for the first time (or after it was hidden) + if (state.nodes.length > 0) { + dispatch({ + type: Type.SetFocus, + payload: { node: state.nodes[0] }, + }); + } + ev.preventDefault(); + ev.stopPropagation(); + return; + } this.keyboardNavigation(ev, state, dispatch); } }; @@ -248,6 +292,15 @@ class EmojiPicker extends React.Component { private onChangeFilter = (filter: string): void => { const lcFilter = filter.toLowerCase().trim(); // filter is case insensitive + + // User has typed a query, show highlight + // If filter is cleared, hide highlight again + if (lcFilter && !this.state.showHighlight) { + this.setState({ showHighlight: true }); + } else if (!lcFilter && this.state.showHighlight) { + this.setState({ showHighlight: false }); + } + for (const cat of this.categories) { let emojis: IEmoji[]; // If the new filter string includes the old filter string, we don't have to re-filter the whole dataset. @@ -309,8 +362,11 @@ class EmojiPicker extends React.Component { }; private onEnterFilter = (): void => { + // Only select emoji if highlight is shown + if (!this.state.showHighlight) return; + const btn = this.scrollRef.current?.containerRef.current?.querySelector( - '.mx_EmojiPicker_item_wrapper[tabindex="0"]', + '.mx_EmojiPicker_item_wrapper [tabindex="0"]', ); btn?.click(); this.props.onFinished(); @@ -365,7 +421,9 @@ class EmojiPicker extends React.Component { /> diff --git a/src/components/views/emojipicker/QuickReactions.tsx b/src/components/views/emojipicker/QuickReactions.tsx index a814a6b206..4b337cd5f5 100644 --- a/src/components/views/emojipicker/QuickReactions.tsx +++ b/src/components/views/emojipicker/QuickReactions.tsx @@ -73,6 +73,7 @@ class QuickReactions extends React.Component { onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} selectedEmojis={this.props.selectedEmojis} + className="mx_EmojiPicker_item_wrapper" /> ))} diff --git a/src/components/views/emojipicker/Search.tsx b/src/components/views/emojipicker/Search.tsx index db6ca813df..007fa2251d 100644 --- a/src/components/views/emojipicker/Search.tsx +++ b/src/components/views/emojipicker/Search.tsx @@ -71,7 +71,9 @@ class Search extends React.PureComponent { onChange={(ev) => this.props.onChange(ev.target.value)} onKeyDown={this.onKeyDown} ref={this.inputRef} - aria-activedescendant={this.context.state.activeNode?.id} + // Setting aria-activedescendant on the input allows screen readers to identify the active emoji. + // Setting it when there is not a query causes screen readers to read out the first emoji when focusing the input, and it continually tells you you are in the table vs the input. + aria-activedescendant={this.props.query ? this.context.state.activeNode?.id : undefined} aria-controls="mx_EmojiPicker_body" aria-haspopup="grid" aria-autocomplete="list" diff --git a/src/components/views/messages/LegacyCallEvent.tsx b/src/components/views/messages/LegacyCallEvent.tsx index 97a13db7e5..f43953fb6e 100644 --- a/src/components/views/messages/LegacyCallEvent.tsx +++ b/src/components/views/messages/LegacyCallEvent.tsx @@ -10,6 +10,7 @@ import React, { type JSX, createRef } from "react"; import { type MatrixEvent } from "matrix-js-sdk/src/matrix"; import { CallErrorCode, CallState } from "matrix-js-sdk/src/webrtc/call"; import classNames from "classnames"; +import { Clock } from "@element-hq/web-shared-components"; import { _t } from "../../../languageHandler"; import MemberAvatar from "../avatars/MemberAvatar"; @@ -18,7 +19,6 @@ import { LegacyCallEventGrouperEvent } from "../../structures/LegacyCallEventGro import AccessibleButton from "../elements/AccessibleButton"; import InfoTooltip, { InfoTooltipKind } from "../elements/InfoTooltip"; import { formatPreciseDuration } from "../../../DateUtils"; -import { Clock } from "../../../../packages/shared-components/src/audio/Clock"; const MAX_NON_NARROW_WIDTH = (450 / 70) * 100; diff --git a/src/components/views/messages/MAudioBody.tsx b/src/components/views/messages/MAudioBody.tsx index d29058d081..db61672c9c 100644 --- a/src/components/views/messages/MAudioBody.tsx +++ b/src/components/views/messages/MAudioBody.tsx @@ -10,6 +10,7 @@ import React, { type JSX, useEffect, useMemo } from "react"; import { logger } from "matrix-js-sdk/src/logger"; import { type IContent } from "matrix-js-sdk/src/matrix"; import { type MediaEventContent } from "matrix-js-sdk/src/types"; +import { AudioPlayerView } from "@element-hq/web-shared-components"; import { type Playback } from "../../../audio/Playback"; import InlineSpinner from "../elements/InlineSpinner"; @@ -20,7 +21,6 @@ import { PlaybackManager } from "../../../audio/PlaybackManager"; import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext"; import MediaProcessingError from "./shared/MediaProcessingError"; import { AudioPlayerViewModel } from "../../../viewmodels/audio/AudioPlayerViewModel"; -import { AudioPlayerView } from "../../../../packages/shared-components/src/audio/AudioPlayerView"; interface IState { error?: boolean; diff --git a/src/components/views/messages/MPollBody.tsx b/src/components/views/messages/MPollBody.tsx index 73fb82083a..15f2efce4b 100644 --- a/src/components/views/messages/MPollBody.tsx +++ b/src/components/views/messages/MPollBody.tsx @@ -325,11 +325,11 @@ export default class MPollBody extends React.Component { ) : null; return ( -
-

+
+ {pollEvent.question.text} {editedSpan} -

+
{pollEvent.answers.map((answer: PollAnswerSubevent) => { let answerVotes = 0; @@ -360,7 +360,7 @@ export default class MPollBody extends React.Component { {totalText} {isFetchingResponses && }
-
+ ); } } diff --git a/src/components/views/messages/MessageActionBar.tsx b/src/components/views/messages/MessageActionBar.tsx index aa3a5efe56..528e7f1abf 100644 --- a/src/components/views/messages/MessageActionBar.tsx +++ b/src/components/views/messages/MessageActionBar.tsx @@ -156,7 +156,7 @@ const ReactButton: React.FC = ({ mxEvent, reactions, onFocusC if (menuDisplayed && buttonRef.current) { const buttonRect = buttonRef.current.getBoundingClientRect(); contextMenu = ( - + ); diff --git a/src/components/views/messages/ReactionsRow.tsx b/src/components/views/messages/ReactionsRow.tsx index 0c5dbdd1e2..32f37f4c24 100644 --- a/src/components/views/messages/ReactionsRow.tsx +++ b/src/components/views/messages/ReactionsRow.tsx @@ -34,7 +34,7 @@ const ReactButton: React.FC = ({ mxEvent, reactions }) => { if (menuDisplayed && button.current) { const buttonRect = button.current.getBoundingClientRect(); contextMenu = ( - + ); diff --git a/src/components/views/right_panel/EmptyState.tsx b/src/components/views/right_panel/EmptyState.tsx index 1915cac8ce..8037e3673c 100644 --- a/src/components/views/right_panel/EmptyState.tsx +++ b/src/components/views/right_panel/EmptyState.tsx @@ -8,8 +8,7 @@ Please see LICENSE files in the repository root for full details. import React, { type ComponentType } from "react"; import { Text } from "@vector-im/compound-web"; - -import { Flex } from "../../../../packages/shared-components/src/utils/Flex"; +import { Flex } from "@element-hq/web-shared-components"; interface Props { Icon: ComponentType>; diff --git a/src/components/views/right_panel/RoomSummaryCardView.tsx b/src/components/views/right_panel/RoomSummaryCardView.tsx index 6ebd219ada..67eea91478 100644 --- a/src/components/views/right_panel/RoomSummaryCardView.tsx +++ b/src/components/views/right_panel/RoomSummaryCardView.tsx @@ -39,6 +39,7 @@ import ErrorIcon from "@vector-im/compound-design-tokens/assets/web/icons/error" import ErrorSolidIcon from "@vector-im/compound-design-tokens/assets/web/icons/error-solid"; import ChevronDownIcon from "@vector-im/compound-design-tokens/assets/web/icons/chevron-down"; import { JoinRule, type Room } from "matrix-js-sdk/src/matrix"; +import { Box, Flex } from "@element-hq/web-shared-components"; import BaseCard from "./BaseCard.tsx"; import { _t } from "../../../languageHandler.tsx"; @@ -46,9 +47,7 @@ import RoomAvatar from "../avatars/RoomAvatar.tsx"; import { E2EStatus } from "../../../utils/ShieldUtils.ts"; import { type RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks.ts"; import RoomName from "../elements/RoomName.tsx"; -import { Flex } from "../../../../packages/shared-components/src/utils/Flex"; import { Linkify, topicToHtml } from "../../../HtmlUtils.tsx"; -import { Box } from "../../../../packages/shared-components/src/utils/Box"; import { useRoomSummaryCardViewModel } from "../../viewmodels/right_panel/RoomSummaryCardViewModel.tsx"; import { useRoomTopicViewModel } from "../../viewmodels/right_panel/RoomSummaryCardTopicViewModel.tsx"; diff --git a/src/components/views/right_panel/user_info/UserInfoHeaderVerificationView.tsx b/src/components/views/right_panel/user_info/UserInfoHeaderVerificationView.tsx index e5ef652379..eae5101a6f 100644 --- a/src/components/views/right_panel/user_info/UserInfoHeaderVerificationView.tsx +++ b/src/components/views/right_panel/user_info/UserInfoHeaderVerificationView.tsx @@ -9,10 +9,10 @@ import React from "react"; import { type User, type RoomMember } from "matrix-js-sdk/src/matrix"; import { Text, Button, InlineSpinner, Badge } from "@vector-im/compound-web"; import { VerifiedIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; +import { Flex } from "@element-hq/web-shared-components"; import { useUserInfoVerificationViewModel } from "../../../viewmodels/right_panel/user_info/UserInfoHeaderVerificationViewModel"; import { type IDevice } from "../UserInfo"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; import { _t } from "../../../../languageHandler"; export const UserInfoHeaderVerificationView: React.FC<{ diff --git a/src/components/views/right_panel/user_info/UserInfoHeaderView.tsx b/src/components/views/right_panel/user_info/UserInfoHeaderView.tsx index 1b88d7814e..275175198c 100644 --- a/src/components/views/right_panel/user_info/UserInfoHeaderView.tsx +++ b/src/components/views/right_panel/user_info/UserInfoHeaderView.tsx @@ -8,11 +8,11 @@ Please see LICENSE files in the repository root for full details. import React, { type JSX } from "react"; import { type User, type RoomMember } from "matrix-js-sdk/src/matrix"; import { Heading, Tooltip, Text } from "@vector-im/compound-web"; +import { Flex } from "@element-hq/web-shared-components"; import { useUserfoHeaderViewModel } from "../../../viewmodels/right_panel/user_info/UserInfoHeaderViewModel"; import MemberAvatar from "../../avatars/MemberAvatar"; import { Container, type Member, type IDevice } from "../UserInfo"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; import PresenceLabel from "../../rooms/PresenceLabel"; import CopyableText from "../../elements/CopyableText"; import { UserInfoHeaderVerificationView } from "./UserInfoHeaderVerificationView"; diff --git a/src/components/views/rooms/AppsDrawer.tsx b/src/components/views/rooms/AppsDrawer.tsx index c40f756651..b4b62e9763 100644 --- a/src/components/views/rooms/AppsDrawer.tsx +++ b/src/components/views/rooms/AppsDrawer.tsx @@ -11,6 +11,7 @@ import classNames from "classnames"; import { Resizable, type Size } from "re-resizable"; import { type Room } from "matrix-js-sdk/src/matrix"; import { type IWidget } from "matrix-widget-api"; +import { clamp, percentageOf, percentageWithin } from "@element-hq/web-shared-components"; import AppTile from "../elements/AppTile"; import dis from "../../../dispatcher/dispatcher"; @@ -22,7 +23,6 @@ import ResizeHandle from "../elements/ResizeHandle"; import Resizer, { type IConfig } from "../../../resizer/resizer"; import PercentageDistributor from "../../../resizer/distributors/percentage"; import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore"; -import { clamp, percentageOf, percentageWithin } from "../../../../packages/shared-components/src/utils/numbers"; import UIStore from "../../../stores/UIStore"; import { type ActionPayload } from "../../../dispatcher/payloads"; import Spinner from "../elements/Spinner"; diff --git a/src/components/views/rooms/EmojiButton.tsx b/src/components/views/rooms/EmojiButton.tsx index 9da01ae92f..7eff845a9c 100644 --- a/src/components/views/rooms/EmojiButton.tsx +++ b/src/components/views/rooms/EmojiButton.tsx @@ -34,7 +34,7 @@ export function EmojiButton({ addEmoji, menuPosition, className }: IEmojiButtonP }; contextMenu = ( - + ); diff --git a/src/components/views/rooms/MemberList/MemberListHeaderView.tsx b/src/components/views/rooms/MemberList/MemberListHeaderView.tsx index e6e612b598..af8fe831cf 100644 --- a/src/components/views/rooms/MemberList/MemberListHeaderView.tsx +++ b/src/components/views/rooms/MemberList/MemberListHeaderView.tsx @@ -9,8 +9,8 @@ import { Search, Text, Button, Tooltip, InlineSpinner } from "@vector-im/compoun import React from "react"; import InviteIcon from "@vector-im/compound-design-tokens/assets/web/icons/user-add"; import { UserAddIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; +import { Flex } from "@element-hq/web-shared-components"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; import { type MemberListViewState } from "../../../viewmodels/memberlist/MemberListViewModel"; import { _t } from "../../../../languageHandler"; diff --git a/src/components/views/rooms/MemberList/MemberListView.tsx b/src/components/views/rooms/MemberList/MemberListView.tsx index 1193e245c5..33ef02ea0e 100644 --- a/src/components/views/rooms/MemberList/MemberListView.tsx +++ b/src/components/views/rooms/MemberList/MemberListView.tsx @@ -7,8 +7,8 @@ Please see LICENSE files in the repository root for full details. import { Form } from "@vector-im/compound-web"; import React, { type JSX, useCallback } from "react"; +import { Flex } from "@element-hq/web-shared-components"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; import { type MemberWithSeparator, SEPARATOR, @@ -45,7 +45,7 @@ const MemberListView: React.FC = (props: IProps) => { index: number, item: MemberWithSeparator, context: ListContext, - onFocus: (e: React.FocusEvent) => void, + onFocus: (item: MemberWithSeparator, e: React.FocusEvent) => void, ): JSX.Element => { const itemKey = getItemKey(item); const isRovingItem = itemKey === context.tabIndexKey; @@ -55,6 +55,7 @@ const MemberListView: React.FC = (props: IProps) => { } else if (item.member) { return ( = (props: IProps) => { } else { return ( void; + onFocus: (item: MemberWithSeparator, e: React.FocusEvent) => void; } export function RoomMemberTileView(props: IProps): JSX.Element { @@ -60,7 +65,7 @@ export function RoomMemberTileView(props: IProps): JSX.Element { return ( props.onFocus(props.item, e)} avatarJsx={av} presenceJsx={presenceJSX} nameJsx={nameJSX} diff --git a/src/components/views/rooms/MemberList/tiles/ThreePidInviteTileView.tsx b/src/components/views/rooms/MemberList/tiles/ThreePidInviteTileView.tsx index e4f5d1dbaf..22be2fd4af 100644 --- a/src/components/views/rooms/MemberList/tiles/ThreePidInviteTileView.tsx +++ b/src/components/views/rooms/MemberList/tiles/ThreePidInviteTileView.tsx @@ -12,14 +12,19 @@ import { type ThreePIDInvite } from "../../../../../models/rooms/ThreePIDInvite" import BaseAvatar from "../../../avatars/BaseAvatar"; import { MemberTileView } from "./common/MemberTileView"; import { InvitedIconView } from "./common/InvitedIconView"; +import { type MemberWithSeparator } from "../../../../viewmodels/memberlist/MemberListViewModel"; interface Props { + /** + * Needed for `onFocus` + */ + item: MemberWithSeparator; threePidInvite: ThreePIDInvite; memberIndex: number; memberCount: number; focused?: boolean; tabIndex?: number; - onFocus: (e: React.FocusEvent) => void; + onFocus: (item: MemberWithSeparator, e: React.FocusEvent) => void; } export function ThreePidInviteTileView(props: Props): JSX.Element { @@ -40,7 +45,7 @@ export function ThreePidInviteTileView(props: Props): JSX.Element { iconJsx={iconJsx} focused={props.focused} tabIndex={props.tabIndex} - onFocus={props.onFocus} + onFocus={(e) => props.onFocus(props.item, e)} /> ); } diff --git a/src/components/views/rooms/MemberList/tiles/common/InvitedIconView.tsx b/src/components/views/rooms/MemberList/tiles/common/InvitedIconView.tsx index a22ac031c2..35ac0ce899 100644 --- a/src/components/views/rooms/MemberList/tiles/common/InvitedIconView.tsx +++ b/src/components/views/rooms/MemberList/tiles/common/InvitedIconView.tsx @@ -8,8 +8,7 @@ Please see LICENSE files in the repository root for full details. import React, { type JSX } from "react"; import EmailIcon from "@vector-im/compound-design-tokens/assets/web/icons/email-solid"; import UserAddIcon from "@vector-im/compound-design-tokens/assets/web/icons/user-add-solid"; - -import { Flex } from "../../../../../../../packages/shared-components/src/utils/Flex"; +import { Flex } from "@element-hq/web-shared-components"; interface Props { isThreePid: boolean; diff --git a/src/components/views/rooms/NotificationDecoration.tsx b/src/components/views/rooms/NotificationDecoration.tsx index 7195966131..5dda3b0453 100644 --- a/src/components/views/rooms/NotificationDecoration.tsx +++ b/src/components/views/rooms/NotificationDecoration.tsx @@ -12,8 +12,8 @@ import NotificationOffIcon from "@vector-im/compound-design-tokens/assets/web/ic import VideoCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/video-call-solid"; import EmailIcon from "@vector-im/compound-design-tokens/assets/web/icons/email-solid"; import { UnreadCounter, Unread } from "@vector-im/compound-web"; +import { Flex } from "@element-hq/web-shared-components"; -import { Flex } from "../../../../packages/shared-components/src/utils/Flex"; import { type RoomNotificationState } from "../../../stores/notifications/RoomNotificationState"; import { useTypedEventEmitterState } from "../../../hooks/useEventEmitter"; import { NotificationStateEvents } from "../../../stores/notifications/NotificationState"; diff --git a/src/components/views/rooms/ReadReceiptGroup.tsx b/src/components/views/rooms/ReadReceiptGroup.tsx index 22d2f03697..910e0cfb52 100644 --- a/src/components/views/rooms/ReadReceiptGroup.tsx +++ b/src/components/views/rooms/ReadReceiptGroup.tsx @@ -212,38 +212,41 @@ export function ReadReceiptPerson({ onAfterClick, }: ReadReceiptPersonProps): JSX.Element { return ( - -
- { - dis.dispatch({ - action: Action.ViewUser, - // XXX: We should be using a real member object and not assuming what the receiver wants. - // The ViewUser action leads to the RightPanelStore, and RightPanelStoreIPanelState defines the - // member property of IRightPanelCardState as `RoomMember | User`, so we’re fine for now, but we - // should definitely clean this up later - member: roomMember ?? ({ userId } as User), - push: false, - }); - onAfterClick?.(); - }} - > - -
+ + { + dis.dispatch({ + action: Action.ViewUser, + // XXX: We should be using a real member object and not assuming what the receiver wants. + // The ViewUser action leads to the RightPanelStore, and RightPanelStoreIPanelState defines the + // member property of IRightPanelCardState as `RoomMember | User`, so we’re fine for now, but we + // should definitely clean this up later + member: roomMember ?? ({ userId } as User), + push: false, + }); + onAfterClick?.(); + }} + > + ); } diff --git a/src/components/views/rooms/RoomHeader/RoomHeader.tsx b/src/components/views/rooms/RoomHeader/RoomHeader.tsx index 8c162216ba..02fbf678a3 100644 --- a/src/components/views/rooms/RoomHeader/RoomHeader.tsx +++ b/src/components/views/rooms/RoomHeader/RoomHeader.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React, { type JSX, useCallback, useMemo, useState } from "react"; -import { Body as BodyText, Button, IconButton, Menu, MenuItem, Tooltip } from "@vector-im/compound-web"; +import { Text, Button, IconButton, Menu, MenuItem, Tooltip } from "@vector-im/compound-web"; import VideoCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/video-call-solid"; import VoiceCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/voice-call-solid"; import CloseCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/close"; @@ -19,14 +19,13 @@ import ErrorIcon from "@vector-im/compound-design-tokens/assets/web/icons/error- import PublicIcon from "@vector-im/compound-design-tokens/assets/web/icons/public"; import { JoinRule, type Room } from "matrix-js-sdk/src/matrix"; import { type ViewRoomOpts } from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle"; +import { Flex, Box } from "@element-hq/web-shared-components"; import { useRoomName } from "../../../../hooks/useRoomName.ts"; import { RightPanelPhases } from "../../../../stores/right-panel/RightPanelStorePhases.ts"; import { useMatrixClientContext } from "../../../../contexts/MatrixClientContext.tsx"; import { useRoomMemberCount, useRoomMembers } from "../../../../hooks/useRoomMembers.ts"; import { _t } from "../../../../languageHandler.tsx"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; -import { Box } from "../../../../../packages/shared-components/src/utils/Box"; import { getPlatformCallTypeProps, useRoomCall } from "../../../../hooks/room/useRoomCall.tsx"; import { useRoomThreadNotifications } from "../../../../hooks/room/useRoomThreadNotifications.ts"; import { useGlobalNotificationState } from "../../../../hooks/useGlobalNotificationState.ts"; @@ -54,22 +53,15 @@ import { RoomSettingsTab } from "../../dialogs/RoomSettingsDialog.tsx"; import { useScopedRoomContext } from "../../../../contexts/ScopedRoomContext.tsx"; import { ToggleableIcon } from "./toggle/ToggleableIcon.tsx"; import { CurrentRightPanelPhaseContextProvider } from "../../../../contexts/CurrentRightPanelPhaseContext.tsx"; -import { type LocalRoom } from "../../../../models/LocalRoom.ts"; +import { LocalRoom } from "../../../../models/LocalRoom.ts"; -export default function RoomHeader({ +function RoomHeaderButtons({ room, additionalButtons, - oobData, }: { - room: Room | LocalRoom; + room: Room; additionalButtons?: ViewRoomOpts["buttons"]; - oobData?: IOOBData; }): JSX.Element { - const client = useMatrixClientContext(); - - const roomName = useRoomName(room); - const joinRule = useRoomState(room, (state) => state.getJoinRule()); - const members = useRoomMembers(room, 2500); const memberCount = useRoomMemberCount(room, { throttleWait: 2500, includeInvited: true }); @@ -101,12 +93,9 @@ export default function RoomHeader({ const dmMember = useDmMember(room); const isDirectMessage = !!dmMember; - const e2eStatus = useEncryptionStatus(client, room); const notificationsEnabled = useFeatureEnabled("feature_notifications"); - const askToJoinEnabled = useFeatureEnabled("feature_ask_to_join"); - const videoClick = useCallback( (ev: React.MouseEvent) => videoCallClick(ev, callOptions[0]), [callOptions, videoCallClick], @@ -242,7 +231,118 @@ export default function RoomHeader({ isVideoRoom || roomContext.mainSplitContentType === MainSplitContentType.MaximisedWidget || roomContext.mainSplitContentType === MainSplitContentType.Call; + return ( + <> + {additionalButtons?.map((props) => { + const label = props.label(); + return ( + + { + event.stopPropagation(); + props.onClick(); + }} + > + {typeof props.icon === "function" ? props.icon() : props.icon} + + + ); + })} + + {isViewingCall && } + + {hasActiveCallSession && !isConnectedToCall && !isViewingCall ? ( + joinCallButton + ) : ( + <> + {!isVideoRoom && videoCallButton} + {!useElementCallExclusively && !isVideoRoom && voiceCallButton} + + )} + + {showChatButton && } + + + { + evt.stopPropagation(); + RightPanelStore.instance.showOrHidePhase(RightPanelPhases.ThreadPanel); + PosthogTrackers.trackInteraction("WebRoomHeaderButtonsThreadsButton", evt); + }} + aria-label={_t("common|threads")} + > + + + + {notificationsEnabled && ( + + { + evt.stopPropagation(); + RightPanelStore.instance.showOrHidePhase(RightPanelPhases.NotificationPanel); + }} + aria-label={_t("notifications|enable_prompt_toast_title")} + > + + + + )} + + + { + evt.stopPropagation(); + RightPanelStore.instance.showOrHidePhase(RightPanelPhases.RoomSummary); + }} + aria-label={_t("right_panel|room_summary_card|title")} + > + + + + + {!isDirectMessage && ( + + { + RightPanelStore.instance.showOrHidePhase(RightPanelPhases.MemberList); + e.stopPropagation(); + }} + aria-label={_t("common|n_members", { count: memberCount })} + > + {formatCount(memberCount)} + + + )} + + ); +} + +export default function RoomHeader({ + room, + additionalButtons, + oobData, +}: { + room: Room | LocalRoom; + additionalButtons?: ViewRoomOpts["buttons"]; + oobData?: IOOBData; +}): JSX.Element { + const client = useMatrixClientContext(); + const roomName = useRoomName(room); + const joinRule = useRoomState(room, (state) => state.getJoinRule()); + const dmMember = useDmMember(room); + const isDirectMessage = !!dmMember; + const e2eStatus = useEncryptionStatus(client, room); + const askToJoinEnabled = useFeatureEnabled("feature_ask_to_join"); const onAvatarClick = (): void => { defaultDispatcher.dispatch({ action: "open_room_settings", @@ -256,23 +356,29 @@ export default function RoomHeader({ {/* We hide this from the tabIndex list as it is a pointer shortcut and superfluous for a11y */} + {/* Disable on-click actions until the room is created */} + {/* Disable on-click actions until the room is created */} - - {additionalButtons?.map((props) => { - const label = props.label(); - - return ( - - { - event.stopPropagation(); - props.onClick(); - }} - > - {typeof props.icon === "function" ? props.icon() : props.icon} - - - ); - })} - - {isViewingCall && } - - {hasActiveCallSession && !isConnectedToCall && !isViewingCall ? ( - joinCallButton - ) : ( - <> - {!isVideoRoom && videoCallButton} - {!useElementCallExclusively && !isVideoRoom && voiceCallButton} - - )} - - {showChatButton && } - - - { - evt.stopPropagation(); - RightPanelStore.instance.showOrHidePhase(RightPanelPhases.ThreadPanel); - PosthogTrackers.trackInteraction("WebRoomHeaderButtonsThreadsButton", evt); - }} - aria-label={_t("common|threads")} - > - - - - {notificationsEnabled && ( - - { - evt.stopPropagation(); - RightPanelStore.instance.showOrHidePhase(RightPanelPhases.NotificationPanel); - }} - aria-label={_t("notifications|enable_prompt_toast_title")} - > - - - - )} - - - { - evt.stopPropagation(); - RightPanelStore.instance.showOrHidePhase(RightPanelPhases.RoomSummary); - }} - aria-label={_t("right_panel|room_summary_card|title")} - > - - - - - {!isDirectMessage && ( - - { - RightPanelStore.instance.showOrHidePhase(RightPanelPhases.MemberList); - e.stopPropagation(); - }} - aria-label={_t("common|n_members", { count: memberCount })} - > - {formatCount(memberCount)} - - + {/* If the room is local-only then we don't want to show any additional buttons, as it won't work */} + {room instanceof LocalRoom === false && ( + )} {askToJoinEnabled && } diff --git a/src/components/views/rooms/RoomListPanel/EmptyRoomList.tsx b/src/components/views/rooms/RoomListPanel/EmptyRoomList.tsx index 27fce169af..8c1d04b8c5 100644 --- a/src/components/views/rooms/RoomListPanel/EmptyRoomList.tsx +++ b/src/components/views/rooms/RoomListPanel/EmptyRoomList.tsx @@ -9,9 +9,9 @@ import React, { type JSX, type PropsWithChildren } from "react"; import { Button } from "@vector-im/compound-web"; import ChatIcon from "@vector-im/compound-design-tokens/assets/web/icons/chat"; import RoomIcon from "@vector-im/compound-design-tokens/assets/web/icons/room"; +import { Flex } from "@element-hq/web-shared-components"; import type { RoomListViewState } from "../../../viewmodels/roomlist/RoomListViewModel"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; import { _t } from "../../../../languageHandler"; import { FilterKey } from "../../../../stores/room-list-v3/skip-list/filters"; import { type PrimaryFilter } from "../../../viewmodels/roomlist/useFilteredRooms"; diff --git a/src/components/views/rooms/RoomListPanel/RoomList.tsx b/src/components/views/rooms/RoomListPanel/RoomList.tsx index 4aae621d96..c1c081ca9c 100644 --- a/src/components/views/rooms/RoomListPanel/RoomList.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomList.tsx @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -import React, { useCallback, useRef, useState, type JSX } from "react"; +import React, { useCallback, useRef, type JSX } from "react"; import { type Room } from "matrix-js-sdk/src/matrix"; import { type ScrollIntoViewLocation } from "react-virtuoso"; import { isEqual } from "lodash"; @@ -44,7 +44,6 @@ export function RoomList({ vm: { roomsResult, activeIndex } }: RoomListProps): J const lastSpaceId = useRef(undefined); const lastFilterKeys = useRef(undefined); const roomCount = roomsResult.rooms.length; - const [isScrolling, setIsScrolling] = useState(false); const getItemComponent = useCallback( ( index: number, @@ -53,7 +52,7 @@ export function RoomList({ vm: { roomsResult, activeIndex } }: RoomListProps): J spaceId: string; filterKeys: FilterKey[] | undefined; }>, - onFocus: (e: React.FocusEvent) => void, + onFocus: (item: Room, e: React.FocusEvent) => void, ): JSX.Element => { const itemKey = item.roomId; const isRovingItem = itemKey === context.tabIndexKey; @@ -69,11 +68,10 @@ export function RoomList({ vm: { roomsResult, activeIndex } }: RoomListProps): J roomIndex={index} roomCount={roomCount} onFocus={onFocus} - listIsScrolling={isScrolling} /> ); }, - [activeIndex, roomCount, isScrolling], + [activeIndex, roomCount], ); const getItemKey = useCallback((item: Room): string => { @@ -129,7 +127,6 @@ export function RoomList({ vm: { roomsResult, activeIndex } }: RoomListProps): J getItemKey={getItemKey} isItemFocusable={() => true} onKeyDown={keyDownCallback} - isScrolling={setIsScrolling} increaseViewportBy={{ bottom: EXTENDED_VIEWPORT_HEIGHT, top: EXTENDED_VIEWPORT_HEIGHT, diff --git a/src/components/views/rooms/RoomListPanel/RoomListHeaderView.tsx b/src/components/views/rooms/RoomListPanel/RoomListHeaderView.tsx index 0a12c91cda..7ce6f28321 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListHeaderView.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListHeaderView.tsx @@ -15,9 +15,9 @@ import PreferencesIcon from "@vector-im/compound-design-tokens/assets/web/icons/ import SettingsIcon from "@vector-im/compound-design-tokens/assets/web/icons/settings"; import VideoCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/video-call"; import ChatIcon from "@vector-im/compound-design-tokens/assets/web/icons/chat"; +import { Flex } from "@element-hq/web-shared-components"; import { _t } from "../../../../languageHandler"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; import { type RoomListHeaderViewState, useRoomListHeaderViewModel, diff --git a/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx b/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx index 4a37d90d9a..ad92559f5c 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx @@ -19,9 +19,9 @@ import NotificationIcon from "@vector-im/compound-design-tokens/assets/web/icons import NotificationOffIcon from "@vector-im/compound-design-tokens/assets/web/icons/notifications-off-solid"; import CheckIcon from "@vector-im/compound-design-tokens/assets/web/icons/check"; import { type Room } from "matrix-js-sdk/src/matrix"; +import { Flex } from "@element-hq/web-shared-components"; import { _t } from "../../../../languageHandler"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; import { type RoomListItemMenuViewState, useRoomListItemMenuViewModel, diff --git a/src/components/views/rooms/RoomListPanel/RoomListItemView.tsx b/src/components/views/rooms/RoomListPanel/RoomListItemView.tsx index a18cd337be..0061ac05ef 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListItemView.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListItemView.tsx @@ -8,15 +8,15 @@ import React, { type JSX, memo, useCallback, useEffect, useRef, useState } from "react"; import { type Room } from "matrix-js-sdk/src/matrix"; import classNames from "classnames"; +import { Flex } from "@element-hq/web-shared-components"; import { useRoomListItemViewModel } from "../../../viewmodels/roomlist/RoomListItemViewModel"; -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; import { RoomListItemMenuView } from "./RoomListItemMenuView"; import { NotificationDecoration } from "../NotificationDecoration"; import { RoomAvatarView } from "../../avatars/RoomAvatarView"; import { RoomListItemContextMenuView } from "./RoomListItemContextMenuView"; -interface RoomListItemViewProps extends React.HTMLAttributes { +interface RoomListItemViewProps extends Omit, "onFocus"> { /** * The room to display */ @@ -32,7 +32,7 @@ interface RoomListItemViewProps extends React.HTMLAttributes /** * A callback that indicates the item has received focus */ - onFocus: (e: React.FocusEvent) => void; + onFocus: (room: Room, e: React.FocusEvent) => void; /** * The index of the room in the list */ @@ -41,10 +41,6 @@ interface RoomListItemViewProps extends React.HTMLAttributes * The total number of rooms in the list */ roomCount: number; - /** - * Whether the list is currently scrolling - */ - listIsScrolling: boolean; } /** @@ -57,7 +53,6 @@ export const RoomListItemView = memo(function RoomListItemView({ onFocus, roomIndex: index, roomCount: count, - listIsScrolling, ...props }: RoomListItemViewProps): JSX.Element { const ref = useRef(null); @@ -100,7 +95,7 @@ export const RoomListItemView = memo(function RoomListItemView({ aria-selected={isSelected} aria-label={vm.a11yLabel} onClick={() => vm.openRoom()} - onFocus={onFocus} + onFocus={(e: React.FocusEvent) => onFocus(room, e)} onMouseOver={() => setHover(true)} onMouseOut={() => setHover(false)} onBlur={() => setHover(false)} @@ -148,9 +143,7 @@ export const RoomListItemView = memo(function RoomListItemView({ // Rendering multiple context menus can causes crashes in radix upstream, // See https://github.com/radix-ui/primitives/issues/2717. - // We also don't need the context menu while scrolling so can improve scroll performance - // by not rendering it. - if (!vm.showContextMenu || listIsScrolling) return content; + if (!vm.showContextMenu) return content; return ( = ({ children }) => ( <> diff --git a/src/components/views/settings/encryption/EncryptionCardEmphasisedContent.tsx b/src/components/views/settings/encryption/EncryptionCardEmphasisedContent.tsx index 4ad472ee82..2e705021bc 100644 --- a/src/components/views/settings/encryption/EncryptionCardEmphasisedContent.tsx +++ b/src/components/views/settings/encryption/EncryptionCardEmphasisedContent.tsx @@ -6,8 +6,7 @@ */ import React, { type JSX, type PropsWithChildren } from "react"; - -import { Flex } from "../../../../../packages/shared-components/src/utils/Flex"; +import { Flex } from "@element-hq/web-shared-components"; /** * A component for emphasised text within an {@link EncryptionCard} diff --git a/src/createRoom.ts b/src/createRoom.ts index c3bc1e6b1a..8e39260921 100644 --- a/src/createRoom.ts +++ b/src/createRoom.ts @@ -49,7 +49,19 @@ import { ElementCallEventType, ElementCallMemberEventType } from "./call-types"; export interface IOpts { dmUserId?: string; - createOpts?: ICreateRoomOpts; + /** + * The name of the room to be created. + */ + name?: string; + /** + * The topic for the room. + */ + topic?: string; + /** + * Additional options to pass to the room creation API. + * Note: "name", "topic", and "avatar" should be set via their respective properties in IOpts. + */ + createOpts?: Omit; spinner?: boolean; guestAccess?: boolean; encryption?: boolean; @@ -251,6 +263,14 @@ export default async function createRoom(client: MatrixClient, opts: IOpts): Pro }); } + if (opts.name) { + createOpts.name = opts.name; + } + + if (opts.topic) { + createOpts.topic = opts.topic; + } + if (opts.avatar) { let url = opts.avatar; if (opts.avatar instanceof File) { diff --git a/src/events/EventTileFactory.tsx b/src/events/EventTileFactory.tsx index cc9f4c0a2c..316f62fa94 100644 --- a/src/events/EventTileFactory.tsx +++ b/src/events/EventTileFactory.tsx @@ -18,6 +18,7 @@ import { M_POLL_START, } from "matrix-js-sdk/src/matrix"; import { type Optional } from "matrix-events-sdk"; +import { TextualEventView } from "@element-hq/web-shared-components"; import SettingsStore from "../settings/SettingsStore"; import type LegacyCallEventGrouper from "../components/structures/LegacyCallEventGrouper"; @@ -43,7 +44,6 @@ import { shouldDisplayAsBeaconTile } from "../utils/beacon/timeline"; import { type IBodyProps } from "../components/views/messages/IBodyProps"; import { ModuleApi } from "../modules/Api"; import { TextualEventViewModel } from "../viewmodels/event-tiles/TextualEventViewModel"; -import { TextualEventView } from "../../packages/shared-components/src/event-tiles/TextualEventView"; import { ElementCallEventType } from "../call-types"; // Subset of EventTile's IProps plus some mixins diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 92efe0a476..6bc5b18061 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -807,6 +807,17 @@ }, "developer_mode": "Vývojářský režim", "developer_tools": "Nástroje pro vývojáře", + "device_dehydrated_no": "Dehydratované: Ne", + "device_dehydrated_yes": "Dehydratované: Ano", + "device_id": "ID zařízení: %(deviceId)s", + "device_keys": "Klíče zařízení", + "device_verification_status": { + "signed_by_owner": "Stav ověření: Podepsáno vlastníkem", + "unknown": "Stav ověření: Neznámý", + "unverified": "Stav ověření: Není podepsáno vlastníkem", + "verified": "Stav ověření: Ověřeno křížovým podpisem" + }, + "devices": "Kryptografická zařízení (%(count)s)", "edit_setting": "Upravit nastavení", "edit_values": "Upravit hodnoty", "empty_string": "", @@ -822,6 +833,7 @@ "failed_to_save": "Nepodařilo se uložit nastavení.", "failed_to_send": "Nepodařilo se odeslat událost!", "id": "ID: ", + "invalid_device_key_id": "Neplatné ID klíče zařízení", "invalid_json": "Nevypadá to jako platný JSON.", "level": "Úroveň", "low_bandwidth_mode": "Režim malé šířky pásma", @@ -832,6 +844,7 @@ "notification_state": "Stav oznámení je %(notificationState)s", "notifications_debug": "Ladění oznámení", "number_of_users": "Počet uživatelů", + "only_joined_members": "Pouze připojení uživatelé", "original_event_source": "Původní zdroj události", "room_encrypted": "Místnost je šifrovaná ✅", "room_id": "ID místnosti: %(roomId)s", @@ -878,10 +891,23 @@ "toggle_event": "přepnout událost", "toolbox": "Sada nástrojů", "use_at_own_risk": "Toto uživatelské rozhraní NEKONTROLUJE typy hodnot. Použití na vlastní nebezpečí.", + "user_avatar": "Avatar: %(avatar)s", + "user_displayname": "Zobrazované jméno: %(displayname)s", + "user_id": "ID uživatele: %(userId)s", + "user_no_avatar": "Avatar: Žádný", + "user_no_displayname": "Zobrazované jméno: Žádné", "user_read_up_to": "Uživatel přečetl až: ", "user_read_up_to_ignore_synthetic": "Uživatel čte až do (ignoreSynthetic): ", "user_read_up_to_private": "Uživatel čte až do (m.read.private): ", "user_read_up_to_private_ignore_synthetic": "Uživatel čte až do (m.read.private;ignoreSynthetic): ", + "user_room_membership": "Členství: %(membership)s", + "user_verification_status": { + "identity_changed": "Stav ověření: Neověřeno a identita změněna", + "unverified": "Stav ověření: Neověřeno", + "verified": "Stav ověření: Ověřeno", + "was_verified": "Stav ověření: Bylo ověřeno, ale identita se změnila." + }, + "users": "Uživatelé", "value": "Hodnota", "value_colon": "Hodnota:", "value_in_this_room": "Hodnota v této místnosti", @@ -1572,22 +1598,22 @@ "explainer_1": "Sem přídejte servery a uživatele, které chcete ignorovat. Hvězdička pro %(brand)s zastupuje libovolný počet kterýchkoliv znaků. Např. @bot:* bude ignorovat všechny uživatele se jménem „bot“ na kterémkoliv serveru.", "explainer_2": "Lidé a servery jsou blokováni pomocí seznamů obsahující pravidla koho blokovat. Odebírání blokovacího seznamu znamená, že neuvidíte uživatele a servery na něm uvedené.", "lists": "Odebíráte:", - "lists_description_1": "Odebíráním seznamu zablokovaných uživatelů se přidáte do jeho místnosti!", + "lists_description_1": "Odebíráním seznamu vykázaných uživatelů se přidáte do jeho místnosti!", "lists_description_2": "Pokud to nechcete, tak prosím použijte jiný nástroj na blokování uživatelů.", "lists_heading": "Odebírané seznamy", - "lists_new_label": "ID nebo adresa seznamu zablokovaných", + "lists_new_label": "ID nebo adresa seznamu vykázaných", "no_lists": "Neodebíráte žádné seznamy", "personal_description": "Váš osobní seznam vykázaných obsahuje všechny uživatele/servery, od kterých osobně nechcete vidět zprávy. Po ignorování prvního uživatele/serveru se ve vašem seznamu místností objeví nová místnost s názvem \"%(myBanList)s\" - v této místnosti zůstaňte, aby seznam zákazů zůstal v platnosti.", "personal_empty": "Nikoho neignorujete.", - "personal_heading": "Osobní seznam blokací", + "personal_heading": "Osobní seznam vykázání", "personal_new_label": "Server nebo ID uživatele", "personal_new_placeholder": "např.: @bot:* nebo example.org", "personal_section": "Ignorujete:", - "room_name": "Můj seznam zablokovaných", + "room_name": "Můj seznam vykázaných", "room_topic": "Toto je váš seznam blokovaných uživatelů/serverů - neopouštějte tuto místnost!", "rules_empty": "Žádné", "rules_server": "Pravidla serveru", - "rules_title": "Pravidla blokování - %(roomName)s", + "rules_title": "Pravidla vykázání - %(roomName)s", "rules_user": "Pravidla uživatele", "something_went_wrong": "Něco se nepovedlo. Zkuste pro prosím znovu nebo se podívejte na detaily do konzole.", "title": "Ignorovaní uživatelé", @@ -2599,7 +2625,7 @@ "do_not_close_warning": "Nezavírejte toto okno, dokud není resetování dokončeno", "export_keys": "Exportovat klíče", "import_keys": "Importovat klíče", - "other_people_device_description": "Upozornění: Uživatelé, kteří s vámi výslovně neověřili (např. pomocí emotikonů), nedostanou vaše šifrované zprávy. Také neověřená zařízení ověřených uživatelů nebudou přijímat vaše šifrované zprávy.", + "other_people_device_description": "Upozornění: Uživatelé, kteří s vámi výslovně neověřili (např. pomocí emotikonů), nedostanou vaše šifrované zprávy. Také neověřená zařízení ověřených uživatelů nebudou přijímat vaše šifrované zprávy. Aby se změny projevily, je nutné restartovat aplikaci.", "other_people_device_label": "V šifrovaných místnostech posílat zprávy pouze ověřeným uživatelům", "other_people_device_title": "Zařízení ostatních uživatelů", "reset_identity": "Obnovit kryptografickou identitu", @@ -3650,7 +3676,7 @@ "changed_rule_rooms": "%(senderName)s změnil(a) pravidlo blokující místnosti odpovídající %(oldGlob)s na místnosti odpovídající %(newGlob)s z důvodu %(reason)s", "changed_rule_servers": "%(senderName)s změnil(a) pravidlo blokující servery odpovídající %(oldGlob)s na servery odpovídající %(newGlob)s z důvodu %(reason)s", "changed_rule_users": "%(senderName)s změnil(a) pravidlo blokující uživatele odpovídající %(oldGlob)s na uživatele odpovídající %(newGlob)s z důvodu %(reason)s", - "created_rule": "%(senderName)s vytvořil blokovací pravidlo odpovídající %(glob)s z důvodu %(reason)s", + "created_rule": "%(senderName)s vytvořil pravidlo vykázání odpovídající %(glob)s z důvodu %(reason)s", "created_rule_rooms": "%(senderName)s vytvořil pravidlo blokující místnosti odpovídající %(glob)s z důvodu %(reason)s", "created_rule_servers": "%(senderName)s vytvořil pravidlo blokující servery odpovídající %(glob)s z důvodu %(reason)s", "created_rule_users": "%(senderName)s vytvořil(a) pravidlo blokující uživatele odpovídající %(glob)s z důvodu %(reason)s", @@ -3659,8 +3685,8 @@ "removed_rule_rooms": "%(senderName)s odstranil pravidlo blokující místnosti odpovídající %(glob)s", "removed_rule_servers": "%(senderName)s odstranil pravidlo blokující servery odpovídající %(glob)s", "removed_rule_users": "%(senderName)s odstranil(a) pravidlo blokující uživatele odpovídající %(glob)s", - "updated_invalid_rule": "%(senderName)s aktualizoval neplatné pravidlo blokování", - "updated_rule": "%(senderName)s aktualizoval blokovací pravidlo odpovídající %(glob)s z důvodu %(reason)s", + "updated_invalid_rule": "%(senderName)s aktualizoval neplatné pravidlo vykázání", + "updated_rule": "%(senderName)s aktualizoval pravidlo vykázání odpovídající %(glob)s z důvodu %(reason)s", "updated_rule_rooms": "%(senderName)s aktualizoval pravidlo blokující místnosti odpovídající %(glob)s z důvodu %(reason)s", "updated_rule_servers": "%(senderName)s aktualizoval pravidlo blokující servery odpovídající %(glob)s z důvodu %(reason)s", "updated_rule_users": "%(senderName)s aktualizoval(a) pravidlo blokující uživatele odpovídající %(glob)s z důvodu %(reason)s" diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index 9d1c7408b2..a368ab5a71 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -805,6 +805,17 @@ }, "developer_mode": "Entwicklungsmodus", "developer_tools": "Entwicklungswerkzeuge", + "device_dehydrated_no": "Dehydriert: Nein", + "device_dehydrated_yes": "Dehydriert: Ja", + "device_id": "Geräte-ID:%(deviceId)s", + "device_keys": "Geräteschlüssel", + "device_verification_status": { + "signed_by_owner": "Verifizierungsstatus: Vom Eigentümer signiert", + "unknown": "Verifizierungsstatus: Unbekannt", + "unverified": "Verifizierungsstatus: Nicht vom Eigentümer signiert", + "verified": "Verifizierungsstatus: Durch Cross-Signing bestätigt" + }, + "devices": "Kryptografische Geräte (%(count)s )", "edit_setting": "Einstellung bearbeiten", "edit_values": "Werte bearbeiten", "empty_string": "", @@ -820,6 +831,7 @@ "failed_to_save": "Speichern der Einstellungen fehlgeschlagen.", "failed_to_send": "Übertragung des Ereignisses fehlgeschlagen!", "id": "ID: ", + "invalid_device_key_id": "Ungültige Geräteschlüssel-ID", "invalid_json": "Scheint kein gültiges JSON zu sein.", "level": "Level", "low_bandwidth_mode": "Modus für geringe Bandbreite", @@ -876,10 +888,23 @@ "toggle_event": "Event umschalten", "toolbox": "Werkzeugkasten", "use_at_own_risk": "Diese Benutzeroberfläche prüft nicht auf richtige Datentypen. Benutzung auf eigene Gefahr.", + "user_avatar": "Avatar: %(avatar)s", + "user_displayname": "Anzeigename: %(displayname)s", + "user_id": "Nutzer-ID: %(userId)s", + "user_no_avatar": "Avatar: Keiner", + "user_no_displayname": "Anzeigename: Keiner", "user_read_up_to": "Der Benutzer hat gelesen bis: ", "user_read_up_to_ignore_synthetic": "Der Nutzer hat bis (ignoreSynthetic) gelesen: ", "user_read_up_to_private": "Benutzer las bis (m.read.private): ", "user_read_up_to_private_ignore_synthetic": "Der Nutzer hat bis (m.read.private;ignoreSynthetic) gelesen: ", + "user_room_membership": "Mitgliedschaft: %(membership)s", + "user_verification_status": { + "identity_changed": "Verifizierungsstatus: Nicht verifiziert und Identität geändert", + "unverified": "Verifizierungsstatus: Nicht verifiziert", + "verified": "Verifizierungsstatus: Verifiziert", + "was_verified": "Verifizierungsstatus: Wurde verifiziert, aber die Identität hat sich geändert." + }, + "users": "Nutzer", "value": "Wert", "value_colon": "Wert:", "value_in_this_room": "Wert in diesem Chat", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index b762dccbde..86f9197e92 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2619,7 +2619,7 @@ "do_not_close_warning": "Do not close this window until the reset is finished", "export_keys": "Export keys", "import_keys": "Import keys", - "other_people_device_description": "Warning: users who have not explicitly verified with you (e.g. using emoji) will not receive your encrypted messages. Also, unverified devices of verified users will not receive your encrypted messages.", + "other_people_device_description": "Warning: users who have not explicitly verified with you (e.g. using emoji) will not receive your encrypted messages. Also, unverified devices of verified users will not receive your encrypted messages. Changes require an application restart to take effect.", "other_people_device_label": "In encrypted rooms, only send messages to verified users", "other_people_device_title": "Other people’s devices", "reset_identity": "Reset cryptographic identity", diff --git a/src/i18n/strings/et.json b/src/i18n/strings/et.json index 1be7222bfe..950e883940 100644 --- a/src/i18n/strings/et.json +++ b/src/i18n/strings/et.json @@ -805,6 +805,15 @@ }, "developer_mode": "Arendusrežiim", "developer_tools": "Arendusvahendid", + "device_id": "Seadme tunnus: %(deviceId)s", + "device_keys": "Seadme võtmed", + "device_verification_status": { + "signed_by_owner": "Verifitseerimise olek: omanik on allkirjastanud", + "unknown": "Verifitseerimise olek: teadmata", + "unverified": "Verifitseerimise olek: pole omaniku poolt allkirjastatud", + "verified": "Verifitseerimise olek: verifitseeritud risttunnustamisega" + }, + "devices": "Krüptoseadmed (%(count)s)", "edit_setting": "Muuda seadistust", "edit_values": "Muuda väärtusi", "empty_string": "", @@ -820,6 +829,7 @@ "failed_to_save": "Seadistuste salvestamine ei õnnestunud.", "failed_to_send": "Päringu või sündmuse saatmine ei õnnestunud!", "id": "ID: ", + "invalid_device_key_id": "Vigane seadme võtme tunnus", "invalid_json": "See ei tundu olema korrektse json-andmestikuna.", "level": "Tase", "low_bandwidth_mode": "Vähese ribalaiusega režiim", @@ -830,6 +840,7 @@ "notification_state": "Teavituste olek: %(notificationState)s", "notifications_debug": "Teavituste silumine", "number_of_users": "Kasutajate arv", + "only_joined_members": "Vaid liitunud kasutajad", "original_event_source": "Sündmuse töötlemata lähtekood", "room_encrypted": "Jututuba on krüptitud ✅", "room_id": "Jututoa tunnus: %(roomId)s", @@ -876,10 +887,23 @@ "toggle_event": "lülita sündmus sisse/välja", "toolbox": "Töövahendid", "use_at_own_risk": "See kasutajaliides ei oska kontrollida väärtuste tüüpi ja vormingut. Muudatusi teed omal vastutusel.", + "user_avatar": "Tunnuspilt: %(avatar)s", + "user_displayname": "Kuvatav nimi: %(displayname)s", + "user_id": "Kasutaja tunnus: %(userId)s", + "user_no_avatar": "Tunnuspilt: puudub", + "user_no_displayname": "Kuvatav nimi: puudub", "user_read_up_to": "Kasutaja on lugenud kuni: ", "user_read_up_to_ignore_synthetic": "Kasutaja luges kuni sõnumini (ignoreSynthetic): ", "user_read_up_to_private": "Kasutaja luges kuni sõnumini (m.read.private): ", "user_read_up_to_private_ignore_synthetic": "Kasutaja luges kuni sõnumini (m.read.private;ignoreSynthetic): ", + "user_room_membership": "Liikmelisus: %(membership)s", + "user_verification_status": { + "identity_changed": "Verifitseerimise olek: verifitseerimata ja võrguidentiteet on muutunud", + "unverified": "Verifitseerimise olek: verifitseerimata", + "verified": "Verifitseerimise olek: verifitseeritud", + "was_verified": "Verifitseerimise olek: oli verifitseeritud, aga võrguidentiteet muutus" + }, + "users": "Kasutajad", "value": "Väärtus", "value_colon": "Väärtus:", "value_in_this_room": "Väärtus selles jututoas", @@ -2593,7 +2617,7 @@ "do_not_close_warning": "Ära sulge seda akent enne, kui lähtestamine on lõppenud", "export_keys": "Ekspordi võtmed", "import_keys": "Impordi võtmed", - "other_people_device_description": "Hoiatus: kui kasutaja pole sinuga verifitseerimist läbi teinud (näiteks emojide võrdlemise abil), siis ta ei saa sinu krüptitud sõnumeid. Lisaks ei saadeta krüptitud sõnumeid verifitseeritud kasutajate verifitseerimata seadmetesse.", + "other_people_device_description": "Hoiatus: kui kasutaja pole sinuga verifitseerimist läbi teinud (näiteks emojide võrdlemise abil), siis ta ei saa sinu krüptitud sõnumeid. Lisaks ei saadeta krüptitud sõnumeid verifitseeritud kasutajate verifitseerimata seadmetesse. Muudatused vajavad jõustamiseks rakenduse uuesti käivitamist.", "other_people_device_label": "Krüptitud jututubades saada sõnumeid vaid verifitseeritud kasutajatele", "other_people_device_title": "Teiste kasutajate seadmed", "reset_identity": "Lähtesta krüptoidentiteet", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 740ac2065e..5d4ebe201d 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -805,6 +805,17 @@ }, "developer_mode": "Mode développeur", "developer_tools": "Outils de développement", + "device_dehydrated_no": "Déshydraté : Non", + "device_dehydrated_yes": "Déshydraté : Oui", + "device_id": "Identifiant de l'appareil : %(deviceId)s", + "device_keys": "Clés d'appareil", + "device_verification_status": { + "signed_by_owner": "Statut de vérification : Signé par le propriétaire", + "unknown": "Statut de vérification : Inconnu", + "unverified": "Statut de vérification : Non signé par le propriétaire", + "verified": "Statut de vérification : Vérifié par signature croisée" + }, + "devices": "Appareils cryptographiques (%(count)s )", "edit_setting": "Modifier le paramètre", "edit_values": "Modifier les valeurs", "empty_string": "", diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json index 2da5542044..87d337e584 100644 --- a/src/i18n/strings/sk.json +++ b/src/i18n/strings/sk.json @@ -812,6 +812,17 @@ }, "developer_mode": "Režim pre vývojárov", "developer_tools": "Vývojárske nástroje", + "device_dehydrated_no": "Dehydratované: Nie", + "device_dehydrated_yes": "Dehydratované: Áno", + "device_id": "ID zariadenia: %(deviceId)s", + "device_keys": "Kľúče zariadenia", + "device_verification_status": { + "signed_by_owner": "Stav overenia: Podpísané majiteľom", + "unknown": "Stav overenia: Neznámy", + "unverified": "Stav overenia: Nepodpísané vlastníkom", + "verified": "Stav overenia: Overené krížovým podpisom" + }, + "devices": "Kryptografické zariadenia (%(count)s )", "edit_setting": "Upraviť nastavenie", "edit_values": "Upraviť hodnoty", "empty_string": "", @@ -827,6 +838,7 @@ "failed_to_save": "Nepodarilo sa uložiť nastavenia.", "failed_to_send": "Nepodarilo sa odoslať udalosť!", "id": "ID: ", + "invalid_device_key_id": "Neplatný ID kľúč zariadenia", "invalid_json": "Nevyzerá to ako platný JSON.", "level": "Úroveň", "low_bandwidth_mode": "Režim nízkej šírky pásma", @@ -837,6 +849,7 @@ "notification_state": "Stav oznámenia je %(notificationState)s", "notifications_debug": "Ladenie oznámení", "number_of_users": "Počet používateľov", + "only_joined_members": "Iba pripojení používatelia", "original_event_source": "Pôvodný zdroj udalosti", "room_encrypted": "Miestnosť je šifrovaná ✅", "room_id": "ID miestnosti: %(roomId)s", @@ -885,10 +898,23 @@ "toggle_event": "prepnúť udalosť", "toolbox": "Nástroje", "use_at_own_risk": "Toto používateľské rozhranie nekontroluje typy hodnôt. Používajte ho na vlastné riziko.", + "user_avatar": "Profilový obrázok: %(avatar)s", + "user_displayname": "Zobrazované meno: %(displayname)s", + "user_id": "ID používateľa: %(userId)s", + "user_no_avatar": "Obrázok: Žiadny", + "user_no_displayname": "Zobrazované meno: Žiadne", "user_read_up_to": "Používateľ sa dočítal až do: ", "user_read_up_to_ignore_synthetic": "Používateľ prečíta až do (ignoreSynthetic): ", "user_read_up_to_private": "Používateľ prečíta až do (m.read.private): ", "user_read_up_to_private_ignore_synthetic": "Používateľ prečíta až do (m.read.private;ignoreSynthetic): ", + "user_room_membership": "Členstvo: %(membership)s", + "user_verification_status": { + "identity_changed": "Stav overenia: Neoverené a identita zmenená", + "unverified": "Stav overenia: Neoverené", + "verified": "Stav overenia: Overené", + "was_verified": "Stav overenia: Bolo overené, ale totožnosť sa zmenila" + }, + "users": "Používatelia", "value": "Hodnota", "value_colon": "Hodnota:", "value_in_this_room": "Hodnota v tejto miestnosti", @@ -2629,7 +2655,7 @@ "do_not_close_warning": "Nezatvárajte toto okno, kým sa obnovenie nedokončí", "export_keys": "Exportovať kľúče", "import_keys": "Importovať kľúče", - "other_people_device_description": "Upozornenie: používatelia, ktorí sa s vami výslovne neoverili (napr. pomocou emotikonov), nedostanú vaše šifrované správy. Neoverené zariadenia overených používateľov tiež nedostanú vaše šifrované správy.", + "other_people_device_description": "Upozornenie: používatelia, ktorí sa s vami výslovne neoverili (napr. pomocou emotikonov), nedostanú vaše šifrované správy. Neoverené zariadenia overených používateľov tiež nedostanú vaše šifrované správy. Zmeny nadobudnú platnosť po reštartovaní aplikácie.", "other_people_device_label": "V šifrovaných miestnostiach odosielajte správy iba overeným používateľom", "other_people_device_title": "Zariadenia iných ľudí", "reset_identity": "Obnoviť kryptografickú identitu", diff --git a/src/languageHandler.tsx b/src/languageHandler.tsx index 569db2d360..da31ab1811 100644 --- a/src/languageHandler.tsx +++ b/src/languageHandler.tsx @@ -5,19 +5,11 @@ * Please see LICENSE files in the repository root for full details. */ -import counterpart from "counterpart"; import { logger } from "matrix-js-sdk/src/logger"; import { type Optional } from "matrix-events-sdk"; import { MapWithDefault } from "matrix-js-sdk/src/utils"; import { type TranslationStringsObject } from "@matrix-org/react-sdk-module-api"; import _ from "lodash"; - -import SettingsStore from "./settings/SettingsStore"; -import PlatformPeg from "./PlatformPeg"; -import { SettingLevel } from "./settings/SettingLevel"; -import { retry } from "./utils/promise"; -import SdkConfig from "./SdkConfig"; -import { ModuleRunner } from "./modules/ModuleRunner"; import { _t, normalizeLanguageKey, @@ -25,7 +17,18 @@ import { type IVariables, KEY_SEPARATOR, getLangsJson, -} from "../packages/shared-components/src/utils/i18n"; + registerTranslations, + setLocale, + getLocale, + setMissingEntryGenerator as setMissingEntryGeneratorSharedComponents, +} from "@element-hq/web-shared-components"; + +import SettingsStore from "./settings/SettingsStore"; +import PlatformPeg from "./PlatformPeg"; +import { SettingLevel } from "./settings/SettingLevel"; +import { retry } from "./utils/promise"; +import SdkConfig from "./SdkConfig"; +import { ModuleRunner } from "./modules/ModuleRunner"; export { _t, @@ -40,7 +43,7 @@ export { normalizeLanguageKey, getNormalizedLanguageKeys, substitute, -} from "../packages/shared-components/src/utils/i18n"; +} from "@element-hq/web-shared-components"; const i18nFolder = "i18n/"; @@ -100,7 +103,7 @@ export function getUserLanguage(): string { // Currently only used in unit tests to avoid having to load // the translations in element-web export function setMissingEntryGenerator(f: (value: string) => void): void { - counterpart.setMissingEntryGenerator(f); + setMissingEntryGeneratorSharedComponents(f); } export async function setLanguage(...preferredLangs: string[]): Promise { @@ -116,8 +119,8 @@ export async function setLanguage(...preferredLangs: string[]): Promise { const languageData = await getLanguageRetry(i18nFolder + availableLanguages[chosenLanguage]); - counterpart.registerTranslations(chosenLanguage, languageData); - counterpart.setLocale(chosenLanguage); + registerTranslations(chosenLanguage, languageData); + setLocale(chosenLanguage); await SettingsStore.setValue("language", null, SettingLevel.DEVICE, chosenLanguage); // Adds a lot of noise to test runs, so disable logging there. @@ -128,7 +131,7 @@ export async function setLanguage(...preferredLangs: string[]): Promise { // Set 'en' as fallback language: if (chosenLanguage !== "en") { const fallbackLanguageData = await getLanguageRetry(i18nFolder + availableLanguages["en"]); - counterpart.registerTranslations("en", fallbackLanguageData); + registerTranslations("en", fallbackLanguageData); } await registerCustomTranslations(); @@ -166,7 +169,7 @@ export function getLanguageFromBrowser(): string { } export function getCurrentLanguage(): string { - return counterpart.getLocale(); + return getLocale(); } /** @@ -258,7 +261,7 @@ function doRegisterTranslations(customTranslations: TranslationStringsObject): v // Finally, tell counterpart about our translations for (const [lang, translations] of langs) { - counterpart.registerTranslations(lang, translations); + registerTranslations(lang, translations); } } diff --git a/src/modules/I18nApi.ts b/src/modules/I18nApi.ts index 43c101eca6..9a195a47ec 100644 --- a/src/modules/I18nApi.ts +++ b/src/modules/I18nApi.ts @@ -6,7 +6,7 @@ Please see LICENSE files in the repository root for full details. */ import { type I18nApi as II18nApi, type Variables, type Translations } from "@element-hq/element-web-module-api"; -import counterpart from "counterpart"; +import { registerTranslations } from "@element-hq/web-shared-components"; import { _t, getCurrentLanguage, type TranslationKey } from "../languageHandler.tsx"; @@ -32,7 +32,7 @@ export class I18nApi implements II18nApi { // Finally, tell counterpart about our translations for (const lang in langs) { - counterpart.registerTranslations(lang, langs[lang]); + registerTranslations(lang, langs[lang]); } } diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 78758ea277..2b2a57c2c5 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -9,10 +9,10 @@ Please see LICENSE files in the repository root for full details. import React, { type ReactNode } from "react"; import { STABLE_MSC4133_EXTENDED_PROFILES, UNSTABLE_MSC4133_EXTENDED_PROFILES } from "matrix-js-sdk/src/matrix"; +// Import these directly from shared-components to avoid circular deps +import { _t, _td, type TranslationKey } from "@element-hq/web-shared-components"; import { type MediaPreviewConfig } from "../@types/media_preview.ts"; -// Import i18n.tsx instead of languageHandler to avoid circular deps -import { _t, _td, type TranslationKey } from "../../packages/shared-components/src/utils/i18n"; import DeviceIsolationModeController from "./controllers/DeviceIsolationModeController.ts"; import { NotificationBodyEnabledController, diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 990de130ad..293dc06c03 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -10,11 +10,11 @@ import { type Room, RoomStateEvent, type MatrixEvent } from "matrix-js-sdk/src/m import { type Optional } from "matrix-events-sdk"; import { MapWithDefault, recursiveMapToObject } from "matrix-js-sdk/src/utils"; import { type IWidget } from "matrix-widget-api"; +import { clamp, defaultNumber, sum } from "@element-hq/web-shared-components"; import SettingsStore from "../../settings/SettingsStore"; import WidgetStore, { type IApp } from "../WidgetStore"; import { WidgetType } from "../../widgets/WidgetType"; -import { clamp, defaultNumber, sum } from "../../../packages/shared-components/src/utils/numbers"; import defaultDispatcher from "../../dispatcher/dispatcher"; import { ReadyWatchingStore } from "../ReadyWatchingStore"; import { SettingLevel } from "../../settings/SettingLevel"; diff --git a/src/toasts/IncomingCallToast.tsx b/src/toasts/IncomingCallToast.tsx index 18fd846fd2..f2de9aedc1 100644 --- a/src/toasts/IncomingCallToast.tsx +++ b/src/toasts/IncomingCallToast.tsx @@ -14,6 +14,7 @@ import CheckIcon from "@vector-im/compound-design-tokens/assets/web/icons/check" import CrossIcon from "@vector-im/compound-design-tokens/assets/web/icons/close"; import { logger } from "matrix-js-sdk/src/logger"; import { type IRTCNotificationContent } from "matrix-js-sdk/src/matrixrtc"; +import { AvatarWithDetails } from "@element-hq/web-shared-components"; import { _t } from "../languageHandler"; import RoomAvatar from "../components/views/avatars/RoomAvatar"; @@ -35,7 +36,6 @@ import { type Call, CallEvent } from "../models/Call"; import LegacyCallHandler, { AudioID } from "../LegacyCallHandler"; import { useEventEmitter } from "../hooks/useEventEmitter"; import { CallStore, CallStoreEvent } from "../stores/CallStore"; -import { AvatarWithDetails } from "../../packages/shared-components/src/avatar/AvatarWithDetails"; /** * Get the key for the incoming call toast. A combination of the event ID and room ID. diff --git a/src/utils/EventUtils.ts b/src/utils/EventUtils.ts index b3ba86a914..2c6d149342 100644 --- a/src/utils/EventUtils.ts +++ b/src/utils/EventUtils.ts @@ -70,7 +70,9 @@ export function canEditContent(matrixClient: MatrixClient, mxEvent: MatrixEvent) if ( !isCancellable || - mxEvent.status === EventStatus.CANCELLED || + // Editing local echos is not supported(results in send a message that references the local ID). + // We need to ensure the event is not local, and therefore has no send status. + mxEvent.status !== null || mxEvent.isRedacted() || mxEvent.isRelation(RelationType.Replace) || mxEvent.getSender() !== matrixClient.getUserId() diff --git a/src/utils/FormattingUtils.ts b/src/utils/FormattingUtils.ts index 0e10136438..b952c96170 100644 --- a/src/utils/FormattingUtils.ts +++ b/src/utils/FormattingUtils.ts @@ -13,7 +13,7 @@ import { useIdColorHash } from "@vector-im/compound-web"; import { _t, getCurrentLanguage, getUserLanguage } from "../languageHandler"; import { jsxJoin } from "./ReactUtils"; -export { formatBytes } from "../../packages/shared-components/src/utils/FormattingUtils"; +export { formatBytes } from "@element-hq/web-shared-components"; const locale = getCurrentLanguage(); diff --git a/src/utils/PinningUtils.ts b/src/utils/PinningUtils.ts index 9575e3b767..19a1a9a726 100644 --- a/src/utils/PinningUtils.ts +++ b/src/utils/PinningUtils.ts @@ -81,6 +81,9 @@ export default class PinningUtils { const room = matrixClient.getRoom(mxEvent.getRoomId()); if (!room) return false; + // Should have a non-local event id + if (mxEvent.status !== null) return false; + return PinningUtils.userHasPinOrUnpinPermission(matrixClient, room) && PinningUtils.isPinnable(mxEvent); } @@ -94,6 +97,9 @@ export default class PinningUtils { const room = matrixClient.getRoom(mxEvent.getRoomId()); if (!room) return false; + // Should have a non-local event id + if (mxEvent.status !== null) return false; + return PinningUtils.userHasPinOrUnpinPermission(matrixClient, room) && PinningUtils.isUnpinnable(mxEvent); } @@ -123,6 +129,9 @@ export default class PinningUtils { const eventId = mxEvent.getId(); if (!eventId) return; + // Should have a non-local event id + if (mxEvent.status !== null) return; + // Get the current pinned events of the room const pinnedIds: Array = room diff --git a/src/utils/arrays.ts b/src/utils/arrays.ts index 80896db71c..392436eee8 100644 --- a/src/utils/arrays.ts +++ b/src/utils/arrays.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { percentageOf, percentageWithin } from "../../packages/shared-components/src/utils/numbers"; +import { percentageOf, percentageWithin } from "@element-hq/web-shared-components"; /** * Quickly resample an array to have less/more data points. If an input which is larger diff --git a/src/vector/index.ts b/src/vector/index.ts index 943ed49c6a..e705014add 100644 --- a/src/vector/index.ts +++ b/src/vector/index.ts @@ -17,6 +17,9 @@ import { shouldPolyfill as shouldPolyFillIntlSegmenter } from "@formatjs/intl-se import { parseQsFromFragment } from "./url_utils"; import "./modernizr"; +// Import shared components CSS +import "@element-hq/web-shared-components/dist/element-web-shared-components.css"; + // Require common CSS here; this will make webpack process it into bundle.css. // Our own CSS (which is themed) is imported via separate webpack entry points // in webpack.config.js diff --git a/src/vector/jitsi/index.pcss b/src/vector/jitsi/index.pcss index 09299f1b7f..f51559f19a 100644 --- a/src/vector/jitsi/index.pcss +++ b/src/vector/jitsi/index.pcss @@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details. /* TODO: Match the user's theme: https://github.com/element-hq/element-web/issues/12794 */ +@import url("@vector-im/compound-design-tokens/assets/web/css/compound-design-tokens.css"); /* Path to `res` dir in the source tree */ $res: ../../../res; @@ -70,16 +71,22 @@ html { } #joinButton { - /* A mix of AccessibleButton styles */ - cursor: pointer; - padding: 7px 18px; + /* Copy of Compound Button styles */ + border: 1px solid var(--cpd-color-bg-action-primary-rest); + color: var(--cpd-color-text-on-solid-primary); + background-color: var(--cpd-color-bg-action-primary-rest); + padding-block: var(--cpd-space-2x); + padding-inline: var(--cpd-space-8x); + min-block-size: var(--cpd-space-12x); text-align: center; - border-radius: 4px; - display: inline-block; - font-size: 14px; - color: #ffffff; - background-color: #03b381; - border: 0; + border-radius: 24px; + display: inline-flex; + align-items: center; + justify-content: center; + font: var(--cpd-font-body-lg-semibold); + border: none; + word-break: keep-all; + cursor: pointer; } .icon { diff --git a/src/viewmodels/audio/AudioPlayerViewModel.ts b/src/viewmodels/audio/AudioPlayerViewModel.ts index 9c8d4c4822..f0f5f87989 100644 --- a/src/viewmodels/audio/AudioPlayerViewModel.ts +++ b/src/viewmodels/audio/AudioPlayerViewModel.ts @@ -7,17 +7,17 @@ import { type ChangeEvent, type KeyboardEvent } from "react"; import { logger } from "matrix-js-sdk/src/logger"; - import { + percentageOf, + BaseViewModel, type AudioPlayerViewSnapshot, type AudioPlayerViewModel as AudioPlayerViewModelInterface, -} from "../../../packages/shared-components/src/audio/AudioPlayerView"; +} from "@element-hq/web-shared-components"; + import { type Playback } from "../../audio/Playback"; import { UPDATE_EVENT } from "../../stores/AsyncStore"; -import { percentageOf } from "../../../packages/shared-components/src/utils/numbers"; import { getKeyBindingsManager } from "../../KeyBindingsManager"; import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts"; -import { BaseViewModel } from "../../../packages/shared-components/src/viewmodel"; /** * The number of seconds to skip when the user presses the left or right arrow keys. diff --git a/src/viewmodels/event-tiles/TextualEventViewModel.ts b/src/viewmodels/event-tiles/TextualEventViewModel.ts index a561dfa90d..46322c4590 100644 --- a/src/viewmodels/event-tiles/TextualEventViewModel.ts +++ b/src/viewmodels/event-tiles/TextualEventViewModel.ts @@ -6,12 +6,11 @@ Please see LICENSE files in the repository root for full details. */ import { MatrixEventEvent } from "matrix-js-sdk/src/matrix"; +import { type TextualEventViewSnapshot, BaseViewModel } from "@element-hq/web-shared-components"; import { type EventTileTypeProps } from "../../events/EventTileFactory"; import { MatrixClientPeg } from "../../MatrixClientPeg"; import { textForEvent } from "../../TextForEvent"; -import { type TextualEventViewSnapshot } from "../../../packages/shared-components/src/event-tiles/TextualEventView/TextualEventView"; -import { BaseViewModel } from "../../../packages/shared-components/src/viewmodel"; export class TextualEventViewModel extends BaseViewModel { public constructor(props: EventTileTypeProps) { diff --git a/test/unit-tests/async-components/structures/__snapshots__/ErrorView-test.tsx.snap b/test/unit-tests/async-components/structures/__snapshots__/ErrorView-test.tsx.snap index bb75f6263d..0af351ee85 100644 --- a/test/unit-tests/async-components/structures/__snapshots__/ErrorView-test.tsx.snap +++ b/test/unit-tests/async-components/structures/__snapshots__/ErrorView-test.tsx.snap @@ -98,7 +98,7 @@ exports[` should match snapshot 1`] = `

- - -
-
-
- - u - - - u - -
- 2 -
-
- + - - -
-
-
- - u - - - u - -
- 2 -
-
- + - - -
-
-
- - u - - - u - -
- 2 -
-
- +
- - -
-
-
- - u - - - u - -
- 2 -
-
should show the empty state when there are no pi tabindex="-1" >
has button to edit topic 1`] = ` title="" />
has button to edit topic 1`] = `

has button to edit topic 1`] = `

renders the room summary 1`] = ` title="" />
renders the room summary 1`] = `
renders the room topic in the summary 1`] = ` title="" />
renders the room topic in the summary 1`] = `

renders the room topic in the summary 1`] = `

with crypto enabled renders 1`] = ` class="mx_UserInfo_container mx_UserInfo_header" >

with crypto enabled renders 1`] = ` dir="auto" >
@user:example.com @@ -113,7 +113,7 @@ exports[` with crypto enabled renders 1`] = `

with crypto enabled should render a deactivate button for class="mx_UserInfo_container mx_UserInfo_header" >

with crypto enabled should render a deactivate button for dir="auto" >
@user:example.com @@ -400,7 +400,7 @@ exports[` with crypto enabled should render a deactivate button for

renders verification unavailable message 1`] = `

renders verification unavailable mes exports[` renders verified badge when user is verified 1`] = `

renders verified badge when user is exports[` renders verify button 1`] = `
renders custom user identifiers in the header 1` class="mx_UserInfo_container mx_UserInfo_header" >

renders custom user identifiers in the header 1` dir="auto" >
@user:example.com @@ -62,7 +62,7 @@ exports[` renders custom user identifiers in the header 1`

{ }), ); }); + + it("should fall back to userId if roomMember unspecified", async () => { + const { container } = renderReadReceipt({ roomMember: null }); + expect(container).toMatchSnapshot(); + }); }); }); diff --git a/test/unit-tests/components/views/rooms/RoomHeader/__snapshots__/RoomHeader-test.tsx.snap b/test/unit-tests/components/views/rooms/RoomHeader/__snapshots__/RoomHeader-test.tsx.snap index ea58935769..5d504919e6 100644 --- a/test/unit-tests/components/views/rooms/RoomHeader/__snapshots__/RoomHeader-test.tsx.snap +++ b/test/unit-tests/components/views/rooms/RoomHeader/__snapshots__/RoomHeader-test.tsx.snap @@ -3,7 +3,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
", () => { }); const listItem = screen.getByRole("option", { name: `Open room ${room.name}` }); - expect(listItem).toHaveClass("flex mx_RoomListItemView mx_RoomListItemView_hover"); + expect(listItem).toHaveClass("_flex_4dswl_9 mx_RoomListItemView mx_RoomListItemView_hover"); rerender( ", () => { onFocus={jest.fn()} roomIndex={0} roomCount={1} - listIsScrolling={false} />, ); @@ -193,26 +192,4 @@ describe("", () => { await user.keyboard("{Escape}"); expect(screen.queryByRole("menu")).toBeNull(); }); - - test("should not render context menu when list is scrolling", async () => { - const user = userEvent.setup(); - - mocked(useRoomListItemViewModel).mockReturnValue({ - ...defaultValue, - showContextMenu: true, - }); - - renderRoomListItem({ - listIsScrolling: true, - }); - - const button = screen.getByRole("option", { name: `Open room ${room.name}` }); - await user.pointer([{ target: button }, { keys: "[MouseRight]", target: button }]); - - // Context menu should not appear when scrolling - expect(screen.queryByRole("menu")).toBeNull(); - - // But the room item itself should still be rendered - expect(button).toBeInTheDocument(); - }); }); diff --git a/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/EmptyRoomList-test.tsx.snap b/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/EmptyRoomList-test.tsx.snap index 520a254aff..4d40661f79 100644 --- a/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/EmptyRoomList-test.tsx.snap +++ b/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/EmptyRoomList-test.tsx.snap @@ -3,7 +3,7 @@ exports[` should display empty state for filter favourite 1`] = `
@@ -24,7 +24,7 @@ exports[` should display empty state for filter favourite 1`] = exports[` should display empty state for filter people 1`] = `
@@ -45,7 +45,7 @@ exports[` should display empty state for filter people 1`] = ` exports[` should display empty state for filter rooms 1`] = `
@@ -66,7 +66,7 @@ exports[` should display empty state for filter rooms 1`] = ` exports[` should display the empty state for the invite filter 1`] = `
@@ -91,7 +91,7 @@ exports[` should display the empty state for the invite filter exports[` should display the empty state for the low priority filter 1`] = `
@@ -116,7 +116,7 @@ exports[` should display the empty state for the low priority f exports[` should display the empty state for the mention filter 1`] = `
@@ -141,7 +141,7 @@ exports[` should display the empty state for the mention filter exports[` should display the empty state for the unread filter 1`] = `
@@ -166,7 +166,7 @@ exports[` should display the empty state for the unread filter exports[` should not render the new room button if the user doesn't have the rights to create a room 1`] = `
@@ -181,7 +181,7 @@ exports[` should not render the new room button if the user doe Get started by messaging someone
compose menu should not display the compose menu

compose menu should not display the compose menu

should render 'room options' button 1`] = `

should render 'room options' button 1`] = `

space menu should display the space menu 1`] = `

space menu should display the space menu 1`] = `

space menu should not display the space menu 1`]

space menu should not display the space menu 1`]

should render the more options menu 1`] = `

Deleting key storage will remove your cryptographic identity and message keys from the server and turn off the following security features: diff --git a/test/unit-tests/components/views/settings/encryption/__snapshots__/ResetIdentityPanel-test.tsx.snap b/test/unit-tests/components/views/settings/encryption/__snapshots__/ResetIdentityPanel-test.tsx.snap index 1a00f42660..4bc5ca2598 100644 --- a/test/unit-tests/components/views/settings/encryption/__snapshots__/ResetIdentityPanel-test.tsx.snap +++ b/test/unit-tests/components/views/settings/encryption/__snapshots__/ResetIdentityPanel-test.tsx.snap @@ -84,7 +84,7 @@ exports[` should display the 'forgot recovery key' variant

    should display the 'sync failed' variant correct

    should reset the encryption when the continue bu
    should reset the encryption when the continue bu