diff --git a/.github/realease.yml b/.github/release.yml similarity index 100% rename from .github/realease.yml rename to .github/release.yml diff --git a/.github/workflows/build-and-publish-docker.yaml b/.github/workflows/build-and-publish-docker.yaml index fbe2d665..3ebb594a 100644 --- a/.github/workflows/build-and-publish-docker.yaml +++ b/.github/workflows/build-and-publish-docker.yaml @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: 📥 Download artifact - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ inputs.artifact_run_id }} @@ -53,7 +53,7 @@ jobs: uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 - name: Build and push Docker image - uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 + uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/build-element-call.yaml b/.github/workflows/build-element-call.yaml index 5a193eb5..fc5eee02 100644 --- a/.github/workflows/build-element-call.yaml +++ b/.github/workflows/build-element-call.yaml @@ -31,7 +31,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: Yarn cache - uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: cache: "yarn" node-version-file: ".node-version" diff --git a/.github/workflows/changelog-label.yml b/.github/workflows/changelog-label.yml index 6fdfd1e6..d8a82832 100644 --- a/.github/workflows/changelog-label.yml +++ b/.github/workflows/changelog-label.yml @@ -7,7 +7,7 @@ jobs: pr-changelog-label: runs-on: ubuntu-latest steps: - - uses: yogevbd/enforce-label-action@2.1.0 + - uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2 with: REQUIRED_LABELS_ANY: "PR-Bug-Fix,PR-Documentation,PR-Task,PR-Feature,PR-Improvement,PR-Developer-Experience,dependencies" REQUIRED_LABELS_ANY_DESCRIPTION: "Select at least one 'PR-' label" diff --git a/.github/workflows/deploy-to-netlify.yaml b/.github/workflows/deploy-to-netlify.yaml index 53a6931b..388192e4 100644 --- a/.github/workflows/deploy-to-netlify.yaml +++ b/.github/workflows/deploy-to-netlify.yaml @@ -46,7 +46,7 @@ jobs: Exercise caution. Use test accounts. - name: 📥 Download artifact - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} run-id: ${{ inputs.artifact_run_id }} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 1049930e..0efbcf5a 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -11,7 +11,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: Yarn cache - uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: cache: "yarn" node-version-file: ".node-version" diff --git a/.github/workflows/publish-embedded-packages.yaml b/.github/workflows/publish-embedded-packages.yaml index b09b3376..c309c91c 100644 --- a/.github/workflows/publish-embedded-packages.yaml +++ b/.github/workflows/publish-embedded-packages.yaml @@ -71,7 +71,7 @@ jobs: - name: Determine filename run: echo "FILENAME_PREFIX=element-call-embedded-${{ needs.versioning.outputs.UNPREFIXED_VERSION }}" >> "$GITHUB_ENV" - name: 📥 Download built element-call artifact - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id || github.run_id }} @@ -83,7 +83,7 @@ jobs: run: find ${{ env.FILENAME_PREFIX }} -type f -print0 | sort -z | xargs -0 sha256sum | tee ${{ env.FILENAME_PREFIX }}.sha256 - name: Upload if: ${{ needs.versioning.outputs.DRY_RUN == 'false' }} - uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2 + uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2 with: files: | ${{ env.FILENAME_PREFIX }}.tar.gz @@ -104,7 +104,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: 📥 Download built element-call artifact - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id || github.run_id }} @@ -113,7 +113,7 @@ jobs: # n.b. We don't enable corepack here because we are using plain npm - name: Setup node - uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version-file: .node-version registry-url: "https://registry.npmjs.org" @@ -145,7 +145,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: 📥 Download built element-call artifact - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id || github.run_id }} @@ -153,7 +153,7 @@ jobs: path: embedded/android/lib/src/main/assets/element-call - name: ☕️ Setup Java - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4 + uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 with: distribution: "temurin" java-version: "17" @@ -200,7 +200,7 @@ jobs: path: element-call - name: 📥 Download built element-call artifact - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id || github.run_id }} @@ -260,7 +260,7 @@ jobs: echo "iOS: ${{ needs.publish_ios.outputs.ARTIFACT_VERSION }}" - name: Add release notes if: ${{ needs.versioning.outputs.DRY_RUN == 'false' }} - uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2 + uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2 with: append_body: true body: | diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 463953fa..86169e16 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -31,7 +31,7 @@ jobs: - name: Determine filename run: echo "FILENAME_PREFIX=element-call-${VERSION:1}" >> "$GITHUB_ENV" - name: 📥 Download built element-call artifact - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id || github.run_id }} @@ -42,7 +42,7 @@ jobs: - name: Create Checksum run: find ${{ env.FILENAME_PREFIX }} -type f -print0 | sort -z | xargs -0 sha256sum | tee ${{ env.FILENAME_PREFIX }}.sha256 - name: Upload - uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2 + uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2 with: files: | ${{ env.FILENAME_PREFIX }}.tar.gz @@ -68,7 +68,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Add release note - uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2 + uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2 with: append_body: true body: | diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 85215e68..2ef4dc04 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -13,7 +13,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: Yarn cache - uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: cache: "yarn" node-version-file: ".node-version" @@ -22,7 +22,7 @@ jobs: - name: Vitest run: "yarn run test:coverage" - name: Upload to codecov - uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5 + uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Enable Corepack run: corepack enable - - uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: cache: "yarn" node-version-file: ".node-version" diff --git a/.github/workflows/translations-download.yaml b/.github/workflows/translations-download.yaml index ae1e92d0..fc4fbf40 100644 --- a/.github/workflows/translations-download.yaml +++ b/.github/workflows/translations-download.yaml @@ -18,7 +18,7 @@ jobs: - name: Enable Corepack run: corepack enable - - uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: cache: "yarn" node-version-file: ".node-version" diff --git a/README.md b/README.md index 8ac32d80..510b7c76 100644 --- a/README.md +++ b/README.md @@ -192,11 +192,6 @@ To use it, create a local config by, e.g., The `config.devenv.json` config should work with the backend development environment as outlined in the next section out of box. -> [!NOTE] -> Be aware, that this `config.devenv.json` is exposing a deprecated fallback -> LiveKit config key. If the homeserver advertises SFU backend via -> `.well-known/matrix/client` this has precedence. - You're now ready to launch the development server: ```sh @@ -212,12 +207,20 @@ See also: A docker compose file `dev-backend-docker-compose.yml` is provided to start the whole stack of components which is required for a local development environment: -- Minimum Synapse Setup (servername: `synapse.localhost`) -- LiveKit JWT Service (Note requires Federation API and hence a TLS reverse proxy) -- Minimum TLS reverse proxy (servername: `synapse.localhost`) Note certificates - are valid for at least 10 years from now +- Minimum Synapse Setup (servername: `synapse.m.localhost`) +- LiveKit Authorization Service (Note requires Federation API and hence a TLS reverse proxy) - Minimum LiveKit SFU Setup using dev defaults for config - Redis db for completeness +- Minimum `localhost` Certificate Authority (CA) for Transport Layer Security (TLS) + - Hostnames: `m.localhost`, `*.m.localhost` + - Add [./backend/dev_tls_local-ca.crt](./backend/dev_tls_local-ca.crt) to your web browsers trusted + certificates +- Minimum TLS reverse proxy for + - Synapse homeserver: `synapse.m.localhost` + - MatrixRTC backend: `matrix-rtc.m.localhost` + - Local Element Call development `call.m.localhost` via `yarn dev --host ` + - Element Web `app.m.localhost` + - Note certificates will expire on Thu, 03 May 2035 10:32:02 GMT These use a test 'secret' published in this repository, so this must be used only for local development and **_never be exposed to the public Internet._** @@ -230,6 +233,16 @@ yarn backend # podman-compose -f dev-backend-docker-compose.yml up ``` +> [!NOTE] +> To ensure your local development frontend functions properly, you’ll need to +> add certificate exceptions in your browser for `https://localhost:3000`, +> `https://matrix-rtc.m.localhost/livekit/jwt/healthz` and +> `https://synapse.m.localhost/.well-known/matrix/client`. This can be either +> done by adding the minimum localhost CA +> ([./backend/dev_tls_local-ca.crt](./backend/dev_tls_local-ca.crt)) to your web +> browsers trusted certificates or by simply copying and pasting each URL into +> your browser’s address bar and follow the prompts to add the exception. + ### Playwright tests Our Playwright tests run automatically as part of our CI along with our other diff --git a/backend/dev_homeserver.yaml b/backend/dev_homeserver.yaml index 5697c32e..eab4e698 100644 --- a/backend/dev_homeserver.yaml +++ b/backend/dev_homeserver.yaml @@ -1,5 +1,5 @@ -server_name: "synapse.localhost" -public_baseurl: http://synapse.localhost:8008/ +server_name: "synapse.m.localhost" +public_baseurl: https://synapse.m.localhost/ pid_file: /data/homeserver.pid diff --git a/backend/dev_nginx.conf b/backend/dev_nginx.conf new file mode 100644 index 00000000..44fef8a5 --- /dev/null +++ b/backend/dev_nginx.conf @@ -0,0 +1,155 @@ +# Synapse reverse proxy including .well-known/matrix/client +server { + listen 80; + listen [::]:80; + listen 443 ssl; + listen 8448 ssl; + listen [::]:443 ssl; + listen [::]:8448 ssl; + server_name synapse.m.localhost; + ssl_certificate /root/ssl/cert.pem; + ssl_certificate_key /root/ssl/key.pem; + + # well-known config adding rtc_foci backend + # Note well-known is currently not effective due to: + # https://spec.matrix.org/v1.12/client-server-api/#well-known-uri the spec + # says it must be at https://$server_name/... (implied port 443) Hence, we + # currently rely for local development environment on deprecated config.json + # setting for livekit_service_url + location /.well-known/matrix/client { + add_header Access-Control-Allow-Origin *; + return 200 '{"m.homeserver": {"base_url": "https://synapse.m.localhost"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://matrix-rtc.m.localhost/livekit/jwt"}]}'; + default_type application/json; + } + + # Reverse proxy for Matrix Synapse Homeserver + # This is also required for development environment. + # Reason: the lk-jwt-service uses the federation API for the openid token + # verification, which requires TLS + location / { + proxy_pass "http://homeserver:8008"; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + } + + error_page 500 502 503 504 /50x.html; + +} + +# MatrixRTC reverse proxy +# - MatrixRTC Authorization Service +# - LiveKit SFU websocket signaling connection +server { + listen 80; + listen [::]:80; + listen 443 ssl; + listen [::]:443 ssl; + listen 8448 ssl; + listen [::]:8448 ssl; + server_name matrix-rtc.m.localhost; + ssl_certificate /root/ssl/cert.pem; + ssl_certificate_key /root/ssl/key.pem; + + + location ^~ /livekit/jwt/ { + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # JWT Service running at port 8080 + proxy_pass http://auth-server:8080/; + } + + location ^~ /livekit/sfu/ { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_send_timeout 120; + proxy_read_timeout 120; + proxy_buffering off; + + proxy_set_header Accept-Encoding gzip; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # LiveKit SFU websocket connection running at port 7880 + proxy_pass http://livekit-sfu:7880/; + } + + error_page 500 502 503 504 /50x.html; + +} + +# Convenience reverse proxy for the call.m.localhost domain to yarn dev --host +server { + listen 80; + listen [::]:80; + server_name call.m.localhost; + + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name call.m.localhost; + ssl_certificate /root/ssl/cert.pem; + ssl_certificate_key /root/ssl/key.pem; + + + location ^~ / { + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_pass https://host.docker.internal:3000; + proxy_ssl_verify off; + + } + + error_page 500 502 503 504 /50x.html; + +} + +# Convenience reverse proxy app.m.localhost for element web +server { + listen 80; + listen [::]:80; + server_name app.m.localhost; + + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name app.m.localhost; + ssl_certificate /root/ssl/cert.pem; + ssl_certificate_key /root/ssl/key.pem; + + + location ^~ / { + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_pass http://element-web:8081; + proxy_ssl_verify off; + + } + + error_page 500 502 503 504 /50x.html; + +} diff --git a/backend/dev_tls_local-ca.crt b/backend/dev_tls_local-ca.crt new file mode 100644 index 00000000..9c8ee3d7 --- /dev/null +++ b/backend/dev_tls_local-ca.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDGjCCAgKgAwIBAgIUGdiFHhH4KL2pqBjMQHQ+PVIkSV8wDQYJKoZIhvcNAQEL +BQAwHjEcMBoGA1UEAwwTRWxlbWVudCBDYWxsIERldiBDQTAeFw0yNTA1MDUxMDMy +MDJaFw0zNTA1MDMxMDMyMDJaMB4xHDAaBgNVBAMME0VsZW1lbnQgQ2FsbCBEZXYg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA2y0hjmNn1vRsVSdy +8IOfo8N1q9UgkhQWpGKXzPh+D5d1fnuJEmHIVwtDEtS/PwQ43LTmegChPtKH9jdT +tG0IihW9Ja5YNG+9xAwaoA/sB3CGCBYsz+2/XjVUpXoBJXIPoFBWsn+K0oeFw9fw +eRO1z9abM4cl+LjKzMNM8CCyu9uI1MaGjYez2YIWvG854VucLxX7HSlMJxZNWnie +Ui7fMakuJhB2+aiIQjdKxy4E5RHNhzYG/LXhvP+wBYBDPNRsP3rtzEaE9HAveL9K +FGqd3R4cBia6r1WIXmpAzyu5RGP5Eou0TZlGkal96/bF0I7q/pKlL23Jt1BLPiQU +KGKrAgMBAAGjUDBOMB0GA1UdDgQWBBQJqBjMu61c1p24txw/y+kv3D+V6DAfBgNV +HSMEGDAWgBQJqBjMu61c1p24txw/y+kv3D+V6DAMBgNVHRMEBTADAQH/MA0GCSqG +SIb3DQEBCwUAA4IBAQB8m2YfFGLugNt5vAAOvNxVqDA8c72yCVYr3CBCpmTIEY5Z +d3qVGhG9//ux6+J8ntkSwd9nV5GJyYXHukCG1VavnAWolWdNF/WAllf0jhLuz7kD +/cJnuI1By4tBsBmSz851i6HJ4t5k99Be+6GQVzi0e7zzfxTHZE4xP2J6Ox8QbPsP +n0m76nIp/WbWaJqzvIIjJhmUUPPv+4wN+eOArgjiGLzptM2qTtGZtd0c9nS5gvep ++mEbSUN9zkhAroZf80wf+hEvy+fJ94VbZ9QjTzTg7odZLrsXGIe8DaG63EYRQ25b +W5iYBAreln5fGSt7qHsGfqwZibTEk/Lx3dydO1Kg +-----END CERTIFICATE----- diff --git a/backend/dev_tls_local-ca.key b/backend/dev_tls_local-ca.key new file mode 100644 index 00000000..c6de05c4 --- /dev/null +++ b/backend/dev_tls_local-ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDA2y0hjmNn1vRs +VSdy8IOfo8N1q9UgkhQWpGKXzPh+D5d1fnuJEmHIVwtDEtS/PwQ43LTmegChPtKH +9jdTtG0IihW9Ja5YNG+9xAwaoA/sB3CGCBYsz+2/XjVUpXoBJXIPoFBWsn+K0oeF +w9fweRO1z9abM4cl+LjKzMNM8CCyu9uI1MaGjYez2YIWvG854VucLxX7HSlMJxZN +WnieUi7fMakuJhB2+aiIQjdKxy4E5RHNhzYG/LXhvP+wBYBDPNRsP3rtzEaE9HAv +eL9KFGqd3R4cBia6r1WIXmpAzyu5RGP5Eou0TZlGkal96/bF0I7q/pKlL23Jt1BL +PiQUKGKrAgMBAAECggEAAPX2kxi5AQ7ul82SzT1KgpSXyDHLdYaUyAoYnaX9RO+B +8ylmpyeqygs4+KQS4EMJm9jpo85Oy37bIKdG3kljU6wQcKlL5Y+ZUOo1nzpV6fid +hGVs6ts8VXw8KshKQ9AyccZ8L/pirUfgOffgTwfjY7/90zceAL/s98GuZWc62nkX +55joQv/OikqYfAGP/U6Bp2Zyf23DwJB09Z3B6NnZj/ZyAbDrDEHuA15LhCOcCczp +IU/mFEywBPHT9Tg4w4Beq78PeAETvku2UalYRLhP3RLlXr2oEbwUtINRVt2QjZ85 +Esps4uCqL/mgQluIebtudD9HL/YMlNPXue1mDXFxJQKBgQDgZZY4yJBcf488T1V6 +HNm06b/LvVGj253pKgw14hpY1xQu3Ymgzv1GEqzhSYdzxhpmj0tMUNHxAp+YdGQu +SZ0wcPKhw0aYVkIjDRYDC3Wn5GJhyIEYHGYMo/n4l49UzHRBPOTDzp49DkHTKBgh +XgIIazYT3CkjTIMRrkUv+qfIPQKBgQDcBGu/mqbjxs4sN3zqPS4aB21o6t6W0sXs +ZP9w6RlTPQi5U2oRbftjZtYc0bbEgkMUImB1HwYPQT5pJ+MyC414xDvSc2exBr5d +To6yyPIy78Tf5PHM12fpKV92nSvoz/pSjYcGxxDtKfPqu+t8mOJfjCV1lLLA+xuB +DDaE4p8dBwKBgQCdAne6A5v/HMH8UQZeCxHJpESvKiiVnnU/UEx651nID7XvlNNX +0X0mKqsMd4ZvW43ddSYan/JF0LAa3FW8jYWO/3jF9vzOWoysOdvNBZetgf/Uq5ao +aDZ/YbzmVCXWD7jIbPMkjs3pqrAkL0mzDzQc7+dGviWKrV6IYIfIqnn7gQKBgDCz +vdIk/qpO+JZrFfiX4Fucp0hhLTJ/p5ZDaRPqVVPKn+K+Jy2ChfIj8mNgvK9VEloj +nexvGJ1J2PHYBX+vdPp1nbRhHWPfVUY8PHQw7QP/dToGaMvqJrNDGEGeWvjnCMc7 +UtdaO1H0Rm0AegkTopB56lTTvJnhO95eALd7nrMDAoGAEPdzJtWoKafp49svhSj0 +hiXQv2SPBwVUN4LZ4SOWiXUcmYYm80aNpYKLkBxYjrfqFWhE7NUHLGp8YorQWKY2 +acD9AReHk/xku0ABy6jeYmSCmCxASxst5liKD+l12sk0gB0rk5MBxB4Uu1MIbQZ2 +aCASX3AVD2/XyC2MKkzc8Eg= +-----END PRIVATE KEY----- diff --git a/backend/dev_tls_m.localhost.crt b/backend/dev_tls_m.localhost.crt new file mode 100644 index 00000000..5d6251a9 --- /dev/null +++ b/backend/dev_tls_m.localhost.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIUXizLjwkdqepX0bh0K3abeJxj68IwDQYJKoZIhvcNAQEL +BQAwHjEcMBoGA1UEAwwTRWxlbWVudCBDYWxsIERldiBDQTAeFw0yNTA1MDUxMzU5 +MTFaFw0zNTA1MDMxMzU5MTFaMBgxFjAUBgNVBAMMDSoubS5sb2NhbGhvc3QwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrzGSScSgaQuZdELGFYiLiYRwr +LKyUdNr0rsPcOo0bvbeZ3zQMeUMRNlA69zGFdarumiDRXUoAmZI39WmH95aX3d+A +U7EFnWev7xpWSVhSYj8T0d4rke8HjGk3LpaffJ93tbJuagBIH1ouuN6AOdzWs8hp +RYIomWleEeeuVnnfaMwaXOdc+ihJJ6wzm2hwQSfdpjZPWBDd/DFft1ZXxIZOCjDs +rEIiI7uU8iZPLB3QEM/tgxSSAOxrcKvQvxZokk+FD7aMJFP71IfieLCEzMTP1VXa +tP7UTAKAqB2NyDJ8m3IHbOINiqcdFvFR3R1D9bXOYE4oRynNvYZrQUGnL2RtAgMB +AAGjgaIwgZ8wHwYDVR0jBBgwFoAUCagYzLutXNaduLccP8vpL9w/legwCQYDVR0T +BAIwADALBgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwMAYDVR0RBCkw +J4IJbG9jYWxob3N0ggttLmxvY2FsaG9zdIINKi5tLmxvY2FsaG9zdDAdBgNVHQ4E +FgQUfdh1p52ZgWyZcBgBXGwKi4EnUE0wDQYJKoZIhvcNAQELBQADggEBAKrHEuB6 +33j8+EwSHw3zrvt/DRXK2BDHI1Ir9JcztSunaKAjZXVvf/dvZp0Xs1dEdJIdnv6G +iZYhBbOqDqpQZbf2h/h0kuu5yZSBUdnQXnYNxlhp2UaC/UEgw5iZT/p1rm7RjVie +y4Dp2WytV5iZOLmLj6xDvd3DXazgJPWIRX8p8qJZbKTkwCjTr7nDIj8jjG1sVFf7 +1RJBO5/6WSnImrpDmlLUrvjiKvbxcdseDJyBOhTwdRdSk4S2M+s5tR5j2I1gXLOq +J5ioN76+SCrTY0K0WKRy9oOXWO1/X3+VYcekp+0F3SGkd5w17jylCv1XIGHAdEsQ +v2z2/aMI/7sAD2Q= +-----END CERTIFICATE----- diff --git a/backend/dev_tls_m.localhost.key b/backend/dev_tls_m.localhost.key new file mode 100644 index 00000000..73d89ce4 --- /dev/null +++ b/backend/dev_tls_m.localhost.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrzGSScSgaQuZd +ELGFYiLiYRwrLKyUdNr0rsPcOo0bvbeZ3zQMeUMRNlA69zGFdarumiDRXUoAmZI3 +9WmH95aX3d+AU7EFnWev7xpWSVhSYj8T0d4rke8HjGk3LpaffJ93tbJuagBIH1ou +uN6AOdzWs8hpRYIomWleEeeuVnnfaMwaXOdc+ihJJ6wzm2hwQSfdpjZPWBDd/DFf +t1ZXxIZOCjDsrEIiI7uU8iZPLB3QEM/tgxSSAOxrcKvQvxZokk+FD7aMJFP71Ifi +eLCEzMTP1VXatP7UTAKAqB2NyDJ8m3IHbOINiqcdFvFR3R1D9bXOYE4oRynNvYZr +QUGnL2RtAgMBAAECggEAJaFQii8U/KOYt9vXNoMnZvSkaeSQLLhn2V6Kciu1CtWE +aMTWLsFE6nk+G5xXkYcTmM3T0GghtH3u5CjyI6EcsEkeEorCZJt0wbmayDmqiekR +LfMzOdHuTHX5+edPgMGYYG1BFyRKyYFsjH1b5zRFZhXdGQnrl5760GsVlz9D1KZQ +iHcT+q1S2tmZeoUukQnADENKXUMCyTGM5FCddgNtsWnGDsTDayh7hUdvDkB+mW4G +lSp+BZuc3PCwpbD6qkXvfugWs6CUAAtXoV3ceWgxQ+TEnNlwxaG1AyugfgNUBolk +8xgeZt4r5QId03jsHDf7hpBAofcaCd5EMIIQYFvWoQKBgQDlbAvAzEFPTZZn2nRV +Xagw4xjqVc1LLEKLCWq0N5rEkwn0h90Dz5N7/3NuonP/sIDsDHCbyiOYBI1Ck6Xi +0WuB+OyKDh+xeF2mekN9G9ywPahdK5lT/TVsxXFyZlwtVv1x/6KBO4yv5URizxqU +gyAPDDxfD/KcNjkOBaodWEwQGQKBgQC/s2gPDBtQkjLwkHXchBomLww5eLlVrac1 +WK4UX6uSdOgrjJ375OOgMTxe8NVZdOuAKytGXRWDwgH3nVWvuZhe7dGlX3JMuSer +e9VwDpBESrvqcR4ruL6wm8wej6BXyjH0wD3FHb0S5HfuBDxTn+4bDwrbRzOUMNgy +lSppuflxdQKBgQDiZcIfazFT8evn5nMAvuC4BZNTxIJHmZC9JfjPiUPIkpWzYtOe +7BvNtKOT3Op9uw8uYYRKqKqBXJSNy6ha8XCXHS9HeXKbLn20SFkLQBCDNwVLlDfF +40zyXtF6JDr4XyzSb4NM5pgKCER5AYloXxGm59s3sEQpFXUuOjbKqJS/GQKBgAoI +c7vF4HAZFr1sch62cz/oWnVvkhOf4Q5zs7ixQSOLJtOQqnwSgK9TpFs7s47ZBbJR +kBRAru2Ua9Hv1Bo8VnMxczV6h1roneDlvEf/GyHX33nnrbKQGrrXjJlU3wl5NaAf +p5v3cHvapUQ5yIZ/6lBUOzc6xMJOxCHxmKSr7Rg5AoGAbEE4lt6Xh2dnBPJ81eNI +IDrw/3ITY53qAY4Bx88CByIFuu8CEUdUZprh98jSl6ic1tMinZfUhRMwABLrUD51 +DGst8iGLPD9u83iMcUHI/L+p7AbxrKLvWXZrF5UZm440c9mSWqfhPaTBosPtNDsG +LfETwH1flKXMTXd2xA9RTE4= +-----END PRIVATE KEY----- diff --git a/backend/dev_tls_setup b/backend/dev_tls_setup new file mode 100644 index 00000000..8a778dc8 --- /dev/null +++ b/backend/dev_tls_setup @@ -0,0 +1,38 @@ +#!/bin/bash + +# Step 1: Create a Root CA key and cert +openssl genrsa -out dev_tls_local-ca.key 2048 +openssl req -x509 -new -nodes \ + -days 3650 \ + -subj "/CN=Element Call Dev CA" \ + -key dev_tls_local-ca.key \ + -out dev_tls_local-ca.crt \ + -sha256 -addext "basicConstraints=CA:TRUE" + +# Step 2: Create a private key and CSR for *.m.localhost +openssl req -new -nodes -newkey rsa:2048 \ + -keyout dev_tls_m.localhost.key \ + -out dev_tls_m.localhost.csr \ + -subj "/CN=*.m.localhost" + +# Step 3: Sign the CSR with your CA +openssl x509 \ + -req -in dev_tls_m.localhost.csr \ + -CA dev_tls_local-ca.crt -CAkey dev_tls_local-ca.key \ + -CAcreateserial \ + -out dev_tls_m.localhost.crt \ + -days 3650 \ + -sha256 \ + -extfile <( cat < void) | undefined` Callback called whenever the user or application selects a new audio output. +- `controls.setAudioDevice(id: string): void` Sets the selected audio device in Element Call's menu. This should be used if the OS decides to automatically switch to Bluetooth, for example. +- `controls.setAudioEnabled(enabled: boolean)` Enables/disables all audio output from the application. Output is enabled by default. +- `showNativeAudioDevicePicker: (() => void) | undefined`. Callback called whenever the user presses the output button in the settings menu. + This button is only shown on iOS. (`userAgent.includes("iPhone")`) diff --git a/docs/self-hosting.md b/docs/self-hosting.md index 7a515930..85ace615 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -63,6 +63,11 @@ rc_delayed_event_mgmt: burst_count: 20 ``` +As a prerequisite for the +[Matrix LiveKit JWT auth service](https://github.com/element-hq/lk-jwt-service) +make sure that your Synapse server has either a `federation` or `openid` +[listener configured](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#listeners). + ### MatrixRTC Backend In order to **guarantee smooth operation** of Element Call MatrixRTC backend is @@ -88,7 +93,7 @@ the example above, this results in: Using Nginx, you can achieve this by: -```jsonc +```nginx configuration file server { ... location ^~ /livekit/jwt/ { @@ -198,7 +203,7 @@ Because Element Call uses client-side routing, your server must be able to route any requests to non-existing paths back to `/index.html`. For example, in Nginx you can achieve this with the `try_files` directive: -```jsonc +```nginx configuration file server { ... location / { diff --git a/docs/url-params.md b/docs/url-params.md index c533937b..27f8f579 100644 --- a/docs/url-params.md +++ b/docs/url-params.md @@ -63,6 +63,7 @@ These parameters are relevant to both [widget](./embedded-standalone.md) and [st | `lang` | [BCP 47](https://www.rfc-editor.org/info/bcp47) code | No | No | The language the app should use. | | `password` | | No | No | E2EE password when using a shared secret. (For individual sender keys in embedded mode this is not required.) | | `perParticipantE2EE` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Enables per participant encryption with Keys exchanged over encrypted matrix room messages. | +| `controlledAudioDevices` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Whether the [global JS controls for audio devices](./controls.md#audio-devices) should be enabled, allowing the list of audio devices to be controlled by the app hosting Element Call. | | `roomId` | [Matrix Room ID](https://spec.matrix.org/v1.12/appendices/#room-ids) | Yes | No | Anything about what room we're pointed to should be from useRoomIdentifier which parses the path and resolves alias with respect to the default server name, however roomId is an exception as we need the room ID in embedded widget mode, and not the room alias (or even the via params because we are not trying to join it). This is also not validated, where it is in `useRoomIdentifier()`. | | `showControls` | `true` or `false` | No, defaults to `true` | No, defaults to `true` | Displays controls like mute, screen-share, invite, and hangup buttons during a call. | | `skipLobby` (deprecated: use `intent` instead) | `true` or `false` | No. If `intent` is explicitly `start_call` then defaults to `true`. Otherwise defaults to `false` | No, defaults to `false` | Skips the lobby to join a call directly, can be combined with preload in widget. When `true` the audio and video inputs will be muted by default. (This means there currently is no way to start without muted video if one wants to skip the lobby. Also not in widget mode.) | diff --git a/embedded/android/gradle/libs.versions.toml b/embedded/android/gradle/libs.versions.toml index 8d38daab..2d9bfa40 100644 --- a/embedded/android/gradle/libs.versions.toml +++ b/embedded/android/gradle/libs.versions.toml @@ -2,11 +2,11 @@ # https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format [versions] -android_gradle_plugin = "8.8.0" +android_gradle_plugin = "8.10.0" [libraries] android_gradle_plugin = { module = "com.android.tools.build:gradle", version.ref = "android_gradle_plugin" } [plugins] android_library = { id = "com.android.library", version.ref = "android_gradle_plugin" } -maven_publish = { id = "com.vanniktech.maven.publish", version = "0.30.0" } \ No newline at end of file +maven_publish = { id = "com.vanniktech.maven.publish", version = "0.31.0" } \ No newline at end of file diff --git a/embedded/android/gradle/wrapper/gradle-wrapper.jar b/embedded/android/gradle/wrapper/gradle-wrapper.jar index d64cd491..1b33c55b 100644 Binary files a/embedded/android/gradle/wrapper/gradle-wrapper.jar and b/embedded/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/embedded/android/gradle/wrapper/gradle-wrapper.properties b/embedded/android/gradle/wrapper/gradle-wrapper.properties index 79eb9d00..6514f919 100644 --- a/embedded/android/gradle/wrapper/gradle-wrapper.properties +++ b/embedded/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/embedded/android/gradlew b/embedded/android/gradlew index f5feea6d..23d15a93 100755 --- a/embedded/android/gradlew +++ b/embedded/android/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -206,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -214,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/embedded/android/gradlew.bat b/embedded/android/gradlew.bat index 9d21a218..db3a6ac2 100644 --- a/embedded/android/gradlew.bat +++ b/embedded/android/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/knip.ts b/knip.ts index 05bd029d..2381356c 100644 --- a/knip.ts +++ b/knip.ts @@ -27,6 +27,10 @@ export default { // then Knip will flag it as a false positive // https://github.com/webpro-nl/knip/issues/766 "@vector-im/compound-web", + // We need this so that TypeScript is happy with @livekit/track-processors. + // This might be a bug in the LiveKit repo but for now we fix it on the + // Element Call side. + "@types/dom-mediacapture-transform", "matrix-widget-api", ], ignoreExportsUsedInFile: true, diff --git a/locales/cs/app.json b/locales/cs/app.json index a63a6de8..81f1ef9a 100644 --- a/locales/cs/app.json +++ b/locales/cs/app.json @@ -70,10 +70,12 @@ "livekit_server_info": "Informace o serveru LiveKit", "livekit_sfu": "LiveKit SFU: {{url}}", "matrix_id": "Matrix ID: {{id}}", + "mute_all_audio": "Ztlumit všechny zvuky (účastníci, reakce, zvuky připojení)", "show_connection_stats": "Zobrazit statistiky připojení", "show_non_member_tiles": "Zobrazit dlaždice pro nečlenská média", "url_params": "Parametry URL", - "use_new_membership_manager": "Použijte novou implementaci volání MembershipManager" + "use_new_membership_manager": "Použijte novou implementaci volání MembershipManager", + "use_to_device_key_transport": "Použít přenos klíčů do zařízení. Tím se vrátíte k přenosu klíčů do místnosti, když jiný účastník hovoru pošle klíč místnosti" }, "disconnected_banner": "Připojení k serveru bylo ztraceno.", "error": { @@ -164,6 +166,9 @@ "effect_volume_description": "Upravit hlasitost přehrávání reakcí a efektů zvednutých rukou.", "effect_volume_label": "Hlasitost zvukového efektu" }, + "background_blur_header": "Pozadí", + "background_blur_label": "Rozostřit pozadí videa", + "blur_not_supported_by_browser": "(Toto zařízení nepodporuje rozostření pozadí.)", "developer_tab_title": "Vývojář", "devices": { "camera": "Fotoaparát", diff --git a/locales/da/app.json b/locales/da/app.json new file mode 100644 index 00000000..4461e467 --- /dev/null +++ b/locales/da/app.json @@ -0,0 +1,221 @@ +{ + "a11y": { + "user_menu": "Brugermenu" + }, + "action": { + "close": "Luk", + "copy_link": "Kopiér link", + "edit": "Rediger", + "go": "Gå", + "invite": "Invitér", + "lower_hand": "Sænk hånd", + "no": "Nej", + "pick_reaction": "Vælg reaktion", + "raise_hand": "Ræk hånden op", + "register": "Registrér", + "remove": "Fjern", + "show_less": "Vis mindre", + "show_more": "Vis mere", + "sign_in": "Log ind", + "sign_out": "Log ud", + "submit": "Indsend", + "upload_file": "Upload fil" + }, + "analytics_notice": "Ved at deltage i denne beta giver du samtykke til indsamling af anonyme data, som vi bruger til at forbedre produktet. Du kan finde flere oplysninger om, hvilke data vi sporer, i vores <2>fortrolighedspolitik og vores <6>cookiepolitik.", + "app_selection_modal": { + "continue_in_browser": "Fortsæt i browseren", + "open_in_app": "Åbn i appen", + "text": "Klar til at deltage?", + "title": "Vælg app" + }, + "call_ended_view": { + "create_account_button": "Opret konto", + "create_account_prompt": "<0>Hvorfor ikke afslutte med at oprette en adgangskode for at beholde din konto? <1>Du kan beholde dit navn og indstille en avatar til brug ved fremtidige opkald ", + "feedback_done": "<0>Tak for din feedback! ", + "feedback_prompt": "<0>Vi vil meget gerne høre din feedback, så vi kan forbedre din oplevelse.", + "headline": "{{displayName}}, dit opkald er afsluttet.", + "not_now_button": "Ikke nu, vend tilbage til startskærmen", + "reconnect_button": "Tilslut igen", + "survey_prompt": "Hvordan gik det?" + }, + "call_name": "Navn på opkald", + "common": { + "analytics": "Analyse-værktøj", + "audio": "Lyd", + "avatar": "Avatar", + "back": "Tilbage", + "display_name": "Vist navn", + "encrypted": "Krypteret", + "home": "Hjem", + "loading": "Indlæser...", + "next": "Næste", + "options": "Valgmuligheder", + "password": "Adgangskode", + "preferences": "Foretrukne", + "profile": "Profil", + "reaction": "Reaktion", + "reactions": "Reaktioner", + "settings": "Indstillinger", + "unencrypted": "Ikke krypteret", + "username": "Brugernavn", + "video": "Video" + }, + "developer_mode": { + "crypto_version": "Krypto-version: {{version}}", + "debug_tile_layout_label": "Fejlfinding af fliselayout", + "device_id": "Enheds-id: {{id}}", + "duplicate_tiles_label": "Antal ekstra flisekopier pr. deltager", + "environment_variables": "Miljøvariabler", + "hostname": "Værtsnavn: {{hostname}}", + "livekit_server_info": "LiveKit Serverinfo", + "livekit_sfu": "LiveKit SFU: {{url}}", + "matrix_id": "Matrix ID: {{id}}", + "show_connection_stats": "Vis forbindelsesstatistik", + "show_non_member_tiles": "Vis fliser for medier fra ikke-medlemmer", + "url_params": "URL-parametre", + "use_new_membership_manager": "Brug den nye implementering af opkaldet MembershipManager", + "use_to_device_key_transport": "Bruges til at transportere enhedsnøgler. Dette vil falde tilbage til transport af værelsesnøgler, når et andet opkaldsmedlem sender en rumnøgle" + }, + "disconnected_banner": "Forbindelsen til serveren er gået tabt.", + "error": { + "call_is_not_supported": "Opkald er ikke understøttet", + "call_not_found": "Opkald ikke fundet", + "call_not_found_description": "<0>Det link ser ikke ud til at høre til et eksisterende opkald. Tjek at du har det rigtige link, eller<1> opret et nyt.", + "connection_lost": "Forbindelsen gik tabt", + "connection_lost_description": "Du blev afbrudt fra opkaldet.", + "e2ee_unsupported": "Inkompatibel browser", + "e2ee_unsupported_description": "Din webbrowser understøtter ikke krypterede opkald. Understøttede browsere inkluderer Chrome, Safari og Firefox 117+.", + "generic": "Noget gik galt", + "generic_description": "Indsendelse af fejlfindingslogfiler hjælper os med at spore problemet.", + "insufficient_capacity": "Utilstrækkelig kapacitet", + "insufficient_capacity_description": "Serveren har nået sin maksimale kapacitet, og du kan ikke deltage i opkaldet på dette tidspunkt. Prøv igen senere, eller kontakt din serveradministrator, hvis problemet fortsætter.", + "matrix_rtc_focus_missing": "Serveren er ikke konfigureret til at arbejde med {{brand}}{{domain}}. Kontakt venligst din serveradministrator (domæne:{{domain}}, fejlkode: {{ errorCode }}).", + "open_elsewhere": "Åbnet i en anden fane", + "open_elsewhere_description": "{{brand}} er blevet åbnet i en anden fane. Hvis det ikke lyder rigtigt, kan du prøve at genindlæse siden.", + "unexpected_ec_error": "Der opstod en uventet fejl (<0>Fejlkode: <1> {{ errorCode }}). Kontakt venligst din serveradministrator." + }, + "group_call_loader": { + "banned_body": "Du er blevet spærret fra rummet.", + "banned_heading": "Spærret", + "call_ended_body": "Du er blevet fjernet fra opkaldet.", + "call_ended_heading": "Opkaldet afsluttet", + "knock_reject_body": "Din anmodning om at deltage blev afvist.", + "knock_reject_heading": "Adgang nægtet", + "reason": "Årsag: {{reason}}" + }, + "hangup_button_label": "Afslut opkald", + "header_label": "Element Ring hjem", + "header_participants_label": "Deltagere", + "invite_modal": { + "link_copied_toast": "Link kopieret til udklipsholder", + "title": "Inviter til dette opkald" + }, + "join_existing_call_modal": { + "join_button": "Ja, deltag i opkald", + "text": "Dette opkald findes allerede, vil du være med?", + "title": "Deltag i eksisterende opkald?" + }, + "layout_grid_label": "Gitter", + "layout_spotlight_label": "Spotlys", + "lobby": { + "ask_to_join": "Anmod om at deltage i opkaldet", + "join_as_guest": "Deltag som gæst", + "join_button": "Deltag i opkald", + "leave_button": "Tilbage til seneste", + "waiting_for_invite": "Anmodning sendt! Venter på tilladelse til at deltage..." + }, + "log_in": "Log ind", + "logging_in": "Logger ind...", + "login_auth_links": "<0>Opret en konto eller <2> få adgang som gæst ", + "login_auth_links_prompt": "Ikke registreret endnu?", + "login_subheading": "For at fortsætte til Element", + "login_title": "Login", + "microphone_off": "Mikrofon slukket", + "microphone_on": "Mikrofon tændt", + "mute_microphone_button_label": "Slå mikrofonen fra", + "participant_count_one": "{{count, number}}", + "participant_count_other": "{{count, number}}", + "qr_code": "QR-kode", + "rageshake_button_error_caption": "Prøv at sende logfiler igen", + "rageshake_request_modal": { + "body": "En anden bruger på dette opkald har et problem. For bedre at kunne diagnosticere sådanne problemer, vil vi gerne indsamle en fejlfindingslog.", + "title": "Anmodning om fejlfindingslogfil" + }, + "rageshake_send_logs": "Send fejlfindingslogfiler", + "rageshake_sending": "Sender...", + "rageshake_sending_logs": "Afsendelse af fejlfindingslogfiler...", + "rageshake_sent": "Tak!", + "recaptcha_dismissed": "Recaptcha afvist", + "recaptcha_not_loaded": "Recaptcha ikke indlæst", + "recaptcha_ssla_caption": "Dette websted er beskyttet af ReCAPTCHA og Googles <2>Privatlivspolitik og <6>Servicevilkår gælder.<9>Ved at klikke på \"Registrer\" accepterer du vores <12>Software og Services Licensaftale (SSLA)", + "register": { + "passwords_must_match": "Adgangskoderne skal være identiske", + "registering": "Registrering..." + }, + "register_auth_links": "<0>Har du allerede en konto? <1><0>Log ind eller <2> få adgang som gæst ", + "register_confirm_password_label": "Bekræft adgangskode", + "register_heading": "Opret din konto", + "return_home_button": "Vend tilbage til startskærmen", + "room_auth_view_continue_button": "Fortsæt", + "room_auth_view_ssla_caption": "Ved at klikke på „Deltag i opkald nu“ accepterer du vores <2> Software og Services Licensaftale (SSLA) ", + "screenshare_button_label": "Del din skærm", + "settings": { + "audio_tab": { + "effect_volume_description": "Juster den lydstyrke som reaktioner og håndsoprækninger afspilles med.", + "effect_volume_label": "Lydstyrke for lydeffekter" + }, + "developer_tab_title": "Udvikler", + "devices": { + "camera": "Kamera", + "camera_numbered": "Kamera {{n}}", + "default": "Standard", + "default_named": "Standard <2>({{name}})", + "microphone": "Mikrofon", + "microphone_numbered": "Mikrofon {{n}}", + "speaker": "Højttaler", + "speaker_numbered": "Højttaler {{n}}" + }, + "feedback_tab_body": "Hvis du oplever problemer eller bare gerne vil give feedback, kan du sende os en kort beskrivelse herunder.", + "feedback_tab_description_label": "Din tilbagemelding", + "feedback_tab_h4": "Indsend feedback", + "feedback_tab_send_logs_label": "Medtag fejlfindingslogfiler", + "feedback_tab_thank_you": "Tak, vi har modtaget din feedback!", + "feedback_tab_title": "Feedback", + "opt_in_description": "<0><1>Du kan trække dit samtykke tilbage ved at fjerne markeringen i dette felt. Hvis du i øjeblikket er i gang med et opkald, træder denne indstilling i kraft ved afslutningen af opkaldet.", + "preferences_tab": { + "developer_mode_label": "Udviklertilstand", + "developer_mode_label_description": "Aktivér udviklertilstand og vis fanen udviklerindstillinger.", + "introduction": "Her kan du konfigurere ekstra muligheder for en forbedret oplevelse.", + "reactions_play_sound_description": "Afspil en lydeffekt, når nogen sender en reaktion i et opkald.", + "reactions_play_sound_label": "Afspil reaktionslyde", + "reactions_show_description": "Vis en animation, når nogen sender en reaktion.", + "reactions_show_label": "Vis reaktioner", + "show_hand_raised_timer_description": "Vis en timer, når en deltager rækker hånden", + "show_hand_raised_timer_label": "Vis varighed af håndsoprækning" + } + }, + "star_rating_input_label_one": "{{count}} stjerne", + "star_rating_input_label_other": "{{count}} stjerner", + "start_new_call": "Start nyt opkald", + "start_video_button_label": "Start video", + "stop_screenshare_button_label": "Skærmen bliver delt", + "stop_video_button_label": "Stop video", + "submitting": "Indsender...", + "switch_camera": "Skift kamera", + "unauthenticated_view_body": "Ikke registreret endnu? <2>Opret en konto ", + "unauthenticated_view_login_button": "Log ind på din konto", + "unauthenticated_view_ssla_caption": "Ved at klikke på \"Start\" accepterer du vores <2>Software og Services Licensaftale (SSLA)", + "unmute_microphone_button_label": "Slå mikrofonen til", + "version": "{{productName}} version: {{version}}", + "video_tile": { + "always_show": "Vis altid", + "camera_starting": "Indlæser video", + "change_fit_contain": "Tilpas til rammen", + "collapse": "Fold sammen", + "expand": "Udvid", + "mute_for_me": "Slå lyden fra for mig", + "muted_for_me": "Dæmpet for mig", + "volume": "Lydstyrke", + "waiting_for_media": "Venter på medier..." + } +} diff --git a/locales/de/app.json b/locales/de/app.json index 6dccde05..67aab44c 100644 --- a/locales/de/app.json +++ b/locales/de/app.json @@ -61,6 +61,7 @@ "video": "Video" }, "developer_mode": { + "always_show_iphone_earpiece": "iPhone-Ohrhörer-Option auf allen Plattformen anzeigen", "crypto_version": "Krypto-Version: {{version}}", "debug_tile_layout_label": "Kachel-Layout debuggen", "device_id": "Geräte-ID: {{id}}", @@ -70,10 +71,12 @@ "livekit_server_info": "LiveKit-Server Informationen", "livekit_sfu": "LiveKit SFU: {{url}}", "matrix_id": "Matrix-ID: {{id}}", + "mute_all_audio": "Stummschalten aller Audiosignale (Teilnehmer, Reaktionen, Beitrittsgeräusche)", "show_connection_stats": "Verbindungsstatistiken anzeigen", "show_non_member_tiles": "Kacheln für Nicht-Mitgliedermedien anzeigen", "url_params": "URL-Parameter", - "use_new_membership_manager": "Neuen MembershipManager verwenden" + "use_new_membership_manager": "Neuen MembershipManager verwenden", + "use_to_device_key_transport": "To-Device media E2EE Schlüssel-Transport verwenden. Falls ein anderer Teilnehmer bereits den Raumschlüssel-Transport verwendet, wird automatisch auf Raumschlüssel-Transport zurückgegriffen." }, "disconnected_banner": "Die Verbindung zum Server wurde getrennt.", "error": { @@ -163,12 +166,16 @@ "effect_volume_description": "Lautstärke anpassen, mit der Reaktionen und Handmeldungen abgespielt werden.", "effect_volume_label": "Lautstärke der Soundeffekte" }, + "background_blur_header": "Hintergrund", + "background_blur_label": "Unschärfeeffekt für den Hintergrund aktivieren", + "blur_not_supported_by_browser": "(Hintergrundunschärfe wird von diesem Gerät nicht unterstützt.)", "developer_tab_title": "Entwickler", "devices": { "camera": "Kamera", "camera_numbered": "Kamera {{n}}", "default": "Standard", "default_named": "Standard<2> ({{name}} )", + "earpiece": "Ohrhörer", "microphone": "Mikrofon", "microphone_numbered": "Mikrofon{{n}}", "speaker": "Lautsprecher", diff --git a/locales/el/app.json b/locales/el/app.json index 6068a1ff..6eec5278 100644 --- a/locales/el/app.json +++ b/locales/el/app.json @@ -4,15 +4,30 @@ }, "action": { "close": "Κλείσιμο", + "copy_link": "Αντιγραφή συνδέσμου", + "edit": "Επεξεργασία", "go": "Μετάβαση", + "invite": "Πρόσκληση", + "lower_hand": "Κατεβάστε το χέρι", "no": "Όχι", + "pick_reaction": "Επιλέξτε αντίδραση", + "raise_hand": "Σηκώστε το χέρι", "register": "Εγγραφή", "remove": "Αφαίρεση", + "show_less": "Εμφάνιση λιγότερων", + "show_more": "Εμφάνιση περισσότερων", "sign_in": "Σύνδεση", "sign_out": "Αποσύνδεση", - "submit": "Υποβολή" + "submit": "Υποβολή", + "upload_file": "Μεταφόρτωση αρχείου" + }, + "analytics_notice": "Συμμετέχοντας σε αυτή τη δοκιμαστική έκδοση, συναινείτε στη συλλογή ανώνυμων δεδομένων, τα οποία χρησιμοποιούμε για τη βελτίωση του προϊόντος. Μπορείτε να βρείτε περισσότερες πληροφορίες σχετικά με το ποια δεδομένα καταγράφουμε στην <2>Πολιτική απορρήτου και στην <6>Πολιτική cookies.", + "app_selection_modal": { + "continue_in_browser": "Συνέχεια στο πρόγραμμα περιήγησης", + "open_in_app": "Ανοίξτε στην εφαρμογή", + "text": "Έτοιμοι να συμμετάσχετε?", + "title": "Επιλέξτε εφαρμογή" }, - "analytics_notice": "Συμμετέχοντας σε αυτή τη δοκιμαστική έκδοση, συναινείτε στη συλλογή ανώνυμων δεδομένων, τα οποία χρησιμοποιούμε για τη βελτίωση του προϊόντος. Μπορείτε να βρείτε περισσότερες πληροφορίες σχετικά με το ποια δεδομένα καταγράφουμε στην <2>Πολιτική απορρήτου και στην <5>Πολιτική cookies.", "call_ended_view": { "create_account_button": "Δημιουργία λογαριασμού", "create_account_prompt": "<0>Γιατί να μην ολοκληρώσετε με τη δημιουργία ενός κωδικού πρόσβασης για τη διατήρηση του λογαριασμού σας;<1>Θα μπορείτε να διατηρήσετε το όνομά σας και να ορίσετε ένα avatar για χρήση σε μελλοντικές κλήσεις.", @@ -20,19 +35,45 @@ "feedback_prompt": "<0>Θα θέλαμε να ακούσουμε τα σχόλιά σας ώστε να βελτιώσουμε την εμπειρία σας.", "headline": "{{displayName}}, η κλήση σας τερματίστηκε.", "not_now_button": "Όχι τώρα, επιστροφή στην αρχική οθόνη", + "reconnect_button": "Επανασύνδεση", "survey_prompt": "Πώς σας φάνηκε;" }, + "call_name": "Όνομα κλήσης", "common": { + "analytics": "Δεδομένα ανάλυσης", "audio": "Ήχος", + "avatar": "Εικόνα Προφίλ", + "back": "Πίσω", "display_name": "Εμφανιζόμενο όνομα", + "encrypted": "Κρυπτογραφημένο", "home": "Αρχική", "loading": "Φόρτωση…", + "next": "Επόμενο", + "options": "Επιλογές", "password": "Κωδικός", + "preferences": "Προτιμήσεις", "profile": "Προφίλ", + "reaction": "Αντίδραση", + "reactions": "Αντιδράσεις", "settings": "Ρυθμίσεις", + "unencrypted": "Μη κρυπτογραφημένο", "username": "Όνομα χρήστη", "video": "Βίντεο" }, + "developer_mode": { + "crypto_version": "Έκδοση κρυπτογράφησης: {{version}}", + "debug_tile_layout_label": "Διάταξη πλακιδίων εντοπισμού σφαλμάτων", + "device_id": "Αναγνωριστικό συσκευής: {{id}}", + "duplicate_tiles_label": "Αριθμός επιπλέον αντιγράφων πλακιδίων ανά συμμετέχοντα", + "environment_variables": "Μεταβλητές περιβάλλοντος", + "hostname": "Όνομα κεντρικού υπολογιστή: {{hostname}}", + "livekit_server_info": "Πληροφορίες διακομιστή LiveKit", + "livekit_sfu": "LiveKit SFU: {{url}}", + "matrix_id": "Αναγνωριστικό Matrix: {{id}}", + "show_connection_stats": "Εμφάνιση στατιστικών σύνδεσης", + "show_non_member_tiles": "Εμφάνιση πλακιδίων για μέσα μη-μελών", + "url_params": "Παράμετροι URL" + }, "header_label": "Element Κεντρική Οθόνη Κλήσεων", "join_existing_call_modal": { "join_button": "Ναι, συμμετοχή στην κλήση", diff --git a/locales/en/app.json b/locales/en/app.json index d5c6293a..e8a86fcc 100644 --- a/locales/en/app.json +++ b/locales/en/app.json @@ -61,6 +61,7 @@ "video": "Video" }, "developer_mode": { + "always_show_iphone_earpiece": "Show iPhone earpiece option on all platforms", "crypto_version": "Crypto version: {{version}}", "debug_tile_layout_label": "Debug tile layout", "device_id": "Device ID: {{id}}", @@ -70,6 +71,7 @@ "livekit_server_info": "LiveKit Server Info", "livekit_sfu": "LiveKit SFU: {{url}}", "matrix_id": "Matrix ID: {{id}}", + "mute_all_audio": "Mute all audio (participants, reactions, join sounds)", "show_connection_stats": "Show connection statistics", "show_non_member_tiles": "Show tiles for non-member media", "url_params": "URL parameters", @@ -164,12 +166,17 @@ "effect_volume_description": "Adjust the volume at which reactions and hand raised effects play.", "effect_volume_label": "Sound effect volume" }, + "background_blur_header": "Background", + "background_blur_label": "Blur the background of the video", + "blur_not_supported_by_browser": "(Background blur is not supported by this device.)", "developer_tab_title": "Developer", "devices": { "camera": "Camera", "camera_numbered": "Camera {{n}}", + "change_device_button": "Change audio device", "default": "Default", "default_named": "Default <2>({{name}})", + "earpiece": "Earpiece", "microphone": "Microphone", "microphone_numbered": "Microphone {{n}}", "speaker": "Speaker", diff --git a/locales/et/app.json b/locales/et/app.json index d3db8c74..ed32a6fc 100644 --- a/locales/et/app.json +++ b/locales/et/app.json @@ -70,10 +70,12 @@ "livekit_server_info": "LiveKiti serveri teave", "livekit_sfu": "LiveKit SFU: {{url}}", "matrix_id": "Matrixi kasutajatunnus: {{id}}", + "mute_all_audio": "Summuta kõik helid (osalejad, regeerimised, liitumise helid)", "show_connection_stats": "Näita ühenduse statistikat", "show_non_member_tiles": "Näita ka mitteseotud meedia paane", "url_params": "Võrguaadressi parameetrid", - "use_new_membership_manager": "Kasuta kõne liikmelisuse halduri (MembershipManager) uut implementatsiooni" + "use_new_membership_manager": "Kasuta kõne liikmelisuse halduri (MembershipManager) uut implementatsiooni", + "use_to_device_key_transport": "Kasuta seadmepõhist krüptovõtmete vahetust. Kui jututoa liige peaks saatma jututoakohase krüptovõtme, siis kasuta jututoakohast võtmevahetust" }, "disconnected_banner": "Võrguühendus serveriga on katkenud.", "error": { @@ -163,6 +165,9 @@ "effect_volume_description": "Häälesta helivaljust, mida kasutatakse käe tõstmisel ja regeerimisel", "effect_volume_label": "Efektide helivajlus" }, + "background_blur_header": "Taust", + "background_blur_label": "Hägusta video taust", + "blur_not_supported_by_browser": "(Tausta hägustamine pole selles seadmes toetatud.)", "developer_tab_title": "Arendaja", "devices": { "camera": "Kaamera", diff --git a/locales/fi/app.json b/locales/fi/app.json new file mode 100644 index 00000000..9e8a463c --- /dev/null +++ b/locales/fi/app.json @@ -0,0 +1,224 @@ +{ + "a11y": { + "user_menu": "Käyttäjävalikko" + }, + "action": { + "close": "Sulje", + "copy_link": "Kopioi linkki", + "edit": "Muokkaa", + "go": "Siirry", + "invite": "Kutsu", + "lower_hand": "Laske käsi", + "no": "Ei", + "pick_reaction": "Valitse reaktio", + "raise_hand": "Nosta käsi", + "register": "Rekisteröidy", + "remove": "Poista", + "show_less": "Näytä vähemmän", + "show_more": "Näytä lisää", + "sign_in": "Kirjaudu sisään", + "sign_out": "Kirjaudu ulos", + "submit": "Lähetä", + "upload_file": "Lähetä tiedosto" + }, + "analytics_notice": "Osallistumalla tähän betaan hyväksyt nimettömien tietojen keräämisen, joita käytämme tuotteen parantamiseen. Löydät lisätietoa siitä, mitä tietoja seuraamme meidän <2> Tietosuojakäytännöstä ja <6>Evästekäytännöstä .", + "app_selection_modal": { + "continue_in_browser": "Jatka selaimessa", + "open_in_app": "Avaa sovelluksessa", + "text": "Oletko valmis liittymään?", + "title": "Valitse sovellus" + }, + "call_ended_view": { + "create_account_button": "Luo tili", + "create_account_prompt": "<0>Miksi et viimeistelisi määrittämällä salasanaa tilisi säilyttämiseksi?<1>Voit säilyttää nimesi ja asettaa avatarin käytettäväksi tulevissa puheluissa", + "feedback_done": "<0>Kiitos palautteestasi!", + "feedback_prompt": "<0>Haluaisimme kuulla palautteesi, jotta voimme parantaa käyttökokemustasi.", + "headline": "{{displayName}}, puhelusi on päättynyt.", + "not_now_button": "Ei nyt, palaa aloitusnäyttöön", + "reconnect_button": "Yhdistä uudelleen", + "survey_prompt": "Miten se meni?" + }, + "call_name": "Puhelun nimi", + "common": { + "analytics": "Analytiikka", + "audio": "Ääni", + "avatar": "Avatar", + "back": "Takaisin", + "display_name": "Näyttönimi", + "encrypted": "Salattu", + "home": "Etusivu", + "loading": "Ladataan...", + "next": "Seuraava", + "options": "Vaihtoehdot", + "password": "Salasana", + "preferences": "Asetukset", + "profile": "Profiili", + "reaction": "Reaktio", + "reactions": "Reaktiot", + "settings": "Asetukset", + "unencrypted": "Ei salattu", + "username": "Käyttäjänimi", + "video": "Video" + }, + "developer_mode": { + "crypto_version": "Kryptoversio: {{version}}", + "debug_tile_layout_label": "Laattojen asettelun vianmääritys", + "device_id": "Laitteen tunnus: {{id}}", + "duplicate_tiles_label": "Lisälaattakopioiden määrä osallistujaa kohti", + "environment_variables": "Ympäristömuuttujat", + "hostname": "Isäntänimi: {{hostname}}", + "livekit_server_info": "LiveKit-palvelimen tiedot", + "livekit_sfu": "LiveKit SFU: {{url}}", + "matrix_id": "Matrix tunnus: {{id}}", + "show_connection_stats": "Näytä yhteystilastot", + "show_non_member_tiles": "Näytä laatat ei-jäsenien medialle", + "url_params": "URL-parametrit", + "use_new_membership_manager": "Käytä uutta puhelun MembershipManagerin toteutusta", + "use_to_device_key_transport": "Käytä laitteen avainten kuljetusta. Tämä palaa huoneen avainten siirtoon, kun toinen puhelun jäsen lähettää huoneavaimen" + }, + "disconnected_banner": "Yhteys palvelimeen on katkennut.", + "error": { + "call_is_not_supported": "Puhelua ei tueta", + "call_not_found": "Puhelua ei löydy", + "call_not_found_description": "<0>Kyseinen linkki ei näytä kuuluvan mihinkään olemassa olevaan puheluun. Tarkista, että sinulla on oikea linkki, tai <1>luo uusi linkki.", + "connection_lost": "Yhteys katkesi", + "connection_lost_description": "Sinut katkaistiin puhelusta.", + "e2ee_unsupported": "Yhteensopimaton selain", + "e2ee_unsupported_description": "Verkkoselaimesi ei tue salattuja puheluita. Tuettuja selaimia ovat Chrome, Safari ja Firefox 117+.", + "generic": "Jokin meni pieleen", + "generic_description": "Vianmäärityslokien lähettäminen auttaa meitä jäljittämään ongelman.", + "insufficient_capacity": "Riittämätön kapasiteetti", + "insufficient_capacity_description": "Palvelin on saavuttanut maksimikapasiteettinsa, etkä voi liittyä puheluun tällä hetkellä. Yritä myöhemmin uudelleen tai ota yhteyttä palvelimen ylläpitäjään, jos ongelma jatkuu.", + "matrix_rtc_focus_missing": "Palvelinta ei ole määritetty toimimaan {{brand}} -sovelluksen kanssa. Ota yhteyttä palvelimen ylläpitäjään (Verkkotunnus: {{domain}}, Virhekoodi: {{ errorCode }}).", + "open_elsewhere": "Avattu toisessa välilehdessä", + "open_elsewhere_description": "{{brand}} on avattu toisessa välilehdessä. Jos tämä ei kuulosta oikealta, yritä ladata sivu uudelleen.", + "unexpected_ec_error": "Tapahtui odottamaton virhe (<0>Virhekoodi: <1>{{ errorCode }}). Ota yhteyttä palvelimen ylläpitäjään." + }, + "group_call_loader": { + "banned_body": "Sinulle on annettu porttikielto huoneesta.", + "banned_heading": "Kielletty", + "call_ended_body": "Sinut on poistettu puhelusta.", + "call_ended_heading": "Puhelu päättyi", + "knock_reject_body": "Liittymispyyntösi hylättiin.", + "knock_reject_heading": "Pääsy kielletty", + "reason": "Syy: {{reason}}" + }, + "hangup_button_label": "Lopeta puhelu", + "header_label": "Element Call Etusivu", + "header_participants_label": "Osallistujat", + "invite_modal": { + "link_copied_toast": "Linkki kopioitu leikepöydälle", + "title": "Kutsu tähän puheluun" + }, + "join_existing_call_modal": { + "join_button": "Kyllä, liity puheluun", + "text": "Tämä puhelu on jo olemassa, haluatko liittyä siihen?", + "title": "Liity olemassa olevaan puheluun?" + }, + "layout_grid_label": "Ruudukko", + "layout_spotlight_label": "Valokeila", + "lobby": { + "ask_to_join": "Pyydä liittymistä puheluun", + "join_as_guest": "Liity vieraana", + "join_button": "Liity puheluun", + "leave_button": "Takaisin viimeisimpiin puheluihin", + "waiting_for_invite": "Pyyntö lähetetty! Odotetaan lupaa liittyä…" + }, + "log_in": "Kirjaudu sisään", + "logging_in": "Kirjaudutaan sisään…", + "login_auth_links": "<0>Luo tili tai <2>Käytä vieraana", + "login_auth_links_prompt": "Etkö ole vielä rekisteröitynyt?", + "login_subheading": "Jatkaaksesi Elementiin", + "login_title": "Kirjaudu sisään", + "microphone_off": "Mikrofoni pois päältä", + "microphone_on": "Mikrofoni päällä", + "mute_microphone_button_label": "Mykistä mikrofoni", + "participant_count_one": "{{count, number}}", + "participant_count_other": "{{count, number}}", + "qr_code": "QR-koodi", + "rageshake_button_error_caption": "Yritä uudelleen lokien lähettämistä", + "rageshake_request_modal": { + "body": "Toisella käyttäjällä tässä puhelussa on ongelma. Jotta voimme diagnosoida nämä ongelmat paremmin, haluaisimme kerätä virheenkorjauslokin.", + "title": "Virheenkorjauslokipyyntö" + }, + "rageshake_send_logs": "Lähetä virheenkorjauslokit", + "rageshake_sending": "Lähetetään…", + "rageshake_sending_logs": "Lähetetään virheenkorjauslokeja…", + "rageshake_sent": "Kiitos!", + "recaptcha_dismissed": "Recaptcha hylätty", + "recaptcha_not_loaded": "Recaptcha ei ole ladattu", + "recaptcha_ssla_caption": "Tämä sivusto on suojattu ReCAPTCHA:lla, ja siihen sovelletaan Googlen <2>Tietosuojakäytäntöä ja <6>Palveluehtoja.<9>Klikkaamalla \"Rekisteröidy\" hyväksyt <12>ohjelmisto- ja palvelulisenssisopimuksen (SSLA)", + "register": { + "passwords_must_match": "Salasanojen on täsmättävä", + "registering": "Rekisteröidään…" + }, + "register_auth_links": "<0>Onko sinulla jo tili?<1><0>Kirjaudu sisään tai <2>Käytä vieraana", + "register_confirm_password_label": "Vahvista salasana", + "register_heading": "Luo tilisi", + "return_home_button": "Palaa aloitusnäyttöön", + "room_auth_view_continue_button": "Jatka", + "room_auth_view_ssla_caption": "Klikkaamalla \"Liity puheluun nyt\" hyväksyt <2>ohjelmisto- ja palvelulisenssisopimuksen (SSLA)", + "screenshare_button_label": "Jaa näyttö", + "settings": { + "audio_tab": { + "effect_volume_description": "Säädä äänenvoimakkuutta, jolla reaktioiden ja käden nostojen ääniefektit toistetaan.", + "effect_volume_label": "Ääniefektien äänenvoimakkuus" + }, + "background_blur_header": "Tausta", + "background_blur_label": "Sumenna videon tausta", + "blur_not_supported_by_browser": "(Tämä laite ei tue taustan sumennusta.)", + "developer_tab_title": "Kehittäjä", + "devices": { + "camera": "Kamera", + "camera_numbered": "Kamera {{n}}", + "default": "Oletus", + "default_named": "Oletus <2>({{name}})", + "microphone": "Mikrofoni", + "microphone_numbered": "Mikrofoni {{n}}", + "speaker": "Kaiutin", + "speaker_numbered": "Kaiutin {{n}}" + }, + "feedback_tab_body": "Jos sinulla on ongelmia tai haluat vain antaa palautetta, lähetä meille lyhyt kuvaus alla.", + "feedback_tab_description_label": "Palautteesi", + "feedback_tab_h4": "Lähetä palautetta", + "feedback_tab_send_logs_label": "Sisällytä virheenkorjauslokit", + "feedback_tab_thank_you": "Kiitos, saimme palautteesi!", + "feedback_tab_title": "Palaute", + "opt_in_description": "<0><1>Voit peruuttaa suostumuksesi poistamalla tämän ruudun valinnan. Jos puhelu on käynnissä, tämä asetus tulee voimaan puhelun lopussa.", + "preferences_tab": { + "developer_mode_label": "Kehittäjätila", + "developer_mode_label_description": "Ota kehittäjätila käyttöön ja näytä kehittäjäasetukset-välilehti.", + "introduction": "Täällä voit määrittää lisävaihtoehtoja parempaa käyttökokemusta varten.", + "reactions_play_sound_description": "Toista äänitefekti, kun joku lähettää reaktion puheluun.", + "reactions_play_sound_label": "Toista reaktioäänet", + "reactions_show_description": "Näytä animaatio, kun joku lähettää reaktion.", + "reactions_show_label": "Näytä reaktiot", + "show_hand_raised_timer_description": "Näytä ajastin, kun osallistuja nostaa kätensä", + "show_hand_raised_timer_label": "Näytä kädennoston kesto" + } + }, + "star_rating_input_label_one": "{{count}} tähti", + "star_rating_input_label_other": "{{count}} tähteä", + "start_new_call": "Aloita uusi puhelu", + "start_video_button_label": "Aloita video", + "stop_screenshare_button_label": "Jaetaan näyttöä", + "stop_video_button_label": "Lopeta video", + "submitting": "Lähetetään…", + "switch_camera": "Vaihda kameraa", + "unauthenticated_view_body": "Etkö ole vielä rekisteröitynyt? <2>Luo tili", + "unauthenticated_view_login_button": "Kirjaudu tilillesi", + "unauthenticated_view_ssla_caption": "Klikkaamalla \"Siirry\" hyväksyt <2>ohjelmisto- ja palvelulisenssisopimuksen (SSLA)", + "unmute_microphone_button_label": "Poista mikrofonin mykistys", + "version": "{{productName}} versio: {{version}}", + "video_tile": { + "always_show": "Näytä aina", + "camera_starting": "Videota ladataan...", + "change_fit_contain": "Sovita kehykseen", + "collapse": "Supista", + "expand": "Laajenna", + "mute_for_me": "Mykistä minulle", + "muted_for_me": "Mykistetty minulle", + "volume": "Äänenvoimakkuus", + "waiting_for_media": "Odotetaan mediaa..." + } +} diff --git a/locales/id/app.json b/locales/id/app.json index 377d23d5..ac1c6221 100644 --- a/locales/id/app.json +++ b/locales/id/app.json @@ -5,14 +5,21 @@ "action": { "close": "Tutup", "copy_link": "Salin tautan", + "edit": "Sunting", "go": "Bergabung", "invite": "Undang", + "lower_hand": "Turunkan tangan", "no": "Tidak", + "pick_reaction": "Pilih reaksi", + "raise_hand": "Angkat tangan", "register": "Daftar", "remove": "Hapus", + "show_less": "Tampilkan lebih sedikit", + "show_more": "Tampilkan lebih banyak", "sign_in": "Masuk", "sign_out": "Keluar", - "submit": "Kirim" + "submit": "Kirim", + "upload_file": "Unggah berkas" }, "analytics_notice": "Dengan bergabung dalam beta ini, Anda mengizinkan kami untuk mengumpulkan data anonim, yang kami gunakan untuk meningkatkan produk ini. Anda dapat mempelajari lebih lanjut tentang data apa yang kami lacak dalam <2>Kebijakan Privasi dan <5>Kebijakan Kuki kami.", "app_selection_modal": { @@ -33,17 +40,69 @@ }, "call_name": "Nama panggilan", "common": { + "analytics": "Analitik", + "audio": "Audio", + "avatar": "Avatar", + "back": "Kembali", "display_name": "Nama tampilan", "encrypted": "Terenkripsi", "home": "Beranda", "loading": "Memuat…", + "next": "Berikutnya", + "options": "Opsi", "password": "Kata sandi", + "preferences": "Preferensi", "profile": "Profil", + "reaction": "Reaksi", + "reactions": "Reaksi", "settings": "Pengaturan", "unencrypted": "Tidak terenkripsi", - "username": "Nama pengguna" + "username": "Nama pengguna", + "video": "Video" + }, + "developer_mode": { + "crypto_version": "Versi kripto: {{version}}", + "debug_tile_layout_label": "Awakutu tata letak ubin", + "device_id": "ID perangkat: {{id}}", + "duplicate_tiles_label": "Jumlah salinan ubin tambahan per peserta", + "environment_variables": "Variabel lingkungan", + "hostname": "Nama hos: {{hostname}}", + "livekit_server_info": "Info Server LiveKit", + "livekit_sfu": "SFU LiveKit: {{url}}", + "matrix_id": "ID Matrix: {{id}}", + "show_connection_stats": "Tampilkan statistik koneksi", + "show_non_member_tiles": "Tampilkan ubin untuk media non-anggota", + "url_params": "Parameter URL", + "use_new_membership_manager": "Gunakan implementasi baru dari panggilan MembershipManager", + "use_to_device_key_transport": "Gunakan untuk transportasi kunci perangkat. Ini akan kembali ke transportasi kunci ruangan ketika anggota panggilan lain mengirim kunci ruangan" }, "disconnected_banner": "Koneksi ke server telah hilang.", + "error": { + "call_is_not_supported": "Panggilan tidak didukung", + "call_not_found": "Panggilan tidak ditemukan", + "call_not_found_description": "<0>Tautan itu tampaknya bukan milik panggilan yang ada. Periksa apakah Anda memiliki tautan yang tepat, atau <1> buat yang baru.", + "connection_lost": "Koneksi terputus", + "connection_lost_description": "Anda terputus dari panggilan.", + "e2ee_unsupported": "Peramban tidak kompatibel", + "e2ee_unsupported_description": "Peramban web Anda tidak mendukung panggilan terenkripsi. Peramban yang didukung meliputi Chrome, Safari, dan Firefox 117+.", + "generic": "Ada yang salah", + "generic_description": "Mengirimkan log awakutu akan membantu kami melacak masalah.", + "insufficient_capacity": "Kapasitas tidak mencukupi", + "insufficient_capacity_description": "Server telah mencapai kapasitas maksimum dan Anda tidak dapat bergabung dalam panggilan saat ini. Coba lagi nanti, atau hubungi admin server Anda jika masalah masih berlanjut.", + "matrix_rtc_focus_missing": "Server tidak dikonfigurasi untuk bekerja dengan {{brand}}. Silakan hubungi admin server Anda (Domain: {{domain}}, Kode Kesalahan: {{ errorCode }}).", + "open_elsewhere": "Dibuka di tab lain", + "open_elsewhere_description": "{{brand}} telah dibuka di tab lain. Jika sepertinya tidak benar, coba muat ulang halaman.", + "unexpected_ec_error": "Terjadi kesalahan tak terduga (<0> Kode Kesalahan:<1>{{ errorCode }}). Silakan hubungi admin server Anda." + }, + "group_call_loader": { + "banned_body": "Anda telah dilarang dari ruangan.", + "banned_heading": "Dilarang", + "call_ended_body": "Anda telah dikeluarkan dari panggilan.", + "call_ended_heading": "Panggilan berakhir", + "knock_reject_body": "Permintaan Anda untuk bergabung ditolak.", + "knock_reject_heading": "Akses ditolak", + "reason": "Alasan: {{reason}}" + }, "hangup_button_label": "Akhiri panggilan", "header_label": "Beranda Element Call", "header_participants_label": "Peserta", @@ -59,15 +118,23 @@ "layout_grid_label": "Kisi", "layout_spotlight_label": "Sorotan", "lobby": { + "ask_to_join": "Permintaan untuk bergabung dalam panggilan", + "join_as_guest": "Bergabung sebagai tamu", "join_button": "Bergabung ke panggilan", - "leave_button": "Kembali ke terkini" + "leave_button": "Kembali ke terkini", + "waiting_for_invite": "Permintaan terkirim! Menunggu izin untuk bergabung…" }, + "log_in": "Masuk", "logging_in": "Memasuki…", "login_auth_links": "<0>Buat akun Atau <2>Akses sebagai tamu", + "login_auth_links_prompt": "Belum terdaftar?", + "login_subheading": "Untuk melanjutkan ke Element", "login_title": "Masuk", "microphone_off": "Mikrofon dimatikan", "microphone_on": "Mikrofon dinyalakan", "mute_microphone_button_label": "Matikan mikrofon", + "participant_count_other": "{{count, number}}", + "qr_code": "Kode QR", "rageshake_button_error_caption": "Kirim ulang catatan", "rageshake_request_modal": { "body": "Pengguna yang lain di panggilan ini sedang mengalami masalah. Supaya dapat mendiagnosa masalah ini, kami ingin mengumpulkan sebuah catatan pengawakutuan.", @@ -79,23 +146,55 @@ "rageshake_sent": "Terima kasih!", "recaptcha_dismissed": "Recaptcha ditutup", "recaptcha_not_loaded": "Recaptcha tidak dimuat", + "recaptcha_ssla_caption": "Situs ini dilindungi oleh ReCAPTCHA dan <2>Kebijakan Privasi dan <6>Ketentuan Layanan Google berlaku.<9>Dengan mengeklik \"Daftar\", Anda menyetujui <12>Perjanjian Lisensi Perangkat Lunak dan Layanan (SSLA) kami", "register": { "passwords_must_match": "Kata sandi harus cocok", "registering": "Mendaftarkan…" }, "register_auth_links": "<0>Sudah punya akun?<1><0>Masuk Atau <2>Akses sebagai tamu", "register_confirm_password_label": "Konfirmasi kata sandi", + "register_heading": "Buat akun Anda", "return_home_button": "Kembali ke layar beranda", + "room_auth_view_continue_button": "Lanjutkan", + "room_auth_view_ssla_caption": "Dengan mengeklik “Gabung panggilan sekarang”, Anda menyetujui <2>Perjanjian Lisensi Perangkat Lunak dan Layanan (SSLA) kami", "screenshare_button_label": "Bagikan layar", "settings": { + "audio_tab": { + "effect_volume_description": "Sesuaikan volume saat reaksi dan efek tangan terangkat diputar.", + "effect_volume_label": "Volume efek suara" + }, + "background_blur_header": "Latar belakang", + "background_blur_label": "Buramkan latar belakang video", + "blur_not_supported_by_browser": "(Pemburaman latar belakang tidak didukung oleh perangkat ini.)", "developer_tab_title": "Pengembang", + "devices": { + "camera": "Kamera", + "camera_numbered": "Kamera {{n}}", + "default": "Bawaan", + "default_named": "Bawaan <2>({{name}})", + "microphone": "Mikrofon", + "microphone_numbered": "Mikrofon {{n}}", + "speaker": "Speaker", + "speaker_numbered": "Speaker {{n}}" + }, "feedback_tab_body": "Jika Anda mengalami masalah atau hanya ingin memberikan masukan, silakan kirimkan kami deskripsi pendek di bawah.", "feedback_tab_description_label": "Masukan Anda", "feedback_tab_h4": "Kirim masukan", "feedback_tab_send_logs_label": "Termasuk catatan pengawakutuan", "feedback_tab_thank_you": "Terima kasih, kami telah menerima masukan Anda!", "feedback_tab_title": "Masukan", - "opt_in_description": "<0><1>Anda dapat mengurungkan kembali izin dengan mencentang kotak ini. Jika Anda saat ini dalam panggilan, pengaturan ini akan diterapkan di akhir panggilan." + "opt_in_description": "<0><1>Anda dapat mengurungkan kembali izin dengan mencentang kotak ini. Jika Anda saat ini dalam panggilan, pengaturan ini akan diterapkan di akhir panggilan.", + "preferences_tab": { + "developer_mode_label": "Mode pengembang", + "developer_mode_label_description": "Aktifkan mode pengembang dan tampilkan tab pengaturan pengembang.", + "introduction": "Di sini Anda dapat mengonfigurasi opsi tambahan untuk pengalaman yang lebih baik.", + "reactions_play_sound_description": "Mainkan efek suara ketika seseorang mengirim reaksi ke panggilan.", + "reactions_play_sound_label": "Putar suara reaksi", + "reactions_show_description": "Tampilkan animasi ketika ada yang mengirimkan reaksi.", + "reactions_show_label": "Tampilkan reaksi", + "show_hand_raised_timer_description": "Tampilkan pengatur waktu saat peserta mengangkat tangannya", + "show_hand_raised_timer_label": "Tampilkan durasi angkat tangan" + } }, "star_rating_input_label_one": "{{count}} bintang", "star_rating_input_label_other": "{{count}} bintang", @@ -104,8 +203,21 @@ "stop_screenshare_button_label": "Berbagi layar", "stop_video_button_label": "Matikan video", "submitting": "Mengirim…", + "switch_camera": "Ganti kamera", "unauthenticated_view_body": "Belum terdaftar? <2>Buat sebuah akun", "unauthenticated_view_login_button": "Masuk ke akun Anda", + "unauthenticated_view_ssla_caption": "Dengan mengeklik \"Go\", Anda menyetujui <2>Perjanjian Lisensi Perangkat Lunak dan Layanan (SSLA) kami", "unmute_microphone_button_label": "Nyalakan mikrofon", - "version": "Versi: {{version}}" + "version": "Versi: {{version}}", + "video_tile": { + "always_show": "Selalu tampilkan", + "camera_starting": "Memuat video...", + "change_fit_contain": "Sesuai dengan bingkai", + "collapse": "Tutup", + "expand": "Buka", + "mute_for_me": "Bisukan untuk saya", + "muted_for_me": "Dibisukan untuk saya", + "volume": "Volume", + "waiting_for_media": "Menunggu media..." + } } diff --git a/locales/lv/app.json b/locales/lv/app.json index bc281463..4c351d97 100644 --- a/locales/lv/app.json +++ b/locales/lv/app.json @@ -4,15 +4,30 @@ }, "action": { "close": "Aizvērt", + "copy_link": "Kopēt saiti", + "edit": "Labot", "go": "Aiziet", + "invite": "Uzaicināt", + "lower_hand": "Nolaist roku", "no": "Nē", + "pick_reaction": "Reaģēt", + "raise_hand": "Pacelt roku", "register": "Reģistrēties", "remove": "Noņemt", + "show_less": "Rādīt mazāk", + "show_more": "Rādīt vairāk", "sign_in": "Pieteikties", "sign_out": "Atteikties", - "submit": "Iesniegt" + "submit": "Iesniegt", + "upload_file": "Augšupielādēt failu" + }, + "analytics_notice": "Piedaloties šajā beta versijā, jūs piekrītat anonīmu datu vākšanai, ko mēs izmantojam produkta uzlabošanai. Plašāku informāciju par to, kādus datus mēs izsekojam, varat atrast mūsu <2>konfidencialitātes politikā un mūsu <6>sīkfailu politikā.", + "app_selection_modal": { + "continue_in_browser": "Turpināt pārlūkprogrammā", + "open_in_app": "Atvērt lietotnē", + "text": "Gatavs pievienoties?", + "title": "Izvēlies lietotni" }, - "analytics_notice": "Piedalīšanās šajā beta apliecina piekrišanu anonīmu datu ievākšanai, ko mēs izmantojam, lai uzlabotu izstrādājumu. Vairāk informācijas par datiem, ko mēs ievācam, var atrast mūsu <2>privātuma nosacījumos un <5>sīkdatņu nosacījumos.", "call_ended_view": { "create_account_button": "Izveidot kontu", "create_account_prompt": "<0>Kādēļ nepabeigt ar paroles iestatīšanu, lai paturētu savu kontu?<1>Būs iespējams paturēt savu vārdu un iestatīt attēlu izmantošanai turpmākajos zvanos", @@ -23,31 +38,104 @@ "reconnect_button": "Atkārtoti savienoties", "survey_prompt": "Kā Tev veicās?" }, + "call_name": "Zvana nosaukums", "common": { + "analytics": "Analītika", "audio": "Skaņa", "avatar": "Attēls", + "back": "Atpakaļ", "display_name": "Attēlojamais vārds", + "encrypted": "Šifrēts", "home": "Sākums", "loading": "Lādējas…", + "next": "Nākamais", + "options": "Opcijas", "password": "Parole", + "preferences": "Iestatījumi", "profile": "Profils", + "reaction": "Reakcija", + "reactions": "Reakcijas", "settings": "Iestatījumi", - "username": "Lietotājvārds" + "unencrypted": "Nav šifrēts", + "username": "Lietotājvārds", + "video": "Video" + }, + "developer_mode": { + "crypto_version": "Crypto versija: {{version}}", + "debug_tile_layout_label": "Vietu izkārtojuma atkļūdošana", + "device_id": "Ierīces ID: {{id}}", + "duplicate_tiles_label": "Papildu vietu kopiju skaits vienam dalībniekam", + "environment_variables": "Vides mainīgie", + "hostname": "Saimniekdatora nosaukums: {{hostname}}", + "livekit_server_info": "LiveKit Server informācija", + "livekit_sfu": "LiveKit SFU: {{url}}", + "matrix_id": "Matrix ID: {{id}}", + "show_connection_stats": "Rādīt savienojuma statistiku", + "show_non_member_tiles": "Rādīt vietu medijiem no ne-dalībniekiem", + "url_params": "URL parametri", + "use_new_membership_manager": "Izmantojiet jauno zvana MembershipManager versiju" }, "disconnected_banner": "Ir zaudēts savienojums ar serveri.", + "error": { + "call_is_not_supported": "Zvans netiek atbalstīts", + "call_not_found": "Zvans nav atrasts", + "call_not_found_description": "<0>Šķiet, ka šī saite nepieder nevienam esošam zvaniem. Pārbaudiet, vai jums ir pareizā saite, vai <1> izveidojiet jaunu. ", + "connection_lost": "Savienojums zaudēts", + "connection_lost_description": "Jūs tikāt atvienots no zvana.", + "e2ee_unsupported": "Nesaderīgs pārlūks", + "e2ee_unsupported_description": "Jūsu tīmekļa pārlūkprogramma neatbalsta encrypted zvanus. Atbalstītās pārlūkprogrammas ir Chrome, Safari un Firefox 117+.", + "generic": "Kaut kas nogāja greizi", + "generic_description": "Atkļūdošanas žurnālu iesniegšana palīdzēs mums izsekot problēmu.", + "insufficient_capacity": "Nepietiekama jauda", + "insufficient_capacity_description": "Serveris ir sasniedzis maksimālo ietilpību, un jūs šobrīd nevarat pievienoties zvanam. Mēģiniet vēlreiz vēlāk vai sazinieties ar servera administratoru, ja problēma joprojām pastāv.", + "matrix_rtc_focus_missing": "Serveris nav konfigurēts darbam ar{{brand}}. Lūdzu, sazinieties ar sava servera administratoru (Domēns: {{domain}}, Kļūdas kods: {{ errorCode }}).", + "open_elsewhere": "Atvērts citā cilnē", + "open_elsewhere_description": "{{brand}} ir atvērts citā cilnē. Ja tas neizklausās pareizi, mēģiniet atkārtoti ielādēt lapu.", + "unexpected_ec_error": "Negaidīta kļūda (<0>kļūdas kods: <1> {{ errorCode }}). Lūdzu, sazinieties ar servera administratoru." + }, + "group_call_loader": { + "banned_body": "Jums ir liegta ieeja šajā istabā.", + "banned_heading": "Aizliegts", + "call_ended_body": "Jūs esat noņemts no zvana.", + "call_ended_heading": "Zvans beidzies", + "knock_reject_body": "Jūsu pieteikums pievienoties tika noraidīts.", + "knock_reject_heading": "Piekļuve liegta", + "reason": "Iemesls: {{reason}}" + }, + "hangup_button_label": "Beigt zvanu", "header_label": "Element Call sākums", + "header_participants_label": "Dalībnieki", + "invite_modal": { + "link_copied_toast": "Saite nokopēta", + "title": "Uzaicināt uz šo zvanu" + }, "join_existing_call_modal": { "join_button": "Jā, pievienoties zvanam", "text": "Šis zvans jau pastāv. Vai vēlies pievienoties?", "title": "Pievienoties esošam zvanam?" }, + "layout_grid_label": "Režģis", "layout_spotlight_label": "Starmešu gaisma", "lobby": { - "join_button": "Pievienoties zvanam" + "ask_to_join": "Pieprasīt pievienoties zvanam", + "join_as_guest": "Pievienojies kā viesis", + "join_button": "Pievienoties zvanam", + "leave_button": "Atpakaļ uz jaunākajiem", + "waiting_for_invite": "Pieprasījums nosūtīts! Gaida atļauju pievienoties..." }, + "log_in": "Pieslēgties", "logging_in": "Piesakās…", "login_auth_links": "<0>Izveidot kontu vai <2>Piekļūt kā viesim", + "login_auth_links_prompt": "Vēl neesi reģistrējies?", + "login_subheading": "Lai turpinātu uz Element", "login_title": "Pieteikties", + "microphone_off": "Mikrofons izslēgts", + "microphone_on": "Mikrofons ieslēgts", + "mute_microphone_button_label": "Izslēgt mikrofonu", + "participant_count_zero": "{{count, number}}", + "participant_count_one": "{{count, number}}", + "participant_count_other": "{{count, number}}", + "qr_code": "QR kods", "rageshake_button_error_caption": "Atkārtoti mēģināt žurnāla ierakstu nosūtīšanu", "rageshake_request_modal": { "body": "Citam lietotājam šajā zvanā ir sarežģījumi. Lai labāk atklātu šīs nepilnības, mēs gribētu iegūt atkļūdošanas žurnālu.", @@ -59,28 +147,76 @@ "rageshake_sent": "Paldies!", "recaptcha_dismissed": "ReCaptcha atmesta", "recaptcha_not_loaded": "ReCaptcha nav ielādēta", + "recaptcha_ssla_caption": "Šo vietni aizsargā ReCAPTCHA un tiek piemēroti Google <2>konfidencialitātes politika un <6>Pakalpojuma noteikumi.<9>Noklikšķinot uz \"Reģistrēties\", jūs piekrītat mūsu <12>Programmatūras un pakalpojumu licences līgumam (SSLA)", "register": { "passwords_must_match": "Parolēm ir jāsakrīt", "registering": "Reģistrē…" }, "register_auth_links": "<0>Jau ir konts?<1><0>Pieteikties vai <2>Piekļūt kā viesim", "register_confirm_password_label": "Apstiprināt paroli", + "register_heading": "Izveido kontu", "return_home_button": "Atgriezties sākuma ekrānā", + "room_auth_view_continue_button": "Turpināt", + "room_auth_view_ssla_caption": "Noklikšķinot uz “Pievienoties zvanam tūlīt”, jūs piekrītat mūsu <2> programmatūras un pakalpojumu licences līgumam (SSLA) ", "screenshare_button_label": "Kopīgot ekrānu", "settings": { + "audio_tab": { + "effect_volume_description": "Pielāgojiet skaļumu, kurā tiek atskaņotas reakcijas un paceltas rokas skaņas.", + "effect_volume_label": "Skaņas efektu skaļums" + }, "developer_tab_title": "Izstrādātājs", + "devices": { + "camera": "Kamera", + "camera_numbered": "Kamera {{n}}", + "default": "Noklusējums", + "default_named": "Noklusējums <2> ({{name}} )", + "microphone": "Mikrofons", + "microphone_numbered": "Mikrofons {{n}}", + "speaker": "Skaļrunis", + "speaker_numbered": "Skaļrunis {{n}}" + }, "feedback_tab_body": "Ja tiek piedzīvoti sarežģījumi vai vienkārši ir vēlme sniegt kādu atsauksmi, lūgums zemāk nosūtīt mums īsu aprakstu.", "feedback_tab_description_label": "Tava atsauksme", "feedback_tab_h4": "Iesniegt atsauksmi", "feedback_tab_send_logs_label": "Iekļaut atkļūdošanas žurnāla ierakstus", "feedback_tab_thank_you": "Paldies, mēs saņēmām atsauksmi!", "feedback_tab_title": "Atsauksmes", - "opt_in_description": "<0><1>Savu piekrišanu var atsaukt ar atzīmes noņemšanu no šīs rūtiņas. Ja pašreiz atrodies zvanā, šis iestatījums stāsies spēkā zvana beigās." + "opt_in_description": "<0><1>Savu piekrišanu var atsaukt ar atzīmes noņemšanu no šīs rūtiņas. Ja pašreiz atrodies zvanā, šis iestatījums stāsies spēkā zvana beigās.", + "preferences_tab": { + "developer_mode_label": "Izstrādātāja režīms", + "developer_mode_label_description": "Iespējot izstrādātāja režīmu un rādīt cilni izstrādātāja iestatījumi.", + "introduction": "Šeit varat konfigurēt papildu opcijas, lai uzlabotu pieredzi.", + "reactions_play_sound_description": "Atskaņojiet skaņas efektu, kad kāds sūta reakciju uz zvanu.", + "reactions_play_sound_label": "Atskaņojiet reakcijas skaņas", + "reactions_show_description": "Rādīt animāciju, kad kāds nosūta reakciju.", + "reactions_show_label": "Rādīt reakcijas", + "show_hand_raised_timer_description": "Rādīt taimeri, kad dalībnieks paceļ roku", + "show_hand_raised_timer_label": "Rādīt rokas pacelšanas ilgumu" + } }, + "star_rating_input_label_zero": "{{count}} zvaigznes", "star_rating_input_label_one": "{{count}} zvaigzne", "star_rating_input_label_other": "{{count}} zvaigznes", + "start_new_call": "Sākt jaunu zvanu", + "start_video_button_label": "Sākt video", + "stop_screenshare_button_label": "Kopīgo ekrānu", + "stop_video_button_label": "Apturēt video", "submitting": "Iesniedz…", + "switch_camera": "Pārslēgt kameru", "unauthenticated_view_body": "Vēl neesi reģistrējies? <2>Izveidot kontu", "unauthenticated_view_login_button": "Pieteikties kontā", - "version": "Versija: {{version}}" + "unauthenticated_view_ssla_caption": "Noklikšķinot uz \"Aiziet\", jūs piekrītat mūsu <2>Programmatūras un pakalpojumu licences līgumam (SSLA)", + "unmute_microphone_button_label": "Ieslēgt mikrofonu", + "version": "{{productName}} versija: {{version}}", + "video_tile": { + "always_show": "Vienmēr rādīt", + "camera_starting": "Video ielāde...", + "change_fit_contain": "Pielāgot rāmim", + "collapse": "Sakļaut", + "expand": "Izvērst", + "mute_for_me": "Klusums man", + "muted_for_me": "Man izslēgts", + "volume": "Skaļums", + "waiting_for_media": "Gaida medijus..." + } } diff --git a/locales/ro/app.json b/locales/ro/app.json index 61bb3e44..ceaa79b7 100644 --- a/locales/ro/app.json +++ b/locales/ro/app.json @@ -4,20 +4,20 @@ }, "action": { "close": "Închide", - "copy_link": "Copiază linkul", + "copy_link": "Copiaţi linkul", "edit": "Editare", "go": "Du-te", "invite": "Invită", "lower_hand": "Mâna inferioară", - "no": "No", + "no": "Nu", "pick_reaction": "Alegeți reacția", "raise_hand": "Ridicați mâna", - "register": "Inregistrare", + "register": "Creaţi un cont", "remove": "elimina", "show_less": "Arată mai puțin", "show_more": "Arată mai mult", "sign_in": "Autentificare", - "sign_out": "Sign out", + "sign_out": "Deconecta-ţi-vă", "submit": "Trimiteți", "upload_file": "Încărcați fișierul" }, @@ -26,27 +26,27 @@ "continue_in_browser": "Continuați în browser", "open_in_app": "Deschideți în aplicație", "text": "Sunteți gata să vă alăturați?", - "title": "Selectați aplicația" + "title": "Selectați o aplicație" }, "call_ended_view": { - "create_account_button": "Creează cont", + "create_account_button": "Creaţi un cont", "create_account_prompt": "<0>De ce să nu terminați prin configurarea unei parole pentru a vă păstra contul? <1>Veți putea să vă păstrați numele și să setați un avatar pentru a fi utilizat la apelurile viitoare ", "feedback_done": "<0>Vă mulțumim pentru feedback! ", "feedback_prompt": "<0>Ne-ar plăcea să auzim feedback-ul dvs., astfel încât să vă putem îmbunătăți experiența. ", "headline": "{{displayName}}, apelul tău s-a încheiat.", - "not_now_button": "Nu acum, reveniți la ecranul de pornire", - "reconnect_button": "Reconecta", - "survey_prompt": "Cum a mers?" + "not_now_button": "Nu acum, reveniți la ecranul principal", + "reconnect_button": "Reconectaţi-vă", + "survey_prompt": "Cum a fost?" }, "call_name": "Numele apelului", "common": { "analytics": "Analiză", "audio": "Audio", - "avatar": "avatar", + "avatar": "Imaginea de profil", "back": "Înapoi", "display_name": "Nume afișat", "encrypted": "Criptat", - "home": "Acasa", + "home": "Acasă", "loading": "Se încarcă...", "next": "Urmator\n", "options": "Opțiuni", @@ -55,19 +55,43 @@ "profile": "Profil", "reaction": "Reacție", "reactions": "Reacții", - "settings": "Settings", + "settings": "Setări", "unencrypted": "Nu este criptat", - "username": "Nume utilizator", - "video": "Videoclip" + "username": "Numele utilizatorului", + "video": "Video" }, "developer_mode": { "crypto_version": "Versiunea Crypto: {{version}}", + "debug_tile_layout_label": "Depanaţi aranjamentul cartonaşelor", "device_id": "ID-ul dispozitivului: {{id}}", "duplicate_tiles_label": "Numărul de exemplare suplimentare de cartonașe per participant", + "environment_variables": "Variabile de mediu", "hostname": "Numele gazdei: {{hostname}}", - "matrix_id": "ID-ul matricei: {{id}}" + "matrix_id": "ID-ul matricei: {{id}}", + "show_connection_stats": "Afişaţi informaţii cu privire la starea conexiunii", + "show_non_member_tiles": "Afişaţi pictograme pentru fluxul media care nu aparţine participanţilor apelului", + "url_params": "Parametrii linkului", + "use_new_membership_manager": "Folosiţi noua versiune de administrator pentru participanţi ai apelului", + "use_to_device_key_transport": "Folosiţi metoda de transport direct către dispozitiv. Aceasta va reveni la transportul prin intermediul evenimentelor din cameră doar dacă un alt participant la apel recurge la acel mod de transport mai întâi." + }, + "disconnected_banner": "Conexiunea către server s-a încheiat abrupt", + "error": { + "call_is_not_supported": "Acest tip de apel nu este suportat", + "call_not_found": "Apelul nu a fost găsit", + "call_not_found_description": "<0>Acel link nu pare să aparţină unui apel existent. Verificaţi dacă aţi introdus linkul corect, sau <1>creaţi unul nou.", + "connection_lost": "Conexiunea s-a pierdut", + "connection_lost_description": "Aţi fost deconectat/ă de la apel", + "e2ee_unsupported": "Navigatorul dumneavoastră este incompatibil cu criptarea integrală", + "e2ee_unsupported_description": "Navigatorul/browserul dumneavoastră web nu suportă apeluri în conversaţii cu criptare integrală. Printre navigatoarele suportate, se numără Chrome, Safari şi Firefox 117+.", + "generic": "A apărut o eroare neaşteptată", + "generic_description": "Dacă ne trimiteţi jurnalele de depanare generate de aplicaţie, ne puteţi ajuta să rezolvăm problema.", + "insufficient_capacity": "Capacitate insuficientă", + "insufficient_capacity_description": "Serverul a ajuns la capacitatea maximă și nu vă puteți alătura apelului în acest moment. Încercați din nou in câteva minute, sau contactați administratorul serverului dumneavoastră dacă problema persistă.", + "matrix_rtc_focus_missing": "Serverul nu este configurat să funcționeze cu{{brand}}. Vă rugăm să contactați administratorul serverului dumneavoastră pentru a raporta o eroare în configurare. Detalii: Domeniu: {{domain}}. Cod de eroare: {{ errorCode }}.", + "open_elsewhere": "Aplicaţia este deschisă intr-o altă pagină", + "open_elsewhere_description": "{{brand}} a fost deschis într-o altă pagină. Dacă credeți că acest mesaj a fost emis in eroare, încercați să reîncărcați pagina.", + "unexpected_ec_error": "A apărut o eroare neașteptată (Cod de <0> eroare: <1> {{ errorCode }}). Vă rugăm să contactați administratorul serverului dumneavoastră." }, - "disconnected_banner": "Conectivitatea la server a fost pierdută.", "group_call_loader": { "banned_body": "Ai fost interzis să ieși din cameră.", "banned_heading": "Interzis", @@ -135,6 +159,10 @@ "effect_volume_label": "Volumul efectului sonor" }, "developer_tab_title": "dezvoltator", + "devices": { + "microphone": "Microfon", + "speaker": "Difuzor" + }, "feedback_tab_body": "Dacă întâmpinați probleme sau pur și simplu doriți să oferiți feedback, vă rugăm să ne trimiteți o scurtă descriere mai jos.", "feedback_tab_description_label": "Feedback-ul tău", "feedback_tab_h4": "Trimiteți Feedback", @@ -143,6 +171,8 @@ "feedback_tab_title": "Feedback", "opt_in_description": "<0><1>Puteți retrage consimțământul debifând această casetă. Dacă sunteți în prezent la un apel, această setare va intra în vigoare la sfârșitul apelului.", "preferences_tab": { + "developer_mode_label": "Modul dezvoltator", + "developer_mode_label_description": "Activați modul dezvoltator și afișați pagina specifică setărilor pentru dezvoltatori", "introduction": "Aici puteți configura opțiuni suplimentare pentru o experiență îmbunătățită.", "reactions_play_sound_description": "Redați un efect sonor atunci când cineva trimite o reacție la un apel.", "reactions_play_sound_label": "Redați sunete de reacție", @@ -164,11 +194,13 @@ "version": "{{productName}}Versiune: {{version}}", "video_tile": { "always_show": "Arată întotdeauna", + "camera_starting": "Se încarcă fluxul video...", "change_fit_contain": "Se potrivește cadrului", "collapse": "colaps", "expand": "Extindeți", "mute_for_me": "Mute pentru mine", "muted_for_me": "Dezactivat pentru mine", - "volume": "VOLUM" + "volume": "VOLUM", + "waiting_for_media": "Flux multimedia în aşteptare" } } diff --git a/locales/ru/app.json b/locales/ru/app.json index cdfdfe80..b6ec8a6a 100644 --- a/locales/ru/app.json +++ b/locales/ru/app.json @@ -21,7 +21,7 @@ "submit": "Отправить", "upload_file": "Загрузить файл" }, - "analytics_notice": "Участвуя в этой бета-версии, вы соглашаетесь на сбор анонимных данных, которые мы используем для улучшения продукта. Более подробную информацию о том, какие данные мы отслеживаем, вы можете найти в нашей <2> Политике конфиденциальности и нашей <5> Политике использования файлов cookie.", + "analytics_notice": "Участвуя в этой бета-версии, вы соглашаетесь на сбор анонимных данных, которые мы используем для улучшения продукта. Дополнительную информацию о том, какие данные мы отслеживаем, можно найти в нашей <2> Политике конфиденциальности и Политике <6> использования файлов cookie.", "app_selection_modal": { "continue_in_browser": "Продолжить в браузере", "open_in_app": "Открыть в приложении", @@ -65,13 +65,16 @@ "debug_tile_layout_label": "Отладка расположения плиток", "device_id": "Идентификатор устройства: {{id}}", "duplicate_tiles_label": "Количество дополнительных копий плиток на участника", + "environment_variables": "Переменные окружения", "hostname": "Имя хоста: {{hostname}}", "livekit_server_info": "Информация о сервере LiveKit", "livekit_sfu": "LiveKit SFU: {{url}}", "matrix_id": "Matrix ID: {{id}}", "show_connection_stats": "Показать статистику подключений", "show_non_member_tiles": "Показать плитки для медиафайлов, не являющихся участниками", - "use_new_membership_manager": "Используйте новую реализацию вызова MembershipManager" + "url_params": "Параметры URL-адреса", + "use_new_membership_manager": "Используйте новую реализацию вызова MembershipManager", + "use_to_device_key_transport": "Используйте для передачи ключей устройства. Это позволит вернуться к передаче ключей комнаты, когда другой участник вызова отправит ключ комнаты" }, "disconnected_banner": "Связь с сервером была потеряна.", "error": { @@ -98,7 +101,7 @@ "call_ended_heading": "Вызов завершен", "knock_reject_body": "Участники комнаты отклонили ваш запрос на присоединение.", "knock_reject_heading": "Не разрешено присоединиться", - "reason": "Причина" + "reason": "Причина: {{reason}}" }, "hangup_button_label": "Завершить звонок", "header_label": "Главная Element Call", @@ -145,6 +148,7 @@ "rageshake_sent": "Спасибо!", "recaptcha_dismissed": "Проверка не пройдена", "recaptcha_not_loaded": "Невозможно начать проверку", + "recaptcha_ssla_caption": "Этот сайт защищен reCAPTCHA, и к нему применяются <2> Политика конфиденциальности и <6> Условия обслуживания Google. <9>Нажимая «Зарегистрироваться», вы соглашаетесь с нашим лицензионным соглашением на <12> программное обеспечение и услуги (SSLA) ", "register": { "passwords_must_match": "Пароли должны совпадать", "registering": "Регистрация…" @@ -154,12 +158,16 @@ "register_heading": "Создать учетную запись", "return_home_button": "Вернуться в Начало", "room_auth_view_continue_button": "Продолжить", + "room_auth_view_ssla_caption": "Нажимая кнопку \"Присоединиться к звонку\", вы соглашаетесь с нашим <2>Лицензионное соглашение на программное обеспечение и услуги (SSLA)", "screenshare_button_label": "Поделиться экраном", "settings": { "audio_tab": { "effect_volume_description": "Отрегулируйте громкость воспроизведения реакций и эффектов поднятия руки.", "effect_volume_label": "Громкость звукового эффекта" }, + "background_blur_header": "Фон", + "background_blur_label": "Размытие фона видео", + "blur_not_supported_by_browser": "(Размытие фона не поддерживается этим устройством.)", "developer_tab_title": "Разработчику", "devices": { "camera": "Камера", @@ -190,8 +198,9 @@ "show_hand_raised_timer_label": "Показать продолжительность поднятия руки" } }, - "star_rating_input_label_one": "{{count}} отмечен", - "star_rating_input_label_other": "{{count}} отмеченных", + "star_rating_input_label_one": "{{count}} звезда", + "star_rating_input_label_few": "{{count}} звезды", + "star_rating_input_label_many": "{{count}} звезд", "start_new_call": "Начать новый звонок", "start_video_button_label": "Начать видео", "stop_screenshare_button_label": "Демонстрация экрана", @@ -200,8 +209,9 @@ "switch_camera": "Переключить камеру", "unauthenticated_view_body": "Ещё не зарегистрированы? <2>Создайте аккаунт", "unauthenticated_view_login_button": "Войдите в свой аккаунт", + "unauthenticated_view_ssla_caption": "Нажимая «Перейти», вы соглашаетесь с нашим лицензионным соглашением на <2> программное обеспечение и услуги (SSLA) ", "unmute_microphone_button_label": "Включить микрофон", - "version": "Версия: {{version}}", + "version": "{{productName}} версия: {{version}}", "video_tile": { "always_show": "Показывать всегда", "camera_starting": "Загрузка видео...", diff --git a/locales/sk/app.json b/locales/sk/app.json index 0c320dfd..20e41408 100644 --- a/locales/sk/app.json +++ b/locales/sk/app.json @@ -21,7 +21,7 @@ "submit": "Odoslať", "upload_file": "Nahrať súbor" }, - "analytics_notice": "Účasťou v tejto beta verzii súhlasíte so zhromažďovaním anonymných údajov, ktoré použijeme na zlepšenie produktu. Viac informácií o tom, ktoré údaje sledujeme, nájdete v našich <2>Zásadách ochrany osobných údajov a <5>Zásadách používania súborov cookie.", + "analytics_notice": "Účasťou v tejto beta verzii súhlasíte so zhromažďovaním anonymných údajov, ktoré použijeme na zlepšenie produktu. Viac informácií o tom, ktoré údaje sledujeme, nájdete v našich <2>Zásadách ochrany osobných údajov a <6>Zásadách používania súborov cookie.", "app_selection_modal": { "continue_in_browser": "Pokračovať v prehliadači", "open_in_app": "Otvoriť v aplikácii", @@ -65,13 +65,17 @@ "debug_tile_layout_label": "Ladenie rozloženia dlaždíc", "device_id": "ID zariadenia: {{id}}", "duplicate_tiles_label": "Počet ďalších kópií dlaždíc na účastníka", + "environment_variables": "Premenné prostredia", "hostname": "Názov hostiteľa: {{hostname}}", "livekit_server_info": "Informácie o serveri LiveKit", "livekit_sfu": "LiveKit SFU: {{url}}", "matrix_id": "Matrix ID: {{id}}", + "mute_all_audio": "Stlmiť všetky zvuky (účastníkov, reakcií, zvuky pripojenia)", "show_connection_stats": "Zobraziť štatistiky pripojenia", "show_non_member_tiles": "Zobraziť dlaždice pre nečlenské médiá", - "use_new_membership_manager": "Použiť novú implementáciu hovoru MembershipManager" + "url_params": "Parametre URL adresy", + "use_new_membership_manager": "Použiť novú implementáciu hovoru MembershipManager", + "use_to_device_key_transport": "Používa sa na prenos kľúča zariadenia. Toto sa vráti k prenosu kľúča miestnosti, keď iný účastník hovoru poslal kľúč od miestnosti" }, "disconnected_banner": "Spojenie so serverom sa stratilo.", "error": { @@ -145,6 +149,7 @@ "rageshake_sent": "Ďakujeme!", "recaptcha_dismissed": "Recaptcha zamietnutá", "recaptcha_not_loaded": "Recaptcha sa nenačítala", + "recaptcha_ssla_caption": "Táto stránka je chránená reCAPTCHA a platia <2>Zásady ochrany osobných údajov a <6>Podmienky služby spoločnosti Google. <9>Kliknutím na tlačidlo „Registrovať“ súhlasíte s našou <12>Licenčnou zmluvou o softvéri a službách (SSLA)", "register": { "passwords_must_match": "Heslá sa musia zhodovať", "registering": "Registrácia…" @@ -154,12 +159,16 @@ "register_heading": "Vytvorte si účet", "return_home_button": "Návrat na domovskú obrazovku", "room_auth_view_continue_button": "Pokračovať", + "room_auth_view_ssla_caption": "Kliknutím na „Pripojiť sa k hovoru teraz“ súhlasíte s našou <2>Licenčnou zmluvou o softvéri a službách (SSLA)", "screenshare_button_label": "Zdieľať obrazovku", "settings": { "audio_tab": { "effect_volume_description": "Upraviť hlasitosť, pri ktorej sa prehrávajú reakcie a efekty zdvihnutia ruky.", "effect_volume_label": "Hlasitosť zvukového efektu" }, + "background_blur_header": "Pozadie", + "background_blur_label": "Rozmazať pozadie videa", + "blur_not_supported_by_browser": "(Rozmazanie pozadia nie je podporované týmto zariadením.)", "developer_tab_title": "Vývojár", "devices": { "camera": "Kamera", @@ -191,6 +200,7 @@ } }, "star_rating_input_label_one": "{{count}} hviezdička", + "star_rating_input_label_few": "{{count}} hviezdičky", "star_rating_input_label_other": "{{count}} hviezdičiek", "start_new_call": "Spustiť nový hovor", "start_video_button_label": "Spustiť video", @@ -200,8 +210,9 @@ "switch_camera": "Prepnúť fotoaparát", "unauthenticated_view_body": "Ešte nie ste zaregistrovaný? <2>Vytvorte si účet", "unauthenticated_view_login_button": "Prihláste sa do svojho konta", + "unauthenticated_view_ssla_caption": "Kliknutím na tlačidlo „Prejsť“ súhlasítes našou <2>Licenčnou zmluvou o softvéri a službách (SSLA)", "unmute_microphone_button_label": "Zrušiť stlmenie mikrofónu", - "version": "Verzia: {{version}}", + "version": "Verzia {{productName}}: {{version}}", "video_tile": { "always_show": "Vždy zobraziť", "camera_starting": "Načítavanie videa...", diff --git a/locales/sv/app.json b/locales/sv/app.json index efa3036b..500c4ee7 100644 --- a/locales/sv/app.json +++ b/locales/sv/app.json @@ -73,7 +73,8 @@ "show_connection_stats": "Visa anslutningsstatistik", "show_non_member_tiles": "Visa paneler för media som inte är medlemmar", "url_params": "URL-parametrar", - "use_new_membership_manager": "Använd den nya implementeringen av samtals-MembershipManager" + "use_new_membership_manager": "Använd den nya implementeringen av samtals-MembershipManager", + "use_to_device_key_transport": "Använd \"till enhet\"-nyckeltransport. Detta kommer att falla tillbaka till rumsnyckeltransport om en annan samtalsmedlem skickar en rumsnyckel." }, "disconnected_banner": "Anslutningen till servern har brutits.", "error": { diff --git a/locales/uk/app.json b/locales/uk/app.json index 717e8df3..d7d1b0ea 100644 --- a/locales/uk/app.json +++ b/locales/uk/app.json @@ -21,7 +21,7 @@ "submit": "Надіслати", "upload_file": "Завантажити файл" }, - "analytics_notice": "Користуючись дочасним доступом, ви даєте згоду на збір анонімних даних, які ми використовуємо для вдосконалення продукту. Ви можете знайти більше інформації про те, які дані ми відстежуємо в нашій <2>Політиці Приватності і нашій <5>Політиці про куки.", + "analytics_notice": "Користуючись дочасним доступом, ви даєте згоду на збір анонімних даних, які ми використовуємо для вдосконалення продукту. Ви можете знайти більше інформації про те, які дані ми відстежуємо в нашій <2>Політиці Приватності і нашій <6>Політиці про файли cookie.", "app_selection_modal": { "continue_in_browser": "Продовжити у браузері", "open_in_app": "Відкрити у застосунку", @@ -194,8 +194,9 @@ "show_hand_raised_timer_label": "Показувати тривалість підняття руки" } }, - "star_rating_input_label_one": "{{count}} зірок", - "star_rating_input_label_other": "{{count}} зірок", + "star_rating_input_label_one": "{{count}} зірка", + "star_rating_input_label_few": "{{count}} зірки", + "star_rating_input_label_many": "{{count}} зірок", "start_new_call": "Розпочати новий виклик", "start_video_button_label": "Розпочати відео", "stop_screenshare_button_label": "Презентація екрана", @@ -206,7 +207,7 @@ "unauthenticated_view_login_button": "Увійдіть до свого облікового запису", "unauthenticated_view_ssla_caption": "Натискаючи \"Перейти\", ви погоджуєтеся з нашою <2>Ліцензійною угодою на програмне забезпечення та послуги (SSLA) ", "unmute_microphone_button_label": "Увімкнути мікрофон", - "version": "Версія: {{version}}", + "version": "{{productName}} версія: {{version}}", "video_tile": { "always_show": "Показувати завжди", "camera_starting": "Завантаження відео...", diff --git a/locales/zh-Hans/app.json b/locales/zh-Hans/app.json index f2433e16..9c0e7c8f 100644 --- a/locales/zh-Hans/app.json +++ b/locales/zh-Hans/app.json @@ -4,7 +4,9 @@ }, "action": { "close": "关闭", + "copy_link": "复制链接", "go": "开始", + "invite": "邀请", "no": "否", "register": "注册", "remove": "移除", @@ -31,12 +33,14 @@ }, "call_name": "通话名称", "common": { + "analytics": "分析", "audio": "音频", "avatar": "头像", "display_name": "显示名称", "encrypted": "已加密", "home": "主页", "loading": "加载中……", + "options": "选项", "password": "密码", "profile": "个人信息", "settings": "设置", @@ -45,8 +49,20 @@ "video": "视频" }, "disconnected_banner": "与服务器的连接中断。", + "group_call_loader": { + "banned_body": "你已被房间封禁", + "banned_heading": "已被封禁", + "call_ended_body": "你已被移出通话", + "call_ended_heading": "通话结束", + "knock_reject_body": "房间成员拒绝了你的加入请求" + }, "hangup_button_label": "通话结束", "header_label": "Element Call主页", + "header_participants_label": "参与者", + "invite_modal": { + "link_copied_toast": "链接已复制到剪贴板", + "title": "邀请参加此次通话" + }, "join_existing_call_modal": { "join_button": "是,加入通话", "text": "该通话已存在,你想加入吗?", @@ -58,12 +74,16 @@ "join_button": "加入通话", "leave_button": "返回最近通话" }, + "log_in": "登录", "logging_in": "登录中……", "login_auth_links": "<0>创建账户 Or <2>以访客身份继续", + "login_auth_links_prompt": "还未注册?", + "login_subheading": "继续使用 Element", "login_title": "登录", "microphone_off": "麦克风关闭", "microphone_on": "麦克风开启", "mute_microphone_button_label": "静音麦克风", + "participant_count_other": "{{count, number}}", "rageshake_button_error_caption": "重传日志", "rageshake_request_modal": { "body": "这个通话中的另一个用户出现了问题。为了更好地诊断这些问题,我们想收集调试日志。", @@ -81,6 +101,7 @@ }, "register_auth_links": "<0>已有账户?<1><0>登录 Or <2>以访客身份继续", "register_confirm_password_label": "确认密码", + "register_heading": "创建您的账户", "return_home_button": "返回主页", "screenshare_button_label": "屏幕共享", "settings": { @@ -103,5 +124,10 @@ "unauthenticated_view_body": "还没有注册? <2>创建账户<2>", "unauthenticated_view_login_button": "登录你的账户", "unmute_microphone_button_label": "取消麦克风静音", - "version": "版本:{{version}}" + "version": "版本:{{version}}", + "video_tile": { + "change_fit_contain": "贴合框架", + "mute_for_me": "为我静音", + "volume": "音量" + } } diff --git a/package.json b/package.json index 7c2edc31..76d63cb0 100644 --- a/package.json +++ b/package.json @@ -39,15 +39,17 @@ "@formatjs/intl-segmenter": "^11.7.3", "@livekit/components-core": "^0.12.0", "@livekit/components-react": "^2.0.0", - "@livekit/protocol": "^1.33.0", + "@livekit/protocol": "^1.38.0", + "@livekit/track-processors": "^0.5.5", + "@mediapipe/tasks-vision": "^0.10.18", "@opentelemetry/api": "^1.4.0", - "@opentelemetry/core": "^1.25.1", - "@opentelemetry/exporter-trace-otlp-http": "^0.57.0", - "@opentelemetry/resources": "^1.25.1", - "@opentelemetry/sdk-trace-base": "^1.25.1", - "@opentelemetry/sdk-trace-web": "^1.9.1", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.201.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/sdk-trace-base": "^2.0.0", + "@opentelemetry/sdk-trace-web": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.25.1", - "@playwright/test": "^1.51.0", + "@playwright/test": "^1.52.0", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-slider": "^1.1.2", "@radix-ui/react-visually-hidden": "^1.0.3", @@ -60,6 +62,7 @@ "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.1", "@types/content-type": "^1.1.5", + "@types/dom-mediacapture-transform": "^0.1.11", "@types/grecaptcha": "^3.0.9", "@types/jsdom": "^21.1.7", "@types/lodash-es": "^4.17.12", @@ -70,12 +73,11 @@ "@types/react-dom": "^18.3.0", "@types/sdp-transform": "^2.4.5", "@types/uuid": "10", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", + "@typescript-eslint/eslint-plugin": "^8.31.0", + "@typescript-eslint/parser": "^8.31.0", "@use-gesture/react": "^10.2.11", "@vector-im/compound-design-tokens": "^3.0.0", "@vector-im/compound-web": "^7.2.0", - "@vitejs/plugin-basic-ssl": "^1.0.1", "@vitejs/plugin-react": "^4.0.1", "@vitest/coverage-v8": "^3.0.0", "babel-plugin-transform-vite-meta-env": "^1.0.3", @@ -86,7 +88,7 @@ "eslint-plugin-deprecate": "^0.8.2", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-matrix-org": "^2.0.0", + "eslint-plugin-matrix-org": "2.1.0", "eslint-plugin-react": "^7.29.4", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-rxjs": "^5.0.3", @@ -97,11 +99,11 @@ "i18next-parser": "^9.1.0", "jsdom": "^26.0.0", "knip": "^5.27.2", - "livekit-client": "2.11.2", + "livekit-client": "^2.13.0", "lodash-es": "^4.17.21", "loglevel": "^1.9.1", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#64e27f5d3cdab6aafeb7c22f1264416ffa72b83f", - "matrix-widget-api": "1.11.0", + "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#head=develop", + "matrix-widget-api": "^1.13.0", "normalize.css": "^8.0.1", "observable-hooks": "^4.2.3", "pako": "^2.0.4", @@ -118,12 +120,12 @@ "react-use-measure": "^2.1.1", "rxjs": "^7.8.1", "sass": "^1.42.1", - "typescript": "^5.1.6", + "typescript": "^5.8.3", "typescript-eslint-language-service": "^5.0.5", "unique-names-generator": "^4.6.0", "vaul": "^1.0.0", "vite": "^6.0.0", - "vite-plugin-generate-file": "^0.2.0", + "vite-plugin-generate-file": "^0.3.0", "vite-plugin-html": "^3.2.2", "vite-plugin-svgr": "^4.0.0", "vitest": "^3.0.0", @@ -131,7 +133,7 @@ }, "resolutions": { "@livekit/components-core/rxjs": "^7.8.1", - "matrix-widget-api": "1.11.0" + "@livekit/track-processors/@mediapipe/tasks-vision": "^0.10.18" }, "packageManager": "yarn@4.7.0" } diff --git a/playwright-backend-docker-compose.override.yml b/playwright-backend-docker-compose.override.yml new file mode 100644 index 00000000..dadbccc2 --- /dev/null +++ b/playwright-backend-docker-compose.override.yml @@ -0,0 +1,4 @@ +services: + synapse: + volumes: + - ./backend/playwright_homeserver.yaml:/data/cfg/homeserver.yaml:Z diff --git a/playwright-backend-docker-compose.yml b/playwright-backend-docker-compose.yml index e5cf12b5..bb6686d0 100644 --- a/playwright-backend-docker-compose.yml +++ b/playwright-backend-docker-compose.yml @@ -1,97 +1,2 @@ -networks: - ecbackend: - -services: - auth-service: - image: ghcr.io/element-hq/lk-jwt-service:latest-ci - hostname: auth-server - environment: - - LK_JWT_PORT=8080 - - LIVEKIT_URL=ws://localhost:7880 - - LIVEKIT_KEY=devkey - - LIVEKIT_SECRET=secret - # If the configured homeserver runs on localhost, it'll probably be using - # a self-signed certificate - - LIVEKIT_INSECURE_SKIP_VERIFY_TLS=YES_I_KNOW_WHAT_I_AM_DOING - deploy: - restart_policy: - condition: on-failure - ports: - # HOST_PORT:CONTAINER_PORT - - 8009:8080 - networks: - - ecbackend - - livekit: - image: livekit/livekit-server:latest - command: --dev --config /etc/livekit.yaml - restart: unless-stopped - # The SFU seems to work far more reliably when we let it share the host - # network rather than opening specific ports (but why?? we're not missing - # any…) - ports: - # HOST_PORT:CONTAINER_PORT - - 7880:7880/tcp - - 7881:7881/tcp - - 7882:7882/tcp - - 50100-50200:50100-50200/udp - volumes: - - ./backend/dev_livekit.yaml:/etc/livekit.yaml:Z - networks: - - ecbackend - - redis: - image: redis:6-alpine - command: redis-server /etc/redis.conf - ports: - # HOST_PORT:CONTAINER_PORT - - 6379:6379 - volumes: - - ./backend/redis.conf:/etc/redis.conf:Z - networks: - - ecbackend - - element-web: - image: ghcr.io/element-hq/element-web:develop - volumes: - - ./backend/ew.test.config.json:/app/config.json - environment: - ELEMENT_WEB_PORT: 81 - ports: - - "8081:81" - networks: - - ecbackend - - synapse: - hostname: homeserver - image: docker.io/matrixdotorg/synapse:latest - environment: - - SYNAPSE_CONFIG_PATH=/data/cfg/homeserver.yaml - # Needed for rootless podman-compose such that the uid/gid mapping does - # fit local user uid. If the container runs as root (uid 0) it is fine as - # it actually maps to your non-root user on the host (e.g. 1000). - # Otherwise uid mapping will not match your non-root user. - - UID=0 - - GID=0 - volumes: - - ./backend/synapse_tmp:/data:Z - - ./backend/playwright_homeserver.yaml:/data/cfg/homeserver.yaml:Z - networks: - - ecbackend - - nginx: - # openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls_localhost_key.pem -out tls_localhost_cert.pem -subj "/C=GB/ST=London/L=London/O=Alros/OU=IT Department/CN=localhost" - hostname: synapse.localhost - image: nginx:latest - volumes: - - ./backend/tls_localhost_nginx.conf:/etc/nginx/conf.d/default.conf:Z - - ./backend/tls_localhost_key.pem:/root/ssl/key.pem:Z - - ./backend/tls_localhost_cert.pem:/root/ssl/cert.pem:Z - ports: - # HOST_PORT:CONTAINER_PORT - - "8008:80" - - "4443:443" - depends_on: - - synapse - networks: - - ecbackend +include: + - dev-backend-docker-compose.yml diff --git a/playwright/access.spec.ts b/playwright/access.spec.ts index 14a70873..da7ec364 100644 --- a/playwright/access.spec.ts +++ b/playwright/access.spec.ts @@ -49,7 +49,7 @@ test("Sign up a new account, then login, then logout", async ({ browser }) => { // logout await returningUserPage.getByTestId("usermenu_open").click(); - await returningUserPage.locator('[data-test-id="usermenu_logout"]').click(); + await returningUserPage.locator('[data-testid="usermenu_logout"]').click(); await expect( returningUserPage.getByRole("link", { name: "Log In" }), diff --git a/playwright/fixtures/widget-user.ts b/playwright/fixtures/widget-user.ts index 0a422d20..d1412bd8 100644 --- a/playwright/fixtures/widget-user.ts +++ b/playwright/fixtures/widget-user.ts @@ -154,8 +154,13 @@ export const widgetTest = test.extend({ ewPage1.getByRole("heading", { name: "Invite to Welcome Room" }), ).toBeVisible(); - await ewPage1.getByRole("textbox").fill(whistlerMxId); - await ewPage1.getByRole("textbox").click(); + // To get the invite textbox we need to specifically select within the + // dialog, since there is another textbox in the background (the message + // composer). In theory the composer shouldn't be visible to Playwright at + // all because the invite dialog has trapped focus, but the focus trap + // doesn't quite work right on Firefox. + await ewPage1.getByRole("dialog").getByRole("textbox").fill(whistlerMxId); + await ewPage1.getByRole("dialog").getByRole("textbox").click(); await ewPage1.getByRole("button", { name: "Invite" }).click(); // Accept the invite diff --git a/src/App.tsx b/src/App.tsx index 549a98f2..5dc8d29c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,6 +22,7 @@ import { Initializer } from "./initializer"; import { MediaDevicesProvider } from "./livekit/MediaDevicesContext"; import { widget } from "./widget"; import { useTheme } from "./useTheme"; +import { ProcessorProvider } from "./livekit/TrackProcessorContext"; const SentryRoute = Sentry.withSentryReactRouterV7Routing(Route); @@ -72,22 +73,24 @@ export const App: FC = () => { - ( - - )} - > - - - } /> - } /> - } - /> - } /> - - + + ( + + )} + > + + + } /> + } /> + } + /> + } /> + + + diff --git a/src/UrlParams.ts b/src/UrlParams.ts index fce95445..17e169d9 100644 --- a/src/UrlParams.ts +++ b/src/UrlParams.ts @@ -124,9 +124,15 @@ export interface UrlParams { */ password: string | null; /** - * Whether we the app should use per participant keys for E2EE. + * Whether the app should use per participant keys for E2EE. */ perParticipantE2EE: boolean; + /** + * Whether the global JS controls for audio output devices should be enabled, + * allowing the list of output devices to be controlled by the app hosting + * Element Call. + */ + controlledAudioDevices: boolean; /** * Setting this flag skips the lobby and brings you in the call directly. * In the widget this can be combined with preload to pass the device settings @@ -173,6 +179,7 @@ export interface UrlParams { * The Sentry DSN. This is only used in the embedded package of Element Call. */ sentryDsn: string | null; + /** * The Sentry environment. This is only used in the embedded package of Element Call. */ @@ -281,6 +288,11 @@ export const getUrlParams = ( fontScale: Number.isNaN(fontScale) ? null : fontScale, allowIceFallback: parser.getFlagParam("allowIceFallback"), perParticipantE2EE: parser.getFlagParam("perParticipantE2EE"), + controlledAudioDevices: parser.getFlagParam( + "controlledAudioDevices", + // the deprecated property name + parser.getFlagParam("controlledMediaDevices"), + ), skipLobby: parser.getFlagParam( "skipLobby", isWidget && intent === UserIntent.StartNewCall, diff --git a/src/UserMenu.tsx b/src/UserMenu.tsx index 52cc4a5a..e431c328 100644 --- a/src/UserMenu.tsx +++ b/src/UserMenu.tsx @@ -119,7 +119,7 @@ export const UserMenu: FC = ({ key={key} Icon={Icon} label={label} - data-test-id={dataTestid} + data-testid={dataTestid} onSelect={() => onAction(key)} /> ))} diff --git a/src/analytics/RageshakeSpanProcessor.ts b/src/analytics/RageshakeSpanProcessor.ts index 97b6eebe..eca657db 100644 --- a/src/analytics/RageshakeSpanProcessor.ts +++ b/src/analytics/RageshakeSpanProcessor.ts @@ -107,13 +107,13 @@ export class RageshakeSpanProcessor implements SpanProcessor { startTime, duration, references: - span.parentSpanId === undefined + span.parentSpanContext?.spanId === undefined ? [] : [ { refType: "CHILD_OF", traceID: traceId, - spanID: span.parentSpanId, + spanID: span.parentSpanContext?.spanId, }, ], tags: dumpAttributes(span.attributes), diff --git a/src/controls.ts b/src/controls.ts index b708c9be..320f41ca 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -5,15 +5,55 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { Subject } from "rxjs"; +import { BehaviorSubject, Subject } from "rxjs"; export interface Controls { - canEnterPip: () => boolean; - enablePip: () => void; - disablePip: () => void; + canEnterPip(): boolean; + enablePip(): void; + disablePip(): void; + /** @deprecated use setAvailableAudioDevices instead*/ + setAvailableOutputDevices(devices: OutputDevice[]): void; + setAvailableAudioDevices(devices: OutputDevice[]): void; + /** @deprecated use setAudioDevice instead*/ + setOutputDevice(id: string): void; + setAudioDevice(id: string): void; + /** @deprecated use onAudioDeviceSelect instead*/ + onOutputDeviceSelect?: (id: string) => void; + onAudioDeviceSelect?: (id: string) => void; + /** @deprecated use setAudioEnabled instead*/ + setOutputEnabled(enabled: boolean): void; + setAudioEnabled(enabled: boolean): void; + /** @deprecated use showNativeAudioDevicePicker instead*/ + showNativeOutputDevicePicker?: () => void; + showNativeAudioDevicePicker?: () => void; } +export interface OutputDevice { + id: string; + name: string; + forEarpiece?: boolean; + isEarpiece?: boolean; + isSpeaker?: boolean; + isExternalHeadset?: boolean; +} + +/** + * If pipMode is enabled, EC will render a adapted call view layout. + */ export const setPipEnabled$ = new Subject(); +// BehaviorSubject since the client might set this before we have subscribed (GroupCallView still in "loading" state) +// We want the devices that have been set during loading to be available immediately once loaded. +export const availableOutputDevices$ = new BehaviorSubject([]); +// BehaviorSubject since the client might set this before we have subscribed (GroupCallView still in "loading" state) +// We want the device that has been set during loading to be available immediately once loaded. +export const outputDevice$ = new BehaviorSubject(undefined); +/** + * This allows the os to mute the call if the user + * presses the volume down button when it is at the minimum volume. + * + * This should also be used to display a darkened overlay screen letting the user know that audio is muted. + */ +export const setAudioEnabled$ = new Subject(); window.controls = { canEnterPip(): boolean { @@ -27,4 +67,28 @@ window.controls = { if (!setPipEnabled$.observed) throw new Error("No call is running"); setPipEnabled$.next(false); }, + setAvailableAudioDevices(devices: OutputDevice[]): void { + availableOutputDevices$.next(devices); + }, + setAudioDevice(id: string): void { + outputDevice$.next(id); + }, + setAudioEnabled(enabled: boolean): void { + if (!setAudioEnabled$.observed) + throw new Error( + "Output controls are disabled. No setAudioEnabled$ observer", + ); + setAudioEnabled$.next(enabled); + }, + + // wrappers for the deprecated controls fields + setOutputEnabled(enabled: boolean): void { + this.setAudioEnabled(enabled); + }, + setAvailableOutputDevices(devices: OutputDevice[]): void { + this.setAvailableAudioDevices(devices); + }, + setOutputDevice(id: string): void { + this.setAudioDevice(id); + }, }; diff --git a/src/e2ee/matrixKeyProvider.ts b/src/e2ee/matrixKeyProvider.ts index c5f6c879..95033f87 100644 --- a/src/e2ee/matrixKeyProvider.ts +++ b/src/e2ee/matrixKeyProvider.ts @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { BaseKeyProvider, createKeyMaterialFromBuffer } from "livekit-client"; +import { BaseKeyProvider } from "livekit-client"; import { logger } from "matrix-js-sdk/lib/logger"; import { type MatrixRTCSession, @@ -16,7 +16,7 @@ export class MatrixKeyProvider extends BaseKeyProvider { private rtcSession?: MatrixRTCSession; public constructor() { - super({ ratchetWindowSize: 0, keyringSize: 256 }); + super({ ratchetWindowSize: 10, keyringSize: 256 }); } public setRTCSession(rtcSession: MatrixRTCSession): void { @@ -44,20 +44,29 @@ export class MatrixKeyProvider extends BaseKeyProvider { encryptionKeyIndex: number, participantId: string, ): void => { - createKeyMaterialFromBuffer(encryptionKey).then( - (keyMaterial) => { - this.onSetEncryptionKey(keyMaterial, participantId, encryptionKeyIndex); + crypto.subtle + .importKey("raw", encryptionKey, "HKDF", false, [ + "deriveBits", + "deriveKey", + ]) + .then( + (keyMaterial) => { + this.onSetEncryptionKey( + keyMaterial, + participantId, + encryptionKeyIndex, + ); - logger.debug( - `Sent new key to livekit room=${this.rtcSession?.room.roomId} participantId=${participantId} encryptionKeyIndex=${encryptionKeyIndex}`, - ); - }, - (e) => { - logger.error( - `Failed to create key material from buffer for livekit room=${this.rtcSession?.room.roomId} participantId=${participantId} encryptionKeyIndex=${encryptionKeyIndex}`, - e, - ); - }, - ); + logger.debug( + `Sent new key to livekit room=${this.rtcSession?.room.roomId} participantId=${participantId} encryptionKeyIndex=${encryptionKeyIndex}`, + ); + }, + (e) => { + logger.error( + `Failed to create key material from buffer for livekit room=${this.rtcSession?.room.roomId} participantId=${participantId} encryptionKeyIndex=${encryptionKeyIndex}`, + e, + ); + }, + ); }; } diff --git a/src/e2ee/sharedKeyManagement.ts b/src/e2ee/sharedKeyManagement.ts index a3fa1ecc..3aa50b98 100644 --- a/src/e2ee/sharedKeyManagement.ts +++ b/src/e2ee/sharedKeyManagement.ts @@ -21,7 +21,7 @@ const getRoomSharedKeyLocalStorageKey = (roomId: string): string => const useInternalRoomSharedKey = (roomId: string): string | null => { const key = getRoomSharedKeyLocalStorageKey(roomId); - const roomSharedKey = useLocalStorage(key)[0]; + const [roomSharedKey] = useLocalStorage(key); return roomSharedKey; }; diff --git a/src/initializer.tsx b/src/initializer.tsx index 1087dc94..d0797e9d 100644 --- a/src/initializer.tsx +++ b/src/initializer.tsx @@ -136,6 +136,11 @@ export class Initializer { lookup: () => getUrlParams().lang ?? undefined, }); + // Synchronise the HTML lang attribute with the i18next language + i18n.on("languageChanged", (lng) => { + document.documentElement.lang = lng; + }); + await i18n .use(Backend) .use(languageDetector) diff --git a/src/livekit/BlurBackgroundTransformer.ts b/src/livekit/BlurBackgroundTransformer.ts new file mode 100644 index 00000000..72256fe1 --- /dev/null +++ b/src/livekit/BlurBackgroundTransformer.ts @@ -0,0 +1,80 @@ +/* +Copyright 2024-2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only +Please see LICENSE in the repository root for full details. +*/ + +import { + BackgroundTransformer, + VideoTransformer, + type VideoTransformerInitOptions, +} from "@livekit/track-processors"; +import { ImageSegmenter } from "@mediapipe/tasks-vision"; + +import modelAssetPath from "../mediapipe/imageSegmenter/selfie_segmenter.tflite?url"; + +interface WasmFileset { + /** The path to the Wasm loader script. */ + wasmLoaderPath: string; + /** The path to the Wasm binary. */ + wasmBinaryPath: string; +} + +// The MediaPipe package, by default, ships some alternative versions of the +// WASM files which avoid SIMD for compatibility with older browsers. But SIMD +// in WASM is actually fine by our support policy, so we include just the SIMD +// versions. +// It's really not ideal that we have to reference these internal files from +// MediaPipe and depend on node_modules having this specific structure. It's +// easy to see this breaking if our dependencies changed and MediaPipe were +// no longer hoisted, or if we switched to another dependency loader such as +// Yarn PnP. +// https://github.com/google-ai-edge/mediapipe/issues/5961 +const wasmFileset: WasmFileset = { + wasmLoaderPath: new URL( + "../../node_modules/@mediapipe/tasks-vision/wasm/vision_wasm_internal.js", + import.meta.url, + ).href, + wasmBinaryPath: new URL( + "../../node_modules/@mediapipe/tasks-vision/wasm/vision_wasm_internal.wasm", + import.meta.url, + ).href, +}; + +/** + * Track processor that applies effects such as blurring to a user's background. + * + * This is just like LiveKit's prebuilt BackgroundTransformer except that it + * loads the segmentation models from our own bundle rather than as an external + * resource fetched from the public internet. + */ +export class BlurBackgroundTransformer extends BackgroundTransformer { + public async init({ + outputCanvas, + inputElement: inputVideo, + }: VideoTransformerInitOptions): Promise { + // Call super.super.init() since we're totally replacing the init method of + // BackgroundTransformer here, rather than extending it + await VideoTransformer.prototype.init.call(this, { + outputCanvas, + inputElement: inputVideo, + }); + + this.imageSegmenter = await ImageSegmenter.createFromOptions(wasmFileset, { + baseOptions: { + modelAssetPath, + delegate: "GPU", + ...this.options.segmenterOptions, + }, + canvas: this.canvas, + runningMode: "VIDEO", + outputCategoryMask: true, + outputConfidenceMasks: false, + }); + + if (this.options.blurRadius) { + this.gl?.setBlurRadius(this.options.blurRadius); + } + } +} diff --git a/src/livekit/MatrixAudioRenderer.test.tsx b/src/livekit/MatrixAudioRenderer.test.tsx new file mode 100644 index 00000000..637e02ed --- /dev/null +++ b/src/livekit/MatrixAudioRenderer.test.tsx @@ -0,0 +1,104 @@ +/* +Copyright 2023, 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE in the repository root for full details. +*/ + +import { afterEach, beforeEach, expect, it, vi } from "vitest"; +import { render } from "@testing-library/react"; +import { type CallMembership } from "matrix-js-sdk/lib/matrixrtc"; +import { + getTrackReferenceId, + type TrackReference, +} from "@livekit/components-core"; +import { type RemoteAudioTrack } from "livekit-client"; +import { type ReactNode } from "react"; +import { useTracks } from "@livekit/components-react"; + +import { testAudioContext } from "../useAudioContext.test"; +import * as MediaDevicesContext from "./MediaDevicesContext"; +import { MatrixAudioRenderer } from "./MatrixAudioRenderer"; +import { mockTrack } from "../utils/test"; + +export const TestAudioContextConstructor = vi.fn(() => testAudioContext); + +beforeEach(() => { + vi.stubGlobal("AudioContext", TestAudioContextConstructor); +}); + +afterEach(() => { + vi.unstubAllGlobals(); + vi.clearAllMocks(); +}); + +vi.mock("@livekit/components-react", async (importOriginal) => { + return { + ...(await importOriginal()), + AudioTrack: (props: { trackRef: TrackReference }): ReactNode => { + return ( + + ); + }, + useTracks: vi.fn(), + }; +}); + +const tracks = [mockTrack("test:123")]; +vi.mocked(useTracks).mockReturnValue(tracks); + +it("should render for member", () => { + const { container, queryAllByTestId } = render( + , + ); + expect(container).toBeTruthy(); + expect(queryAllByTestId("audio")).toHaveLength(1); +}); +it("should not render without member", () => { + const { container, queryAllByTestId } = render( + , + ); + expect(container).toBeTruthy(); + expect(queryAllByTestId("audio")).toHaveLength(0); +}); + +it("should not setup audioContext gain and pan if there is no need to.", () => { + render( + , + ); + const audioTrack = tracks[0].publication.track! as RemoteAudioTrack; + + expect(audioTrack.setAudioContext).toHaveBeenCalledTimes(1); + expect(audioTrack.setAudioContext).toHaveBeenCalledWith(undefined); + expect(audioTrack.setWebAudioPlugins).toHaveBeenCalledTimes(1); + expect(audioTrack.setWebAudioPlugins).toHaveBeenCalledWith([]); + + expect(testAudioContext.gain.gain.value).toEqual(1); + expect(testAudioContext.pan.pan.value).toEqual(0); +}); +it("should setup audioContext gain and pan", () => { + vi.spyOn(MediaDevicesContext, "useEarpieceAudioConfig").mockReturnValue({ + pan: 1, + volume: 0.1, + }); + render( + , + ); + + const audioTrack = tracks[0].publication.track! as RemoteAudioTrack; + expect(audioTrack.setAudioContext).toHaveBeenCalled(); + expect(audioTrack.setWebAudioPlugins).toHaveBeenCalled(); + + expect(testAudioContext.gain.gain.value).toEqual(0.1); + expect(testAudioContext.pan.pan.value).toEqual(1); +}); diff --git a/src/livekit/MatrixAudioRenderer.tsx b/src/livekit/MatrixAudioRenderer.tsx new file mode 100644 index 00000000..18f09106 --- /dev/null +++ b/src/livekit/MatrixAudioRenderer.tsx @@ -0,0 +1,212 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE in the repository root for full details. +*/ + +import { getTrackReferenceId } from "@livekit/components-core"; +import { type RemoteAudioTrack, Track } from "livekit-client"; +import { useEffect, useMemo, useRef, useState, type ReactNode } from "react"; +import { + useTracks, + AudioTrack, + type AudioTrackProps, +} from "@livekit/components-react"; +import { type CallMembership } from "matrix-js-sdk/lib/matrixrtc"; +import { logger } from "matrix-js-sdk/lib/logger"; + +import { useEarpieceAudioConfig } from "./MediaDevicesContext"; +import { useReactiveState } from "../useReactiveState"; + +export interface MatrixAudioRendererProps { + /** + * The list of participants to render audio for. + * This list needs to be composed based on the matrixRTC members so that we do not play audio from users + * that are not expected to be in the rtc session. + */ + members: CallMembership[]; + /** + * If set to `true`, mutes all audio tracks rendered by the component. + * @remarks + * If set to `true`, the server will stop sending audio track data to the client. + */ + muted?: boolean; +} + +/** + * The `MatrixAudioRenderer` component is a drop-in solution for adding audio to your LiveKit app. + * It takes care of handling remote participants’ audio tracks and makes sure that microphones and screen share are audible. + * + * It also takes care of the earpiece audio configuration for iOS devices. + * This is done by using the WebAudio API to create a stereo pan effect that mimics the earpiece audio. + * @example + * ```tsx + * + * + * + * ``` + * @public + */ +export function MatrixAudioRenderer({ + members, + muted, +}: MatrixAudioRendererProps): ReactNode { + const validIdentities = useMemo( + () => + new Set(members?.map((member) => `${member.sender}:${member.deviceId}`)), + [members], + ); + + const loggedInvalidIdentities = useRef(new Set()); + /** + * Log an invalid livekit track identity. + * A invalid identity is one that does not match any of the matrix rtc members. + * + * @param identity The identity of the track that is invalid + * @param validIdentities The list of valid identities + */ + const logInvalid = (identity: string, validIdentities: Set): void => { + if (loggedInvalidIdentities.current.has(identity)) return; + logger.warn( + `Audio track ${identity} has no matching matrix call member`, + `current members: ${Array.from(validIdentities.values())}`, + `track will not get rendered`, + ); + loggedInvalidIdentities.current.add(identity); + }; + + const tracks = useTracks( + [ + Track.Source.Microphone, + Track.Source.ScreenShareAudio, + Track.Source.Unknown, + ], + { + updateOnlyOn: [], + onlySubscribed: true, + }, + ).filter((ref) => { + const isValid = validIdentities?.has(ref.participant.identity); + if (!isValid && !ref.participant.isLocal) + logInvalid(ref.participant.identity, validIdentities); + return ( + !ref.participant.isLocal && + ref.publication.kind === Track.Kind.Audio && + isValid + ); + }); + + // This component is also (in addition to the "only play audio for connected members" logic above) + // responsible for mimicking earpiece audio on iPhones. + // The Safari audio devices enumeration does not expose an earpiece audio device. + // We alternatively use the audioContext pan node to only use one of the stereo channels. + + // This component does get additionally complicated because of a Safari bug. + // (see: https://bugs.webkit.org/show_bug.cgi?id=251532 + // and the related issues: https://bugs.webkit.org/show_bug.cgi?id=237878 + // and https://bugs.webkit.org/show_bug.cgi?id=231105) + // + // AudioContext gets stopped if the webview gets moved into the background. + // Once the phone is in standby audio playback will stop. + // So we can only use the pan trick only works is the phone is not in standby. + // If earpiece mode is not used we do not use audioContext to allow standby playback. + // shouldUseAudioContext is set to false if stereoPan === 0 to allow standby bluetooth playback. + + const { pan: stereoPan, volume: volumeFactor } = useEarpieceAudioConfig(); + const shouldUseAudioContext = stereoPan !== 0; + + // initialize the potentially used audio context. + const [audioContext, setAudioContext] = useState( + undefined, + ); + useEffect(() => { + const ctx = new AudioContext(); + setAudioContext(ctx); + return (): void => { + void ctx.close(); + }; + }, []); + const audioNodes = useMemo( + () => ({ + gain: audioContext?.createGain(), + pan: audioContext?.createStereoPanner(), + }), + [audioContext], + ); + + // Simple effects to update the gain and pan node based on the props + useEffect(() => { + if (audioNodes.pan) audioNodes.pan.pan.value = stereoPan; + }, [audioNodes.pan, stereoPan]); + useEffect(() => { + if (audioNodes.gain) audioNodes.gain.gain.value = volumeFactor; + }, [audioNodes.gain, volumeFactor]); + + return ( + // We add all audio elements into one
for the browser developer tool experience/tidyness. +
+ {tracks.map((trackRef) => ( + + ))} +
+ ); +} + +interface StereoPanAudioTrackProps { + muted?: boolean; + audioContext?: AudioContext; + audioNodes: { + gain?: GainNode; + pan?: StereoPannerNode; + }; +} + +/** + * This wraps `livekit.AudioTrack` to allow adding audio nodes to a track. + * It main purpose is to remount the AudioTrack component when switching from + * audiooContext to normal audio playback. + * As of now the AudioTrack component does not support adding audio nodes while being mounted. + * @param param0 + * @returns + */ +function AudioTrackWithAudioNodes({ + trackRef, + muted, + audioContext, + audioNodes, + ...props +}: StereoPanAudioTrackProps & + AudioTrackProps & + React.RefAttributes): ReactNode { + // This is used to unmount/remount the AudioTrack component. + // Mounting needs to happen after the audioContext is set. + // (adding the audio context when already mounted did not work outside strict mode) + const [trackReady, setTrackReady] = useReactiveState( + () => false, + // We only want the track to reset once both (audioNodes and audioContext) are set. + // for unsetting the audioContext its enough if one of the the is undefined. + [audioContext && audioNodes], + ); + + useEffect(() => { + if (!trackRef || trackReady) return; + const track = trackRef.publication.track as RemoteAudioTrack; + const useContext = audioContext && audioNodes.gain && audioNodes.pan; + track.setAudioContext(useContext ? audioContext : undefined); + track.setWebAudioPlugins( + useContext ? [audioNodes.gain!, audioNodes.pan!] : [], + ); + setTrackReady(true); + }, [audioContext, audioNodes, setTrackReady, trackReady, trackRef]); + + return ( + trackReady && + ); +} diff --git a/src/livekit/MediaDevicesContext.tsx b/src/livekit/MediaDevicesContext.tsx index c2fc63e5..636f5a6d 100644 --- a/src/livekit/MediaDevicesContext.tsx +++ b/src/livekit/MediaDevicesContext.tsx @@ -1,5 +1,5 @@ /* -Copyright 2023, 2024 New Vector Ltd. +Copyright 2023-2025 New Vector Ltd. SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. @@ -17,8 +17,8 @@ import { type JSX, } from "react"; import { createMediaDeviceObserver } from "@livekit/components-core"; -import { map, startWith } from "rxjs"; -import { useObservableEagerState } from "observable-hooks"; +import { combineLatest, map, startWith } from "rxjs"; +import { useObservable, useObservableEagerState } from "observable-hooks"; import { logger } from "matrix-js-sdk/lib/logger"; import { @@ -26,20 +26,33 @@ import { audioInput as audioInputSetting, audioOutput as audioOutputSetting, videoInput as videoInputSetting, + alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting, type Setting, } from "../settings/settings"; +import { outputDevice$, availableOutputDevices$ } from "../controls"; +import { useUrlParams } from "../UrlParams"; + +// This hardcoded id is used in EX ios! It can only be changed in coordination with +// the ios swift team. +export const EARPIECE_CONFIG_ID = "earpiece-id"; export type DeviceLabel = | { type: "name"; name: string } | { type: "number"; number: number } + | { type: "earpiece" } | { type: "default"; name: string | null }; -export interface MediaDevice { +export interface MediaDeviceHandle { /** * A map from available device IDs to labels. */ available: Map; selectedId: string | undefined; + /** + * An additional device configuration that makes us use only one channel of the + * output device and a reduced volume. + */ + useAsEarpiece: boolean | undefined; /** * The group ID of the selected device. */ @@ -50,23 +63,69 @@ export interface MediaDevice { select: (deviceId: string) => void; } -export interface MediaDevices { - audioInput: MediaDevice; - audioOutput: MediaDevice; - videoInput: MediaDevice; +interface InputDevices { + audioInput: MediaDeviceHandle; + videoInput: MediaDeviceHandle; startUsingDeviceNames: () => void; stopUsingDeviceNames: () => void; + usingNames: boolean; } -function useMediaDevice( +export interface MediaDevices extends Omit { + audioOutput: MediaDeviceHandle; +} + +/** + * An observable that represents if we should display the devices menu for iOS. + * This implies the following + * - hide any input devices (they do not work anyhow on ios) + * - Show a button to show the native output picker instead. + * - Only show the earpiece toggle option if the earpiece is available: + * `availableOutputDevices$.includes((d)=>d.forEarpiece)` + */ +export const iosDeviceMenu$ = alwaysShowIphoneEarpieceSetting.value$.pipe( + map((v) => v || navigator.userAgent.includes("iPhone")), +); + +function useSelectedId( + available: Map, + preferredId: string | undefined, +): string | undefined { + return useMemo(() => { + if (available.size) { + // If the preferred device is available, use it. Or if every available + // device ID is falsy, the browser is probably just being paranoid about + // fingerprinting and we should still try using the preferred device. + // Worst case it is not available and the browser will gracefully fall + // back to some other device for us when requesting the media stream. + // Otherwise, select the first available device. + return (preferredId !== undefined && available.has(preferredId)) || + (available.size === 1 && available.has("")) + ? preferredId + : available.keys().next().value; + } + return undefined; + }, [available, preferredId]); +} + +/** + * Hook to get access to a mediaDevice handle for a kind. This allows to list + * the available devices, read and set the selected device. + * @param kind Audio input, output or video output. + * @param setting The setting this handle's selection should be synced with. + * @param usingNames If the hook should query device names for the associated + * list. + * @returns A handle for the chosen kind. + */ +function useMediaDeviceHandle( kind: MediaDeviceKind, setting: Setting, usingNames: boolean, -): MediaDevice { - // Make sure we don't needlessly reset to a device observer without names, - // once permissions are already given +): MediaDeviceHandle { const hasRequestedPermissions = useRef(false); const requestPermissions = usingNames || hasRequestedPermissions.current; + // Make sure we don't needlessly reset to a device observer without names, + // once permissions are already given hasRequestedPermissions.current ||= usingNames; // We use a bare device observer here rather than one of the fancy device @@ -102,11 +161,13 @@ function useMediaDevice( // Create a virtual default audio output for browsers that don't have one. // Its device ID must be the empty string because that's what setSinkId // recognizes. + // We also create this if we do not have any available devices, so that + // we can use the default or the earpiece. if ( kind === "audiooutput" && - available.size && !available.has("") && - !available.has("default") + !available.has("default") && + available.size ) available = new Map([ ["", { type: "default", name: availableRaw[0]?.label || null }], @@ -118,26 +179,13 @@ function useMediaDevice( return available; }), ), - [kind, deviceObserver$], + [deviceObserver$, kind], ), ); const [preferredId, select] = useSetting(setting); - const selectedId = useMemo(() => { - if (available.size) { - // If the preferred device is available, use it. Or if every available - // device ID is falsy, the browser is probably just being paranoid about - // fingerprinting and we should still try using the preferred device. - // Worst case it is not available and the browser will gracefully fall - // back to some other device for us when requesting the media stream. - // Otherwise, select the first available device. - return (preferredId !== undefined && available.has(preferredId)) || - (available.size === 1 && available.has("")) - ? preferredId - : available.keys().next().value; - } - return undefined; - }, [available, preferredId]); + const selectedId = useSelectedId(available, preferredId); + const selectedGroupId = useObservableEagerState( useMemo( () => @@ -155,6 +203,7 @@ function useMediaDevice( () => ({ available, selectedId, + useAsEarpiece: false, selectedGroupId, select, }), @@ -162,12 +211,14 @@ function useMediaDevice( ); } -export const deviceStub: MediaDevice = { +export const deviceStub: MediaDeviceHandle = { available: new Map(), selectedId: undefined, selectedGroupId: undefined, select: () => {}, + useAsEarpiece: false, }; + export const devicesStub: MediaDevices = { audioInput: deviceStub, audioOutput: deviceStub, @@ -178,26 +229,17 @@ export const devicesStub: MediaDevices = { export const MediaDevicesContext = createContext(devicesStub); -interface Props { - children: JSX.Element; -} - -export const MediaDevicesProvider: FC = ({ children }) => { +function useInputDevices(): InputDevices { // Counts the number of callers currently using device names. const [numCallersUsingNames, setNumCallersUsingNames] = useState(0); const usingNames = numCallersUsingNames > 0; - const audioInput = useMediaDevice( + const audioInput = useMediaDeviceHandle( "audioinput", audioInputSetting, usingNames, ); - const audioOutput = useMediaDevice( - "audiooutput", - audioOutputSetting, - usingNames, - ); - const videoInput = useMediaDevice( + const videoInput = useMediaDeviceHandle( "videoinput", videoInputSetting, usingNames, @@ -212,17 +254,52 @@ export const MediaDevicesProvider: FC = ({ children }) => { [setNumCallersUsingNames], ); + return { + audioInput, + videoInput, + startUsingDeviceNames, + stopUsingDeviceNames, + usingNames, + }; +} + +interface Props { + children: JSX.Element; +} + +export const MediaDevicesProvider: FC = ({ children }) => { + const { + audioInput, + videoInput, + startUsingDeviceNames, + stopUsingDeviceNames, + usingNames, + } = useInputDevices(); + + const { controlledAudioDevices } = useUrlParams(); + + const webViewAudioOutput = useMediaDeviceHandle( + "audiooutput", + audioOutputSetting, + usingNames, + ); + const controlledAudioOutput = useControlledOutput(); + const context: MediaDevices = useMemo( () => ({ audioInput, - audioOutput, + audioOutput: controlledAudioDevices + ? controlledAudioOutput + : webViewAudioOutput, videoInput, startUsingDeviceNames, stopUsingDeviceNames, }), [ audioInput, - audioOutput, + controlledAudioDevices, + controlledAudioOutput, + webViewAudioOutput, videoInput, startUsingDeviceNames, stopUsingDeviceNames, @@ -236,6 +313,80 @@ export const MediaDevicesProvider: FC = ({ children }) => { ); }; +function useControlledOutput(): MediaDeviceHandle { + const { available } = useObservableEagerState( + useObservable(() => { + const outputDeviceData$ = availableOutputDevices$.pipe( + map((devices) => { + const deviceForEarpiece = devices.find((d) => d.forEarpiece); + const deviceMapTuple: [string, DeviceLabel][] = devices.map( + ({ id, name, isEarpiece, isSpeaker /*,isExternalHeadset*/ }) => { + let deviceLabel: DeviceLabel = { type: "name", name }; + // if (isExternalHeadset) // Do we want this? + if (isEarpiece) deviceLabel = { type: "earpiece" }; + if (isSpeaker) deviceLabel = { type: "default", name }; + return [id, deviceLabel]; + }, + ); + return { + devicesMap: new Map(deviceMapTuple), + deviceForEarpiece, + }; + }), + ); + + return combineLatest( + [outputDeviceData$, iosDeviceMenu$], + ({ devicesMap, deviceForEarpiece }, iosShowEarpiece) => { + let available = devicesMap; + if (iosShowEarpiece && !!deviceForEarpiece) { + available = new Map([ + ...devicesMap.entries(), + [EARPIECE_CONFIG_ID, { type: "earpiece" }], + ]); + } + return { available, deviceForEarpiece }; + }, + ); + }), + ); + const [preferredId, setPreferredId] = useSetting(audioOutputSetting); + useEffect(() => { + const subscription = outputDevice$.subscribe((id) => { + if (id) setPreferredId(id); + }); + return (): void => subscription.unsubscribe(); + }, [setPreferredId]); + + const selectedId = useSelectedId(available, preferredId); + + const [asEarpiece, setAsEarpiece] = useState(false); + + useEffect(() => { + // Let the hosting application know which output device has been selected. + // This information is probably only of interest if the earpiece mode has been + // selected - for example, Element X iOS listens to this to determine whether it + // should enable the proximity sensor. + if (selectedId) { + window.controls.onAudioDeviceSelect?.(selectedId); + // Call deprecated method for backwards compatibility. + window.controls.onOutputDeviceSelect?.(selectedId); + } + setAsEarpiece(selectedId === EARPIECE_CONFIG_ID); + }, [selectedId]); + + return useMemo( + () => ({ + available: available, + selectedId, + selectedGroupId: undefined, + select: setPreferredId, + useAsEarpiece: asEarpiece, + }), + [available, selectedId, setPreferredId, asEarpiece], + ); +} + export const useMediaDevices = (): MediaDevices => useContext(MediaDevicesContext); @@ -255,3 +406,30 @@ export const useMediaDeviceNames = ( return context.stopUsingDeviceNames; } }, [context, enabled]); + +/** + * A convenience hook to get the audio node configuration for the earpiece. + * It will check the `useAsEarpiece` of the `audioOutput` device and return + * the appropriate pan and volume values. + * + * @returns pan and volume values for the earpiece audio node configuration. + */ +export const useEarpieceAudioConfig = (): { + pan: number; + volume: number; +} => { + const { audioOutput } = useMediaDevices(); + // We use only the right speaker (pan = 1) for the earpiece. + // This mimics the behavior of the native earpiece speaker (only the top speaker on an iPhone) + const pan = useMemo( + () => (audioOutput.useAsEarpiece ? 1 : 0), + [audioOutput.useAsEarpiece], + ); + // We also do lower the volume by a factor of 10 to optimize for the usecase where + // a user is holding the phone to their ear. + const volume = useMemo( + () => (audioOutput.useAsEarpiece ? 0.1 : 1), + [audioOutput.useAsEarpiece], + ); + return { pan, volume }; +}; diff --git a/src/livekit/TrackProcessorContext.tsx b/src/livekit/TrackProcessorContext.tsx new file mode 100644 index 00000000..b310e7b3 --- /dev/null +++ b/src/livekit/TrackProcessorContext.tsx @@ -0,0 +1,84 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only +Please see LICENSE in the repository root for full details. +*/ + +import { + ProcessorWrapper, + supportsBackgroundProcessors, + type BackgroundOptions, +} from "@livekit/track-processors"; +import { createContext, type FC, useContext, useEffect, useMemo } from "react"; +import { type LocalVideoTrack } from "livekit-client"; + +import { + backgroundBlur as backgroundBlurSettings, + useSetting, +} from "../settings/settings"; +import { BlurBackgroundTransformer } from "./BlurBackgroundTransformer"; + +type ProcessorState = { + supported: boolean | undefined; + processor: undefined | ProcessorWrapper; +}; + +const ProcessorContext = createContext(undefined); + +export function useTrackProcessor(): ProcessorState { + const state = useContext(ProcessorContext); + if (state === undefined) + throw new Error( + "useTrackProcessor must be used within a ProcessorProvider", + ); + return state; +} + +export const useTrackProcessorSync = ( + videoTrack: LocalVideoTrack | null, +): void => { + const { processor } = useTrackProcessor(); + useEffect(() => { + if (!videoTrack) return; + if (processor && !videoTrack.getProcessor()) { + void videoTrack.setProcessor(processor); + } + if (!processor && videoTrack.getProcessor()) { + void videoTrack.stopProcessor(); + } + }, [processor, videoTrack]); +}; + +interface Props { + children: JSX.Element; +} + +export const ProcessorProvider: FC = ({ children }) => { + // The setting the user wants to have + const [blurActivated] = useSetting(backgroundBlurSettings); + const supported = useMemo(() => supportsBackgroundProcessors(), []); + const blur = useMemo( + () => + new ProcessorWrapper( + new BlurBackgroundTransformer({ blurRadius: 15 }), + "background-blur", + ), + [], + ); + + // This is the actual state exposed through the context + const processorState = useMemo( + () => ({ + supported, + processor: supported && blurActivated ? blur : undefined, + }), + [supported, blurActivated, blur], + ); + + return ( + + {children} + + ); +}; diff --git a/src/livekit/useECConnectionState.test.tsx b/src/livekit/useECConnectionState.test.tsx index 5f2f6064..72324884 100644 --- a/src/livekit/useECConnectionState.test.tsx +++ b/src/livekit/useECConnectionState.test.tsx @@ -6,7 +6,7 @@ Please see LICENSE in the repository root for full details. */ import { type FC, useCallback, useState } from "react"; -import { test, vi } from "vitest"; +import { describe, expect, test, vi, vitest } from "vitest"; import { ConnectionError, ConnectionErrorReason, @@ -15,6 +15,7 @@ import { import userEvent from "@testing-library/user-event"; import { render, screen } from "@testing-library/react"; import { MemoryRouter } from "react-router-dom"; +import { defer, sleep } from "matrix-js-sdk/lib/utils"; import { useECConnectionState } from "./useECConnectionState"; import { type SFUConfig } from "./openIDSFU"; @@ -57,7 +58,7 @@ test.each<[string, ConnectionError]>([ () => setSfuConfig({ url: "URL", jwt: "JWT token" }), [], ); - useECConnectionState({}, false, mockRoom, sfuConfig); + useECConnectionState("default", false, mockRoom, sfuConfig); return ; }; @@ -73,3 +74,111 @@ test.each<[string, ConnectionError]>([ screen.getByText("Insufficient capacity"); }, ); + +describe("Leaking connection prevention", () => { + function createTestComponent(mockRoom: Room): FC { + const TestComponent: FC = () => { + const [sfuConfig, setSfuConfig] = useState( + undefined, + ); + const connect = useCallback( + () => setSfuConfig({ url: "URL", jwt: "JWT token" }), + [], + ); + useECConnectionState("default", false, mockRoom, sfuConfig); + return ; + }; + return TestComponent; + } + + test("Should cancel pending connections when the component is unmounted", async () => { + const connectCall = vi.fn(); + const pendingConnection = defer(); + // let pendingDisconnection = defer() + const disconnectMock = vi.fn(); + + const mockRoom = { + on: () => {}, + off: () => {}, + once: () => {}, + connect: async () => { + connectCall.call(undefined); + return await pendingConnection.promise; + }, + disconnect: disconnectMock, + localParticipant: { + getTrackPublication: () => {}, + createTracks: () => [], + }, + } as unknown as Room; + + const TestComponent = createTestComponent(mockRoom); + + const { unmount } = render(); + const user = userEvent.setup(); + await user.click(screen.getByRole("button", { name: "Connect" })); + + expect(connectCall).toHaveBeenCalled(); + // unmount while the connection is pending + unmount(); + + // resolve the pending connection + pendingConnection.resolve(); + + await vitest.waitUntil( + () => { + return disconnectMock.mock.calls.length > 0; + }, + { + timeout: 1000, + interval: 100, + }, + ); + + // There should be some cleaning up to avoid leaking an open connection + expect(disconnectMock).toHaveBeenCalledTimes(1); + }); + + test("Should cancel about to open but not yet opened connection", async () => { + const createTracksCall = vi.fn(); + const pendingCreateTrack = defer(); + // let pendingDisconnection = defer() + const disconnectMock = vi.fn(); + const connectMock = vi.fn(); + + const mockRoom = { + on: () => {}, + off: () => {}, + once: () => {}, + connect: connectMock, + disconnect: disconnectMock, + localParticipant: { + getTrackPublication: () => {}, + createTracks: async () => { + createTracksCall.call(undefined); + await pendingCreateTrack.promise; + return []; + }, + }, + } as unknown as Room; + + const TestComponent = createTestComponent(mockRoom); + + const { unmount } = render(); + const user = userEvent.setup(); + await user.click(screen.getByRole("button", { name: "Connect" })); + + expect(createTracksCall).toHaveBeenCalled(); + // unmount while createTracks is pending + unmount(); + + // resolve createTracks + pendingCreateTrack.resolve(); + + // Yield to the event loop to let the connection attempt finish + await sleep(100); + + // The operation should have been aborted before even calling connect. + expect(connectMock).not.toHaveBeenCalled(); + }); +}); diff --git a/src/livekit/useECConnectionState.ts b/src/livekit/useECConnectionState.ts index fa9a3038..3c7b91f8 100644 --- a/src/livekit/useECConnectionState.ts +++ b/src/livekit/useECConnectionState.ts @@ -6,7 +6,6 @@ Please see LICENSE in the repository root for full details. */ import { - type AudioCaptureOptions, ConnectionError, ConnectionState, type LocalTrack, @@ -25,6 +24,7 @@ import { InsufficientCapacityError, UnknownCallError, } from "../utils/errors.ts"; +import { AbortHandle } from "../utils/abortHandle.ts"; declare global { interface Window { @@ -59,7 +59,8 @@ async function doConnect( livekitRoom: Room, sfuConfig: SFUConfig, audioEnabled: boolean, - audioOptions: AudioCaptureOptions, + initialDeviceId: string | undefined, + abortHandle: AbortHandle, ): Promise { // Always create an audio track manually. // livekit (by default) keeps the mic track open when you mute, but if you start muted, @@ -82,19 +83,40 @@ async function doConnect( let preCreatedAudioTrack: LocalTrack | undefined; try { const audioTracks = await livekitRoom!.localParticipant.createTracks({ - audio: audioOptions, + audio: { deviceId: initialDeviceId }, }); + if (audioTracks.length < 1) { logger.info("Tried to pre-create local audio track but got no tracks"); } else { preCreatedAudioTrack = audioTracks[0]; } + // There was a yield point previously (awaiting for the track to be created) so we need to check + // if the operation was cancelled and stop connecting if needed. + if (abortHandle.isAborted()) { + logger.info( + "[Lifecycle] Signal Aborted: Pre-created audio track but connection aborted", + ); + preCreatedAudioTrack?.stop(); + return; + } + logger.info("Pre-created microphone track"); } catch (e) { logger.error("Failed to pre-create microphone track", e); } - if (!audioEnabled) await preCreatedAudioTrack?.mute(); + if (!audioEnabled) { + await preCreatedAudioTrack?.mute(); + // There was a yield point. Check if the operation was cancelled and stop connecting. + if (abortHandle.isAborted()) { + logger.info( + "[Lifecycle] Signal Aborted: Pre-created audio track but connection aborted", + ); + preCreatedAudioTrack?.stop(); + return; + } + } // check again having awaited for the track to create if ( @@ -107,9 +129,18 @@ async function doConnect( return; } - logger.info("Connecting & publishing"); + logger.info("[Lifecycle] Connecting & publishing"); try { await connectAndPublish(livekitRoom, sfuConfig, preCreatedAudioTrack, []); + if (abortHandle.isAborted()) { + logger.info( + "[Lifecycle] Signal Aborted: Connected but operation was cancelled. Force disconnect", + ); + livekitRoom?.disconnect().catch((err) => { + logger.error("Failed to disconnect from SFU", err); + }); + return; + } } catch (e) { preCreatedAudioTrack?.stop(); logger.debug("Stopped precreated audio tracks."); @@ -137,13 +168,16 @@ async function connectAndPublish( livekitRoom.once(RoomEvent.SignalConnected, tracker.cacheWsConnect); try { + logger.info(`[Lifecycle] Connecting to livekit room ${sfuConfig!.url} ...`); await livekitRoom!.connect(sfuConfig!.url, sfuConfig!.jwt, { // Due to stability issues on Firefox we are testing the effect of different // timeouts, and allow these values to be set through the console peerConnectionTimeout: window.peerConnectionTimeout ?? 45000, websocketTimeout: window.websocketTimeout ?? 45000, }); + logger.info(`[Lifecycle] ... connected to livekit room`); } catch (e) { + logger.error("[Lifecycle] Failed to connect", e); // LiveKit uses 503 to indicate that the server has hit its track limits. // https://github.com/livekit/livekit/blob/fcb05e97c5a31812ecf0ca6f7efa57c485cea9fb/pkg/service/rtcservice.go#L171 // It also errors with a status code of 200 (yes, really) for room @@ -184,7 +218,7 @@ async function connectAndPublish( } export function useECConnectionState( - initialAudioOptions: AudioCaptureOptions, + initialDeviceId: string | undefined, initialAudioEnabled: boolean, livekitRoom?: Room, sfuConfig?: SFUConfig, @@ -247,6 +281,22 @@ export function useECConnectionState( const currentSFUConfig = useRef(Object.assign({}, sfuConfig)); + // Protection against potential leaks, where the component to be unmounted and there is + // still a pending doConnect promise. This would lead the user to still be in the call even + // if the component is unmounted. + const abortHandlesBag = useRef(new Set()); + + // This is a cleanup function that will be called when the component is about to be unmounted. + // It will cancel all abortHandles in the bag + useEffect(() => { + const bag = abortHandlesBag.current; + return (): void => { + bag.forEach((handle) => { + handle.abort(); + }); + }; + }, []); + // Id we are transitioning from a valid config to another valid one, we need // to explicitly switch focus useEffect(() => { @@ -273,11 +323,14 @@ export function useECConnectionState( // always capturing audio: it helps keep bluetooth headsets in the right mode and // mobile browsers to know we're doing a call. setIsInDoConnect(true); + const abortHandle = new AbortHandle(); + abortHandlesBag.current.add(abortHandle); doConnect( livekitRoom!, sfuConfig!, initialAudioEnabled, - initialAudioOptions, + initialDeviceId, + abortHandle, ) .catch((e) => { if (e instanceof ElementCallError) { @@ -286,14 +339,17 @@ export function useECConnectionState( setError(new UnknownCallError(e)); } else logger.error("Failed to connect to SFU", e); }) - .finally(() => setIsInDoConnect(false)); + .finally(() => { + abortHandlesBag.current.delete(abortHandle); + setIsInDoConnect(false); + }); } currentSFUConfig.current = Object.assign({}, sfuConfig); }, [ sfuConfig, livekitRoom, - initialAudioOptions, + initialDeviceId, initialAudioEnabled, doFocusSwitch, ]); diff --git a/src/livekit/useLiveKit.ts b/src/livekit/useLivekit.ts similarity index 88% rename from src/livekit/useLiveKit.ts rename to src/livekit/useLivekit.ts index da180ab8..c9a4e92a 100644 --- a/src/livekit/useLiveKit.ts +++ b/src/livekit/useLivekit.ts @@ -9,6 +9,7 @@ import { ConnectionState, type E2EEManagerOptions, ExternalE2EEKeyProvider, + LocalVideoTrack, Room, type RoomOptions, Track, @@ -17,12 +18,14 @@ import { useEffect, useMemo, useRef } from "react"; import E2EEWorker from "livekit-client/e2ee-worker?worker"; import { logger } from "matrix-js-sdk/lib/logger"; import { type MatrixRTCSession } from "matrix-js-sdk/lib/matrixrtc"; +import { useObservable, useObservableEagerState } from "observable-hooks"; +import { map } from "rxjs"; import { defaultLiveKitOptions } from "./options"; import { type SFUConfig } from "./openIDSFU"; import { type MuteStates } from "../room/MuteStates"; import { - type MediaDevice, + type MediaDeviceHandle, type MediaDevices, useMediaDevices, } from "./MediaDevicesContext"; @@ -33,18 +36,27 @@ import { import { MatrixKeyProvider } from "../e2ee/matrixKeyProvider"; import { E2eeType } from "../e2ee/e2eeType"; import { type EncryptionSystem } from "../e2ee/sharedKeyManagement"; +import { + useTrackProcessor, + useTrackProcessorSync, +} from "./TrackProcessorContext"; +import { useInitial } from "../useInitial"; +import { observeTrackReference$ } from "../state/MediaViewModel"; +import { useUrlParams } from "../UrlParams"; interface UseLivekitResult { livekitRoom?: Room; connState: ECConnectionState; } -export function useLiveKit( +export function useLivekit( rtcSession: MatrixRTCSession, muteStates: MuteStates, sfuConfig: SFUConfig | undefined, e2eeSystem: EncryptionSystem, ): UseLivekitResult { + const { controlledAudioDevices } = useUrlParams(); + const e2eeOptions = useMemo((): E2EEManagerOptions | undefined => { if (e2eeSystem.kind === E2eeType.NONE) return undefined; @@ -82,12 +94,15 @@ export function useLiveKit( const devices = useMediaDevices(); const initialDevices = useRef(devices); + const { processor } = useTrackProcessor(); + const initialProcessor = useInitial(() => processor); const roomOptions = useMemo( (): RoomOptions => ({ ...defaultLiveKitOptions, videoCaptureDefaults: { ...defaultLiveKitOptions.videoCaptureDefaults, deviceId: initialDevices.current.videoInput.selectedId, + processor: initialProcessor, }, audioCaptureDefaults: { ...defaultLiveKitOptions.audioCaptureDefaults, @@ -98,7 +113,7 @@ export function useLiveKit( }, e2ee: e2eeOptions, }), - [e2eeOptions], + [e2eeOptions, initialProcessor], ); // Store if audio/video are currently updating. If to prohibit unnecessary calls @@ -116,6 +131,7 @@ export function useLiveKit( // @livekit/components-react. JSON.stringify() is used in deps of a // useEffect() with an argument that references itself, if E2EE is enabled const room = useMemo(() => { + logger.info("[LivekitRooms] Create LiveKit room with options", roomOptions); const r = new Room(roomOptions); r.setE2EEEnabled(e2eeSystem.kind !== E2eeType.NONE).catch((e) => { logger.error("Failed to set E2EE enabled on room", e); @@ -123,10 +139,27 @@ export function useLiveKit( return r; }, [roomOptions, e2eeSystem]); + // Sync the requested track processors with LiveKit + useTrackProcessorSync( + useObservableEagerState( + useObservable( + (room$) => + observeTrackReference$( + room$.pipe(map(([room]) => room.localParticipant)), + Track.Source.Camera, + ).pipe( + map((trackRef) => { + const track = trackRef?.publication?.track; + return track instanceof LocalVideoTrack ? track : null; + }), + ), + [room], + ), + ), + ); + const connectionState = useECConnectionState( - { - deviceId: initialDevices.current.audioInput.selectedId, - }, + initialDevices.current.audioInput.selectedId, initialMuteStates.current.audio.enabled, room, sfuConfig, @@ -198,6 +231,7 @@ export function useLiveKit( audioMuteUpdating.current = true; trackPublication = await participant.setMicrophoneEnabled( buttonEnabled.current.audio, + room.options.audioCaptureDefaults, ); audioMuteUpdating.current = false; break; @@ -205,6 +239,7 @@ export function useLiveKit( videoMuteUpdating.current = true; trackPublication = await participant.setCameraEnabled( buttonEnabled.current.video, + room.options.videoCaptureDefaults, ); videoMuteUpdating.current = false; break; @@ -272,8 +307,15 @@ export function useLiveKit( useEffect(() => { // Sync the requested devices with LiveKit's devices - if (room !== undefined && connectionState === ConnectionState.Connected) { - const syncDevice = (kind: MediaDeviceKind, device: MediaDevice): void => { + if ( + room !== undefined && + connectionState === ConnectionState.Connected && + !controlledAudioDevices + ) { + const syncDevice = ( + kind: MediaDeviceKind, + device: MediaDeviceHandle, + ): void => { const id = device.selectedId; // Detect if we're trying to use chrome's default device, in which case @@ -329,7 +371,7 @@ export function useLiveKit( syncDevice("audiooutput", devices.audioOutput); syncDevice("videoinput", devices.videoInput); } - }, [room, devices, connectionState]); + }, [room, devices, connectionState, controlledAudioDevices]); return { connState: connectionState, diff --git a/src/main.tsx b/src/main.tsx index bfa20443..654bd93c 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -29,7 +29,7 @@ window.setLKLogLevel = setLKLogLevel; initRageshake().catch((e) => { logger.error("Failed to initialize rageshake", e); }); -setLKLogLevel("warn"); +setLKLogLevel("info"); setLKLogExtension((level, msg, context) => { // we pass a synthetic logger name of "livekit" to the rageshake to make it easier to read global.mx_rage_logger.log(level, "livekit", msg, context); diff --git a/src/mediapipe/imageSegmenter/README.md b/src/mediapipe/imageSegmenter/README.md new file mode 100644 index 00000000..39bea2d8 --- /dev/null +++ b/src/mediapipe/imageSegmenter/README.md @@ -0,0 +1,5 @@ +# Google AI Edge MediaPipe Selfie Segmentation + +- See: https://ai.google.dev/edge/mediapipe/solutions/vision/image_segmenter +- Latest: https://storage.googleapis.com/mediapipe-models/image_segmenter/selfie_segmenter/float16/latest/selfie_segmenter.tflite +- License: Apache 2.0 as per https://storage.googleapis.com/mediapipe-assets/Model%20Card%20MediaPipe%20Selfie%20Segmentation.pdf diff --git a/src/mediapipe/imageSegmenter/selfie_segmenter.tflite b/src/mediapipe/imageSegmenter/selfie_segmenter.tflite new file mode 100644 index 00000000..a4ebd477 Binary files /dev/null and b/src/mediapipe/imageSegmenter/selfie_segmenter.tflite differ diff --git a/src/otel/otel.ts b/src/otel/otel.ts index a2cd809e..915c3d58 100644 --- a/src/otel/otel.ts +++ b/src/otel/otel.ts @@ -5,12 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base"; +import { + SimpleSpanProcessor, + type SpanProcessor, +} from "@opentelemetry/sdk-trace-base"; import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; import { WebTracerProvider } from "@opentelemetry/sdk-trace-web"; import opentelemetry, { type Tracer } from "@opentelemetry/api"; -import { Resource } from "@opentelemetry/resources"; -import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; +import { resourceFromAttributes } from "@opentelemetry/resources"; +import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions"; import { logger } from "matrix-js-sdk/lib/logger"; import { PosthogSpanProcessor } from "../analytics/PosthogSpanProcessor"; @@ -59,34 +62,34 @@ export class ElementCallOpenTelemetry { collectorUrl: string | undefined, rageshakeUrl: string | undefined, ) { - // This is how we can make Jaeger show a reasonable service in the dropdown on the left. - const providerConfig = { - resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: SERVICE_NAME, - }), - }; - this._provider = new WebTracerProvider(providerConfig); + const spanProcessors: SpanProcessor[] = []; if (collectorUrl) { logger.info("Enabling OTLP collector with URL " + collectorUrl); this.otlpExporter = new OTLPTraceExporter({ url: collectorUrl, }); - this._provider.addSpanProcessor( - new SimpleSpanProcessor(this.otlpExporter), - ); + spanProcessors.push(new SimpleSpanProcessor(this.otlpExporter)); } else { logger.info("OTLP collector disabled"); } if (rageshakeUrl) { this.rageshakeProcessor = new RageshakeSpanProcessor(); - this._provider.addSpanProcessor(this.rageshakeProcessor); + spanProcessors.push(this.rageshakeProcessor); } - this._provider.addSpanProcessor(new PosthogSpanProcessor()); - opentelemetry.trace.setGlobalTracerProvider(this._provider); + spanProcessors.push(new PosthogSpanProcessor()); + this._provider = new WebTracerProvider({ + resource: resourceFromAttributes({ + // This is how we can make Jaeger show a reasonable service in the dropdown on the left. + [ATTR_SERVICE_NAME]: SERVICE_NAME, + }), + spanProcessors, + }); + + opentelemetry.trace.setGlobalTracerProvider(this._provider); this._tracer = opentelemetry.trace.getTracer( // This is not the serviceName shown in jaeger "my-element-call-otl-tracer", diff --git a/src/room/CallEventAudioRenderer.tsx b/src/room/CallEventAudioRenderer.tsx index 6eeef4c4..a0d685ff 100644 --- a/src/room/CallEventAudioRenderer.tsx +++ b/src/room/CallEventAudioRenderer.tsx @@ -47,12 +47,15 @@ export const callEventAudioSounds = prefetchSounds({ export function CallEventAudioRenderer({ vm, + muted, }: { vm: CallViewModel; + muted?: boolean; }): ReactNode { const audioEngineCtx = useAudioContext({ sounds: callEventAudioSounds, latencyHint: "interactive", + muted, }); const audioEngineRef = useLatest(audioEngineCtx); diff --git a/src/room/GroupCallView.test.tsx b/src/room/GroupCallView.test.tsx index 76765270..75961c72 100644 --- a/src/room/GroupCallView.test.tsx +++ b/src/room/GroupCallView.test.tsx @@ -38,6 +38,7 @@ import { GroupCallView } from "./GroupCallView"; import { type WidgetHelpers } from "../widget"; import { LazyEventEmitter } from "../LazyEventEmitter"; import { MatrixRTCFocusMissingError } from "../utils/errors"; +import { ProcessorProvider } from "../livekit/TrackProcessorContext"; vi.mock("../soundUtils"); vi.mock("../useAudioContext"); @@ -46,6 +47,13 @@ vi.mock("react-use-measure", () => ({ default: (): [() => void, object] => [(): void => {}, {}], })); +vi.hoisted( + () => + (global.ImageData = class MockImageData { + public data: number[] = []; + } as unknown as typeof ImageData), +); + const enterRTCSession = vi.hoisted(() => vi.fn(async () => Promise.resolve())); const leaveRTCSession = vi.hoisted(() => vi.fn( @@ -137,18 +145,20 @@ function createGroupCallView( const { getByText } = render( - + + + , ); diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index 0d727485..4097af6c 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -24,6 +24,7 @@ import { type MatrixRTCSession, } from "matrix-js-sdk/lib/matrixrtc"; import { useNavigate } from "react-router-dom"; +import { useObservableEagerState } from "observable-hooks"; import type { IWidgetApiRequest } from "matrix-widget-api"; import { @@ -62,11 +63,12 @@ import { } from "../utils/errors.ts"; import { GroupCallErrorBoundary } from "./GroupCallErrorBoundary.tsx"; import { - useExperimentalToDeviceTransportSetting, - useNewMembershipManagerSetting as useNewMembershipManagerSetting, + useNewMembershipManager as useNewMembershipManagerSetting, + useExperimentalToDeviceTransport as useExperimentalToDeviceTransportSetting, useSetting, } from "../settings/settings"; import { useTypedEventEmitter } from "../useEvents"; +import { muteAllAudio$ } from "../state/MuteAllAudioModel.ts"; declare global { interface Window { @@ -103,12 +105,14 @@ export const GroupCallView: FC = ({ const [externalError, setExternalError] = useState( null, ); - const memberships = useMatrixRTCSessionMemberships(rtcSession); + + const muteAllAudio = useObservableEagerState(muteAllAudio$); const leaveSoundContext = useLatest( useAudioContext({ sounds: callEventAudioSounds, latencyHint: "interactive", + muted: muteAllAudio, }), ); // This should use `useEffectEvent` (only available in experimental versions) @@ -118,6 +122,13 @@ export const GroupCallView: FC = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + useEffect(() => { + logger.info("[Lifecycle] GroupCallView Component mounted"); + return (): void => { + logger.info("[Lifecycle] GroupCallView Component unmounted"); + }; + }, []); + useEffect(() => { window.rtcSession = rtcSession; return (): void => { diff --git a/src/room/InCallView.test.tsx b/src/room/InCallView.test.tsx new file mode 100644 index 00000000..59ca7696 --- /dev/null +++ b/src/room/InCallView.test.tsx @@ -0,0 +1,265 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE in the repository root for full details. +*/ + +import { + beforeEach, + describe, + expect, + it, + type MockedFunction, + vi, +} from "vitest"; +import { act, render, type RenderResult } from "@testing-library/react"; +import { type MatrixClient, JoinRule, type RoomState } from "matrix-js-sdk"; +import { type MatrixRTCSession } from "matrix-js-sdk/lib/matrixrtc"; +import { type RelationsContainer } from "matrix-js-sdk/lib/models/relations-container"; +import { ConnectionState, type LocalParticipant } from "livekit-client"; +import { of } from "rxjs"; +import { BrowserRouter } from "react-router-dom"; +import { TooltipProvider } from "@vector-im/compound-web"; +import { RoomContext, useLocalParticipant } from "@livekit/components-react"; +import { RoomAndToDeviceEvents } from "matrix-js-sdk/lib/matrixrtc/RoomAndToDeviceKeyTransport"; + +import { type MuteStates } from "./MuteStates"; +import { InCallView } from "./InCallView"; +import { + mockLivekitRoom, + mockLocalParticipant, + mockMatrixRoom, + mockMatrixRoomMember, + mockRemoteParticipant, + mockRtcMembership, + type MockRTCSession, +} from "../utils/test"; +import { E2eeType } from "../e2ee/e2eeType"; +import { getBasicCallViewModelEnvironment } from "../utils/test-viewmodel"; +import { alice, local } from "../utils/test-fixtures"; +import { + developerMode as developerModeSetting, + useExperimentalToDeviceTransport as useExperimentalToDeviceTransportSetting, +} from "../settings/settings"; +import { ReactionsSenderProvider } from "../reactions/useReactionsSender"; +import { useRoomEncryptionSystem } from "../e2ee/sharedKeyManagement"; +import { MatrixAudioRenderer } from "../livekit/MatrixAudioRenderer"; + +// vi.hoisted(() => { +// localStorage = {} as unknown as Storage; +// }); +vi.hoisted( + () => + (global.ImageData = class MockImageData { + public data: number[] = []; + } as unknown as typeof ImageData), +); + +vi.mock("../soundUtils"); +vi.mock("../useAudioContext"); +vi.mock("../tile/GridTile"); +vi.mock("../tile/SpotlightTile"); +vi.mock("@livekit/components-react"); +vi.mock("../e2ee/sharedKeyManagement"); +vi.mock("../livekit/MatrixAudioRenderer"); +vi.mock("react-use-measure", () => ({ + default: (): [() => void, object] => [(): void => {}, {}], +})); + +const localRtcMember = mockRtcMembership("@carol:example.org", "CCCC"); +const localParticipant = mockLocalParticipant({ + identity: "@local:example.org:AAAAAA", +}); +const remoteParticipant = mockRemoteParticipant({ + identity: "@alice:example.org:AAAAAA", +}); +const carol = mockMatrixRoomMember(localRtcMember); +const roomMembers = new Map([carol].map((p) => [p.userId, p])); + +const roomId = "!foo:bar"; +let useRoomEncryptionSystemMock: MockedFunction; + +beforeEach(() => { + vi.clearAllMocks(); + + // MatrixAudioRenderer is tested separately. + ( + MatrixAudioRenderer as MockedFunction + ).mockImplementation((_props) => { + return
mocked: MatrixAudioRenderer
; + }); + ( + useLocalParticipant as MockedFunction + ).mockImplementation( + () => + ({ + isScreenShareEnabled: false, + localParticipant: localRtcMember as unknown as LocalParticipant, + }) as unknown as ReturnType, + ); + useRoomEncryptionSystemMock = + useRoomEncryptionSystem as typeof useRoomEncryptionSystemMock; + useRoomEncryptionSystemMock.mockReturnValue({ kind: E2eeType.NONE }); +}); + +function createInCallView(): RenderResult & { + rtcSession: MockRTCSession; +} { + const client = { + getUser: () => null, + getUserId: () => localRtcMember.sender, + getDeviceId: () => localRtcMember.deviceId, + getRoom: (rId) => (rId === roomId ? room : null), + } as Partial as MatrixClient; + const room = mockMatrixRoom({ + relations: { + getChildEventsForEvent: () => + vi.mocked({ + getRelations: () => [], + }), + } as unknown as RelationsContainer, + client, + roomId, + getMember: (userId) => roomMembers.get(userId) ?? null, + getMxcAvatarUrl: () => null, + hasEncryptionStateEvent: vi.fn().mockReturnValue(true), + getCanonicalAlias: () => null, + currentState: { + getJoinRule: () => JoinRule.Invite, + } as Partial as RoomState, + }); + + const muteState = { + audio: { enabled: false }, + video: { enabled: false }, + } as MuteStates; + const livekitRoom = mockLivekitRoom( + { + localParticipant, + }, + { + remoteParticipants$: of([remoteParticipant]), + }, + ); + const { vm, rtcSession } = getBasicCallViewModelEnvironment([local, alice]); + + rtcSession.joined = true; + const renderResult = render( + + + + + + + + + , + ); + return { + ...renderResult, + rtcSession, + }; +} + +describe("InCallView", () => { + describe("rendering", () => { + it("renders", () => { + const { container } = createInCallView(); + expect(container).toMatchSnapshot(); + }); + }); + describe("toDevice label", () => { + it("is shown if setting activated and room encrypted", () => { + useRoomEncryptionSystemMock.mockReturnValue({ + kind: E2eeType.PER_PARTICIPANT, + }); + useExperimentalToDeviceTransportSetting.setValue(true); + developerModeSetting.setValue(true); + const { getByText } = createInCallView(); + expect(getByText("using to Device key transport")).toBeInTheDocument(); + }); + + it("is not shown in unenecrypted room", () => { + useRoomEncryptionSystemMock.mockReturnValue({ + kind: E2eeType.NONE, + }); + useExperimentalToDeviceTransportSetting.setValue(true); + developerModeSetting.setValue(true); + const { queryByText } = createInCallView(); + expect( + queryByText("using to Device key transport"), + ).not.toBeInTheDocument(); + }); + + it("is hidden once fallback was triggered", async () => { + useRoomEncryptionSystemMock.mockReturnValue({ + kind: E2eeType.PER_PARTICIPANT, + }); + useExperimentalToDeviceTransportSetting.setValue(true); + developerModeSetting.setValue(true); + const { rtcSession, queryByText } = createInCallView(); + expect(queryByText("using to Device key transport")).toBeInTheDocument(); + expect(rtcSession).toBeDefined(); + await act(() => + rtcSession.emit(RoomAndToDeviceEvents.EnabledTransportsChanged, { + toDevice: true, + room: true, + }), + ); + expect( + queryByText("using to Device key transport"), + ).not.toBeInTheDocument(); + }); + it("is not shown if setting is disabled", () => { + useExperimentalToDeviceTransportSetting.setValue(false); + developerModeSetting.setValue(true); + useRoomEncryptionSystemMock.mockReturnValue({ + kind: E2eeType.PER_PARTICIPANT, + }); + const { queryByText } = createInCallView(); + expect( + queryByText("using to Device key transport"), + ).not.toBeInTheDocument(); + }); + it("is not shown if developer mode is disabled", () => { + useExperimentalToDeviceTransportSetting.setValue(true); + developerModeSetting.setValue(false); + useRoomEncryptionSystemMock.mockReturnValue({ + kind: E2eeType.PER_PARTICIPANT, + }); + const { queryByText } = createInCallView(); + expect( + queryByText("using to Device key transport"), + ).not.toBeInTheDocument(); + }); + }); +}); diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index b434a1da..b9655d37 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -5,11 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { - RoomAudioRenderer, - RoomContext, - useLocalParticipant, -} from "@livekit/components-react"; +import { RoomContext, useLocalParticipant } from "@livekit/components-react"; import { Text } from "@vector-im/compound-web"; import { ConnectionState, type Room } from "livekit-client"; import { type MatrixClient } from "matrix-js-sdk"; @@ -56,7 +52,7 @@ import { type OTelGroupCallMembership } from "../otel/OTelGroupCallMembership"; import { SettingsModal, defaultSettingsTab } from "../settings/SettingsModal"; import { useRageshakeRequestModal } from "../settings/submit-rageshake"; import { RageshakeRequestModal } from "./RageshakeRequestModal"; -import { useLiveKit } from "../livekit/useLiveKit"; +import { useLivekit } from "../livekit/useLivekit.ts"; import { useWakeLock } from "../useWakeLock"; import { useMergedRefs } from "../useMergedRefs"; import { type MuteStates } from "./MuteStates"; @@ -73,7 +69,10 @@ import { import { Grid, type TileProps } from "../grid/Grid"; import { useInitial } from "../useInitial"; import { SpotlightTile } from "../tile/SpotlightTile"; -import { type EncryptionSystem } from "../e2ee/sharedKeyManagement"; +import { + useRoomEncryptionSystem, + type EncryptionSystem, +} from "../e2ee/sharedKeyManagement"; import { E2eeType } from "../e2ee/e2eeType"; import { makeGridLayout } from "../grid/GridLayout"; import { @@ -96,12 +95,15 @@ import { ReactionsOverlay } from "./ReactionsOverlay"; import { CallEventAudioRenderer } from "./CallEventAudioRenderer"; import { debugTileLayout as debugTileLayoutSetting, - useExperimentalToDeviceTransportSetting, + useExperimentalToDeviceTransport as useExperimentalToDeviceTransportSetting, + developerMode as developerModeSetting, useSetting, } from "../settings/settings"; import { ReactionsReader } from "../reactions/ReactionsReader"; import { ConnectionLostError } from "../utils/errors.ts"; import { useTypedEventEmitter } from "../useEvents.ts"; +import { MatrixAudioRenderer } from "../livekit/MatrixAudioRenderer.tsx"; +import { muteAllAudio$ } from "../state/MuteAllAudioModel.ts"; const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {}); @@ -114,7 +116,7 @@ export interface ActiveCallProps export const ActiveCall: FC = (props) => { const sfuConfig = useOpenIDSFU(props.client, props.rtcSession); - const { livekitRoom, connState } = useLiveKit( + const { livekitRoom, connState } = useLivekit( props.rtcSession, props.muteStates, sfuConfig, @@ -127,10 +129,23 @@ export const ActiveCall: FC = (props) => { const [vm, setVm] = useState(null); useEffect(() => { + logger.info( + `[Lifecycle] InCallView Component mounted, livekitroom state ${livekitRoom?.state}`, + ); return (): void => { - livekitRoom?.disconnect().catch((e) => { - logger.error("Failed to disconnect from livekit room", e); - }); + logger.info( + `[Lifecycle] InCallView Component unmounted, livekitroom state ${livekitRoom?.state}`, + ); + livekitRoom + ?.disconnect() + .then(() => { + logger.info( + `[Lifecycle] Disconnected from livekite room, state:${livekitRoom?.state}`, + ); + }) + .catch((e) => { + logger.error("[Lifecycle] Failed to disconnect from livekit room", e); + }); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -220,19 +235,34 @@ export const InCallView: FC = ({ room: livekitRoom, }); - const [toDeviceEncryptionSetting] = useSetting( - useExperimentalToDeviceTransportSetting, - ); - const [showToDeviceEncryption, setShowToDeviceEncryption] = useState( - () => toDeviceEncryptionSetting, - ); - useEffect(() => { - setShowToDeviceEncryption(toDeviceEncryptionSetting); - }, [toDeviceEncryptionSetting]); + const muteAllAudio = useObservableEagerState(muteAllAudio$); + + // This seems like it might be enough logic to use move it into the call view model? + const [didFallbackToRoomKey, setDidFallbackToRoomKey] = useState(false); useTypedEventEmitter( rtcSession, RoomAndToDeviceEvents.EnabledTransportsChanged, - (enabled) => setShowToDeviceEncryption(enabled.to_device), + (enabled) => setDidFallbackToRoomKey(enabled.room), + ); + + const [developerMode] = useSetting(developerModeSetting); + const [useExperimentalToDeviceTransport] = useSetting( + useExperimentalToDeviceTransportSetting, + ); + const encryptionSystem = useRoomEncryptionSystem(rtcSession.room.roomId); + + const showToDeviceEncryption = useMemo( + () => + developerMode && + useExperimentalToDeviceTransport && + encryptionSystem.kind === E2eeType.PER_PARTICIPANT && + !didFallbackToRoomKey, + [ + developerMode, + useExperimentalToDeviceTransport, + encryptionSystem.kind, + didFallbackToRoomKey, + ], ); const toggleMicrophone = useCallback( @@ -693,10 +723,13 @@ export const InCallView: FC = ({ ) } - + {renderContent()} - - + + {footer} {layout.type !== "pip" && ( diff --git a/src/room/LobbyView.tsx b/src/room/LobbyView.tsx index 0a93675e..72079783 100644 --- a/src/room/LobbyView.tsx +++ b/src/room/LobbyView.tsx @@ -5,14 +5,25 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { type FC, useCallback, useMemo, useState, type JSX } from "react"; +import { + type FC, + useCallback, + useMemo, + useState, + type JSX, + useEffect, +} from "react"; import { useTranslation } from "react-i18next"; import { type MatrixClient } from "matrix-js-sdk"; import { Button } from "@vector-im/compound-web"; import classNames from "classnames"; import { logger } from "matrix-js-sdk/lib/logger"; import { usePreviewTracks } from "@livekit/components-react"; -import { type LocalVideoTrack, Track } from "livekit-client"; +import { + type CreateLocalTracksOptions, + type LocalVideoTrack, + Track, +} from "livekit-client"; import { useObservable } from "observable-hooks"; import { map } from "rxjs"; import { useNavigate } from "react-router-dom"; @@ -36,7 +47,11 @@ import { E2eeType } from "../e2ee/e2eeType"; import { Link } from "../button/Link"; import { useMediaDevices } from "../livekit/MediaDevicesContext"; import { useInitial } from "../useInitial"; -import { useSwitchCamera } from "./useSwitchCamera"; +import { useSwitchCamera as useShowSwitchCamera } from "./useSwitchCamera"; +import { + useTrackProcessor, + useTrackProcessorSync, +} from "../livekit/TrackProcessorContext"; import { usePageTitle } from "../usePageTitle"; interface Props { @@ -64,6 +79,13 @@ export const LobbyView: FC = ({ onShareClick, waitingForInvite, }) => { + useEffect(() => { + logger.info("[Lifecycle] GroupCallView Component mounted"); + return (): void => { + logger.info("[Lifecycle] GroupCallView Component unmounted"); + }; + }, []); + const { t } = useTranslation(); usePageTitle(matrixInfo.roomName); @@ -112,7 +134,10 @@ export const LobbyView: FC = ({ muteStates.audio.enabled && { deviceId: devices.audioInput.selectedId }, ); - const localTrackOptions = useMemo( + const { processor } = useTrackProcessor(); + + const initialProcessor = useInitial(() => processor); + const localTrackOptions = useMemo( () => ({ // The only reason we request audio here is to get the audio permission // request over with at the same time. But changing the audio settings @@ -123,12 +148,14 @@ export const LobbyView: FC = ({ audio: Object.assign({}, initialAudioOptions), video: muteStates.video.enabled && { deviceId: devices.videoInput.selectedId, + processor: initialProcessor, }, }), [ initialAudioOptions, - devices.videoInput.selectedId, muteStates.video.enabled, + devices.videoInput.selectedId, + initialProcessor, ], ); @@ -149,8 +176,8 @@ export const LobbyView: FC = ({ null) as LocalVideoTrack | null, [tracks], ); - - const switchCamera = useSwitchCamera( + useTrackProcessorSync(videoTrack); + const showSwitchCamera = useShowSwitchCamera( useObservable( (inputs$) => inputs$.pipe(map(([video]) => video)), [videoTrack], @@ -212,7 +239,9 @@ export const LobbyView: FC = ({ onClick={onVideoPress} disabled={muteStates.video.setEnabled === null} /> - {switchCamera && } + {showSwitchCamera && ( + + )} {!confineToRoom && }
diff --git a/src/room/MuteStates.test.tsx b/src/room/MuteStates.test.tsx index 4a375c8f..65e7d333 100644 --- a/src/room/MuteStates.test.tsx +++ b/src/room/MuteStates.test.tsx @@ -14,7 +14,7 @@ import userEvent from "@testing-library/user-event"; import { useMuteStates } from "./MuteStates"; import { type DeviceLabel, - type MediaDevice, + type MediaDeviceHandle, type MediaDevices, MediaDevicesContext, } from "../livekit/MediaDevicesContext"; @@ -73,12 +73,13 @@ const mockCamera: MediaDeviceInfo = { }, }; -function mockDevices(available: Map): MediaDevice { +function mockDevices(available: Map): MediaDeviceHandle { return { available, selectedId: "", selectedGroupId: "", select: (): void => {}, + useAsEarpiece: false, }; } diff --git a/src/room/MuteStates.ts b/src/room/MuteStates.ts index e57ba7d5..6e24fb07 100644 --- a/src/room/MuteStates.ts +++ b/src/room/MuteStates.ts @@ -16,7 +16,7 @@ import { type IWidgetApiRequest } from "matrix-widget-api"; import { logger } from "matrix-js-sdk/lib/logger"; import { - type MediaDevice, + type MediaDeviceHandle, useMediaDevices, } from "../livekit/MediaDevicesContext"; import { useReactiveState } from "../useReactiveState"; @@ -53,7 +53,7 @@ export interface MuteStates { } function useMuteState( - device: MediaDevice, + device: MediaDeviceHandle, enabledByDefault: () => boolean, ): MuteState { const [enabled, setEnabled] = useReactiveState( diff --git a/src/room/ReactionAudioRenderer.test.tsx b/src/room/ReactionAudioRenderer.test.tsx index fa7df166..c61cbd82 100644 --- a/src/room/ReactionAudioRenderer.test.tsx +++ b/src/room/ReactionAudioRenderer.test.tsx @@ -21,8 +21,8 @@ import { act, type ReactNode } from "react"; import { ReactionsAudioRenderer } from "./ReactionAudioRenderer"; import { - playReactionsSound, - soundEffectVolumeSetting, + playReactionsSound as playReactionsSoundSetting, + soundEffectVolume as soundEffectVolumeSetting, } from "../settings/settings"; import { useAudioContext } from "../useAudioContext"; import { GenericReaction, ReactionSet } from "../reactions"; @@ -50,7 +50,7 @@ vitest.mock("../soundUtils"); afterEach(() => { vitest.resetAllMocks(); - playReactionsSound.setValue(playReactionsSound.defaultValue); + playReactionsSoundSetting.setValue(playReactionsSoundSetting.defaultValue); soundEffectVolumeSetting.setValue(soundEffectVolumeSetting.defaultValue); }); @@ -74,7 +74,7 @@ beforeEach(() => { test("preloads all audio elements", () => { const { vm } = getBasicCallViewModelEnvironment([local, alice]); - playReactionsSound.setValue(true); + playReactionsSoundSetting.setValue(true); render(); expect(prefetchSounds).toHaveBeenCalledOnce(); }); @@ -84,7 +84,7 @@ test("will play an audio sound when there is a reaction", () => { local, alice, ]); - playReactionsSound.setValue(true); + playReactionsSoundSetting.setValue(true); render(); // Find the first reaction with a sound effect @@ -110,7 +110,7 @@ test("will play the generic audio sound when there is soundless reaction", () => local, alice, ]); - playReactionsSound.setValue(true); + playReactionsSoundSetting.setValue(true); render(); // Find the first reaction with a sound effect @@ -136,7 +136,7 @@ test("will play multiple audio sounds when there are multiple different reaction local, alice, ]); - playReactionsSound.setValue(true); + playReactionsSoundSetting.setValue(true); render(); // Find the first reaction with a sound effect diff --git a/src/room/ReactionAudioRenderer.tsx b/src/room/ReactionAudioRenderer.tsx index c65f6094..2b95acb9 100644 --- a/src/room/ReactionAudioRenderer.tsx +++ b/src/room/ReactionAudioRenderer.tsx @@ -24,8 +24,10 @@ const soundMap = Object.fromEntries([ export function ReactionsAudioRenderer({ vm, + muted, }: { vm: CallViewModel; + muted?: boolean; }): ReactNode { const [shouldPlay] = useSetting(playReactionsSound); const [soundCache, setSoundCache] = useState rendering > renders 1`] = ` +
+
+
+
+ mocked: MatrixAudioRenderer +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+`; diff --git a/src/rtcSessionHelpers.ts b/src/rtcSessionHelpers.ts index 51bc79b8..e083b56c 100644 --- a/src/rtcSessionHelpers.ts +++ b/src/rtcSessionHelpers.ts @@ -121,10 +121,9 @@ export async function enterRTCSession( ...(useDeviceSessionMemberEvents !== undefined && { useLegacyMemberEvents: !useDeviceSessionMemberEvents, }), - membershipServerSideExpiryTimeout: + delayedLeaveEventDelayMs: matrixRtcSessionConfig?.membership_server_side_expiry_timeout, - membershipKeepAlivePeriod: - matrixRtcSessionConfig?.membership_keep_alive_period, + networkErrorRetryMs: matrixRtcSessionConfig?.membership_keep_alive_period, makeKeyDelay: matrixRtcSessionConfig?.key_rotation_on_leave_delay, useExperimentalToDeviceTransport, }, diff --git a/src/settings/DeveloperSettingsTab.tsx b/src/settings/DeveloperSettingsTab.tsx index 67de0e0d..36df5c39 100644 --- a/src/settings/DeveloperSettingsTab.tsx +++ b/src/settings/DeveloperSettingsTab.tsx @@ -15,8 +15,10 @@ import { debugTileLayout as debugTileLayoutSetting, showNonMemberTiles as showNonMemberTilesSetting, showConnectionStats as showConnectionStatsSetting, - useNewMembershipManagerSetting, - useExperimentalToDeviceTransportSetting, + useNewMembershipManager as useNewMembershipManagerSetting, + useExperimentalToDeviceTransport as useExperimentalToDeviceTransportSetting, + muteAllAudio as muteAllAudioSetting, + alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting, } from "./settings"; import type { MatrixClient } from "matrix-js-sdk"; import type { Room as LivekitRoom } from "livekit-client"; @@ -45,10 +47,16 @@ export const DeveloperSettingsTab: FC = ({ client, livekitRoom }) => { useNewMembershipManagerSetting, ); + const [alwaysShowIphoneEarpiece, setAlwaysShowIphoneEarpiece] = useSetting( + alwaysShowIphoneEarpieceSetting, + ); const [ useExperimentalToDeviceTransport, setUseExperimentalToDeviceTransport, ] = useSetting(useExperimentalToDeviceTransportSetting); + + const [muteAllAudio, setMuteAllAudio] = useSetting(muteAllAudioSetting); + const urlParams = useUrlParams(); const sfuUrl = useMemo((): URL | null => { @@ -175,6 +183,34 @@ export const DeveloperSettingsTab: FC = ({ client, livekitRoom }) => { )} /> + + ): void => { + setMuteAllAudio(event.target.checked); + }, + [setMuteAllAudio], + )} + /> + {" "} + + ): void => { + setAlwaysShowIphoneEarpiece(event.target.checked); + }, + [setAlwaysShowIphoneEarpiece], + )} + />{" "} + {livekitRoom ? ( <>

diff --git a/src/settings/DeviceSelection.tsx b/src/settings/DeviceSelection.tsx index 0bdabbe7..aee043c6 100644 --- a/src/settings/DeviceSelection.tsx +++ b/src/settings/DeviceSelection.tsx @@ -22,17 +22,20 @@ import { } from "@vector-im/compound-web"; import { Trans, useTranslation } from "react-i18next"; -import { type MediaDevice } from "../livekit/MediaDevicesContext"; +import { + EARPIECE_CONFIG_ID, + type MediaDeviceHandle, +} from "../livekit/MediaDevicesContext"; import styles from "./DeviceSelection.module.css"; interface Props { - devices: MediaDevice; + device: MediaDeviceHandle; title: string; numberedLabel: (number: number) => string; } export const DeviceSelection: FC = ({ - devices, + device, title, numberedLabel, }) => { @@ -40,12 +43,13 @@ export const DeviceSelection: FC = ({ const groupId = useId(); const onChange = useCallback( (e: ChangeEvent) => { - devices.select(e.target.value); + device.select(e.target.value); }, - [devices], + [device], ); - if (devices.available.size == 0) return null; + // There is no need to show the menu if there is no choice that can be made. + if (device.available.size <= 1) return null; return (

@@ -60,7 +64,7 @@ export const DeviceSelection: FC = ({
- {[...devices.available].map(([id, label]) => { + {[...device.available].map(([id, label]) => { let labelText: ReactNode; switch (label.type) { case "name": @@ -85,6 +89,16 @@ export const DeviceSelection: FC = ({ ); break; + case "earpiece": + labelText = t("settings.devices.earpiece"); + break; + } + + let isSelected = false; + if (device.useAsEarpiece) { + isSelected = id === EARPIECE_CONFIG_ID; + } else { + isSelected = id === device.selectedId; } return ( @@ -93,7 +107,7 @@ export const DeviceSelection: FC = ({ name={groupId} control={ diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx index de717b02..57463fc7 100644 --- a/src/settings/SettingsModal.tsx +++ b/src/settings/SettingsModal.tsx @@ -5,11 +5,12 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { type FC, useState } from "react"; +import { type FC, type ReactNode, useState } from "react"; import { useTranslation } from "react-i18next"; import { type MatrixClient } from "matrix-js-sdk"; -import { Root as Form } from "@vector-im/compound-web"; +import { Button, Root as Form, Separator } from "@vector-im/compound-web"; import { type Room as LivekitRoom } from "livekit-client"; +import { useObservableEagerState } from "observable-hooks"; import { Modal } from "../Modal"; import styles from "./SettingsModal.module.css"; @@ -19,18 +20,23 @@ import { FeedbackSettingsTab } from "./FeedbackSettingsTab"; import { useMediaDevices, useMediaDeviceNames, + iosDeviceMenu$, } from "../livekit/MediaDevicesContext"; import { widget } from "../widget"; import { useSetting, - soundEffectVolumeSetting, + soundEffectVolume as soundEffectVolumeSetting, + backgroundBlur as backgroundBlurSetting, developerMode, } from "./settings"; import { PreferencesSettingsTab } from "./PreferencesSettingsTab"; import { Slider } from "../Slider"; import { DeviceSelection } from "./DeviceSelection"; +import { useTrackProcessor } from "../livekit/TrackProcessorContext"; import { DeveloperSettingsTab } from "./DeveloperSettingsTab"; +import { FieldRow, InputField } from "../input/Input"; import { useSubmitRageshake } from "./submit-rageshake"; +import { useUrlParams } from "../UrlParams"; type SettingsTab = | "audio" @@ -64,33 +70,83 @@ export const SettingsModal: FC = ({ }) => { const { t } = useTranslation(); + // Generate a `Checkbox` input to turn blur on or off. + const BlurCheckbox: React.FC = (): ReactNode => { + const { supported } = useTrackProcessor(); + + const [blurActive, setBlurActive] = useSetting(backgroundBlurSetting); + + return ( + <> +

{t("settings.background_blur_header")}

+ + + setBlurActive(b.target.checked)} + disabled={!supported} + /> + + + ); + }; + const devices = useMediaDevices(); useMediaDeviceNames(devices, open); const [soundVolume, setSoundVolume] = useSetting(soundEffectVolumeSetting); const [soundVolumeRaw, setSoundVolumeRaw] = useState(soundVolume); - const [showDeveloperSettingsTab] = useSetting(developerMode); const { available: isRageshakeAvailable } = useSubmitRageshake(); + // For controlled devices, we will not show the input section: + // Controlled media devices are used on mobile platforms, where input and output are grouped into + // a single device. These are called "headset" or "speaker" (or similar) but contain both input and output. + // On EC, we decided that it is less confusing for the user if they see those options in the output section + // rather than the input section. + const { controlledAudioDevices } = useUrlParams(); + // If we are on iOS we will show a button to open the native audio device picker. + const iosDeviceMenu = useObservableEagerState(iosDeviceMenu$); + const audioTab: Tab = { key: "audio", name: t("common.audio"), content: ( <>
+ {!controlledAudioDevices && ( + + t("settings.devices.microphone_numbered", { n }) + } + /> + )} + {iosDeviceMenu && ( + + )} - t("settings.devices.microphone_numbered", { n }) - } - /> - t("settings.devices.speaker_numbered", { n })} /> +

{t("settings.audio_tab.effect_volume_description")}

@@ -113,13 +169,17 @@ export const SettingsModal: FC = ({ key: "video", name: t("common.video"), content: ( - - t("settings.devices.camera_numbered", { n })} - /> - + <> +
+ t("settings.devices.camera_numbered", { n })} + /> + + + + ), }; diff --git a/src/settings/rageshake.ts b/src/settings/rageshake.ts index 21ed5956..6c1a0f61 100644 --- a/src/settings/rageshake.ts +++ b/src/settings/rageshake.ts @@ -473,11 +473,6 @@ export async function init(): Promise { // configure loglevel based loggers: setLogExtension(logger, global.mx_rage_logger.log); - // these are the child/prefixed loggers we want to capture from js-sdk - // there doesn't seem to be an easy way to capture all children - ["MatrixRTCSession", "MatrixRTCSessionManager"].forEach((loggerName) => { - setLogExtension(logger.getChild(loggerName), global.mx_rage_logger.log); - }); // intercept console logging so that we can get matrix_sdk logs: // this is nasty, but no logging hooks are provided diff --git a/src/settings/settings.ts b/src/settings/settings.ts index 9f9f266c..50e70671 100644 --- a/src/settings/settings.ts +++ b/src/settings/settings.ts @@ -44,6 +44,9 @@ export class Setting { this._value$.next(value); localStorage.setItem(this.key, JSON.stringify(value)); }; + public readonly getValue = (): T => { + return this._value$.getValue(); + }; } /** @@ -96,6 +99,8 @@ export const videoInput = new Setting( undefined, ); +export const backgroundBlur = new Setting("background-blur", false); + export const showHandRaisedTimer = new Setting( "hand-raised-show-timer", false, @@ -108,19 +113,26 @@ export const playReactionsSound = new Setting( true, ); -export const soundEffectVolumeSetting = new Setting( +export const soundEffectVolume = new Setting( "sound-effect-volume", 0.5, ); -export const useNewMembershipManagerSetting = new Setting( +export const useNewMembershipManager = new Setting( "new-membership-manager", true, ); -export const useExperimentalToDeviceTransportSetting = new Setting( +export const useExperimentalToDeviceTransport = new Setting( "experimental-to-device-transport", true, ); +export const muteAllAudio = new Setting("mute-all-audio", false); + export const alwaysShowSelf = new Setting("always-show-self", true); + +export const alwaysShowIphoneEarpiece = new Setting( + "always-show-iphone-earpiece", + false, +); diff --git a/src/state/MuteAllAudioModel.test.ts b/src/state/MuteAllAudioModel.test.ts new file mode 100644 index 00000000..d7b4e0c4 --- /dev/null +++ b/src/state/MuteAllAudioModel.test.ts @@ -0,0 +1,36 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE in the repository root for full details. +*/ + +import { test, vi } from "vitest"; +import { expect } from "vitest"; + +import { setAudioEnabled$ } from "../controls"; +import { muteAllAudio as muteAllAudioSetting } from "../settings/settings"; +import { muteAllAudio$ } from "./MuteAllAudioModel"; + +test("muteAllAudio$", () => { + const valueMock = vi.fn(); + const muteAllAudio = muteAllAudio$.subscribe((value) => { + valueMock(value); + }); + + setAudioEnabled$.next(false); + setAudioEnabled$.next(true); + muteAllAudioSetting.setValue(false); + muteAllAudioSetting.setValue(true); + setAudioEnabled$.next(false); + + muteAllAudio.unsubscribe(); + + expect(valueMock).toHaveBeenCalledTimes(6); + expect(valueMock).toHaveBeenNthCalledWith(1, false); // startWith([false, muteAllAudioSetting.getValue()]); + expect(valueMock).toHaveBeenNthCalledWith(2, true); // setAudioEnabled$.next(false); + expect(valueMock).toHaveBeenNthCalledWith(3, false); // setAudioEnabled$.next(true); + expect(valueMock).toHaveBeenNthCalledWith(4, false); // muteAllAudioSetting.setValue(false); + expect(valueMock).toHaveBeenNthCalledWith(5, true); // muteAllAudioSetting.setValue(true); + expect(valueMock).toHaveBeenNthCalledWith(6, true); // setAudioEnabled$.next(false); +}); diff --git a/src/state/MuteAllAudioModel.ts b/src/state/MuteAllAudioModel.ts new file mode 100644 index 00000000..16f4a0ec --- /dev/null +++ b/src/state/MuteAllAudioModel.ts @@ -0,0 +1,19 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE in the repository root for full details. +*/ + +import { combineLatest, startWith } from "rxjs"; + +import { setAudioEnabled$ } from "../controls"; +import { muteAllAudio as muteAllAudioSetting } from "../settings/settings"; + +/** + * This can transition into sth more complete: `GroupCallViewModel.ts` + */ +export const muteAllAudio$ = combineLatest( + [setAudioEnabled$.pipe(startWith(true)), muteAllAudioSetting.value$], + (outputEnabled, settingsMute) => !outputEnabled || settingsMute, +); diff --git a/src/useAudioContext.test.tsx b/src/useAudioContext.test.tsx index 29949bf8..814df8e9 100644 --- a/src/useAudioContext.test.tsx +++ b/src/useAudioContext.test.tsx @@ -5,14 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { expect, test, vitest, afterEach } from "vitest"; +import { expect, vi, afterEach, beforeEach, test } from "vitest"; import { type FC } from "react"; import { render } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; +import userEvent, { type UserEvent } from "@testing-library/user-event"; +import { BrowserRouter } from "react-router-dom"; import { deviceStub, MediaDevicesContext } from "./livekit/MediaDevicesContext"; import { useAudioContext } from "./useAudioContext"; -import { soundEffectVolumeSetting } from "./settings/settings"; +import { soundEffectVolume as soundEffectVolumeSetting } from "./settings/settings"; const staticSounds = Promise.resolve({ aSound: new ArrayBuffer(0), @@ -38,62 +39,81 @@ const TestComponent: FC = () => { ); }; - -class MockAudioContext { - public static testContext: MockAudioContext; - - public constructor() { - MockAudioContext.testContext = this; - } - - public gain = vitest.mocked( - { - connect: () => {}, - gain: { - setValueAtTime: vitest.fn(), - }, - }, - true, +const TestComponentWrapper: FC = () => { + return ( + + + ); +}; - public setSinkId = vitest.fn().mockResolvedValue(undefined); - public decodeAudioData = vitest.fn().mockReturnValue(1); - public createBufferSource = vitest.fn().mockReturnValue( - vitest.mocked({ +const gainNode = vi.mocked( + { + connect: (node: AudioNode) => node, + gain: { + setValueAtTime: vi.fn(), + value: 1, + }, + }, + true, +); +const panNode = vi.mocked( + { + connect: (node: AudioNode) => node, + pan: { + setValueAtTime: vi.fn(), + value: 0, + }, + }, + true, +); +/** + * A shared audio context test instance. + * It can also be used to mock the `AudioContext` constructor in tests: + * `vi.stubGlobal("AudioContext", () => testAudioContext);` + */ +export const testAudioContext = { + gain: gainNode, + pan: panNode, + setSinkId: vi.fn().mockResolvedValue(undefined), + decodeAudioData: vi.fn().mockReturnValue(1), + createBufferSource: vi.fn().mockReturnValue( + vi.mocked({ connect: (v: unknown) => v, start: () => {}, addEventListener: (_name: string, cb: () => void) => cb(), }), - ); - public createGain = vitest.fn().mockReturnValue(this.gain); - public close = vitest.fn().mockResolvedValue(undefined); -} + ), + createGain: vi.fn().mockReturnValue(gainNode), + createStereoPanner: vi.fn().mockReturnValue(panNode), + close: vi.fn().mockResolvedValue(undefined), +}; +export const TestAudioContextConstructor = vi.fn(() => testAudioContext); + +let user: UserEvent; +beforeEach(() => { + vi.stubGlobal("AudioContext", TestAudioContextConstructor); + user = userEvent.setup(); +}); afterEach(() => { - vitest.unstubAllGlobals(); + vi.unstubAllGlobals(); + vi.clearAllMocks(); }); test("can play a single sound", async () => { - const user = userEvent.setup(); - vitest.stubGlobal("AudioContext", MockAudioContext); - const { findByText } = render(); + const { findByText } = render(); await user.click(await findByText("Valid sound")); - expect( - MockAudioContext.testContext.createBufferSource, - ).toHaveBeenCalledOnce(); + expect(testAudioContext.createBufferSource).toHaveBeenCalledOnce(); }); + test("will ignore sounds that are not registered", async () => { - const user = userEvent.setup(); - vitest.stubGlobal("AudioContext", MockAudioContext); - const { findByText } = render(); + const { findByText } = render(); await user.click(await findByText("Invalid sound")); - expect( - MockAudioContext.testContext.createBufferSource, - ).not.toHaveBeenCalled(); + expect(testAudioContext.createBufferSource).not.toHaveBeenCalled(); }); test("will use the correct device", () => { - vitest.stubGlobal("AudioContext", MockAudioContext); render( { selectedGroupId: "", available: new Map(), select: () => {}, + useAsEarpiece: false, }, videoInput: deviceStub, startUsingDeviceNames: () => {}, stopUsingDeviceNames: () => {}, }} > - + , ); - expect( - MockAudioContext.testContext.createBufferSource, - ).not.toHaveBeenCalled(); - expect(MockAudioContext.testContext.setSinkId).toHaveBeenCalledWith( - "chosen-device", - ); + expect(testAudioContext.createBufferSource).not.toHaveBeenCalled(); + expect(testAudioContext.setSinkId).toHaveBeenCalledWith("chosen-device"); }); test("will use the correct volume level", async () => { - const user = userEvent.setup(); - vitest.stubGlobal("AudioContext", MockAudioContext); soundEffectVolumeSetting.setValue(0.33); - const { findByText } = render(); + const { findByText } = render(); await user.click(await findByText("Valid sound")); - expect( - MockAudioContext.testContext.gain.gain.setValueAtTime, - ).toHaveBeenCalledWith(0.33, 0); + expect(testAudioContext.gain.gain.setValueAtTime).toHaveBeenCalledWith( + 0.33, + 0, + ); + expect(testAudioContext.pan.pan.setValueAtTime).toHaveBeenCalledWith(0, 0); +}); + +test("will use the pan if earpiece is selected", async () => { + const { findByText } = render( + {}, + useAsEarpiece: true, + }, + videoInput: deviceStub, + startUsingDeviceNames: () => {}, + stopUsingDeviceNames: () => {}, + }} + > + + , + ); + await user.click(await findByText("Valid sound")); + expect(testAudioContext.pan.pan.setValueAtTime).toHaveBeenCalledWith(1, 0); + + expect(testAudioContext.gain.gain.setValueAtTime).toHaveBeenCalledWith( + soundEffectVolumeSetting.getValue() * 0.1, + 0, + ); }); diff --git a/src/useAudioContext.tsx b/src/useAudioContext.tsx index d96b9fdc..23df0dbe 100644 --- a/src/useAudioContext.tsx +++ b/src/useAudioContext.tsx @@ -9,11 +9,15 @@ import { logger } from "matrix-js-sdk/lib/logger"; import { useState, useEffect } from "react"; import { - soundEffectVolumeSetting as effectSoundVolumeSetting, + soundEffectVolume as soundEffectVolumeSetting, useSetting, } from "./settings/settings"; -import { useMediaDevices } from "./livekit/MediaDevicesContext"; +import { + useEarpieceAudioConfig, + useMediaDevices, +} from "./livekit/MediaDevicesContext"; import { type PrefetchedSounds } from "./soundUtils"; +import { useUrlParams } from "./UrlParams"; /** * Play a sound though a given AudioContext. Will take @@ -28,12 +32,15 @@ async function playSound( ctx: AudioContext, buffer: AudioBuffer, volume: number, + stereoPan: number, ): Promise { const gain = ctx.createGain(); gain.gain.setValueAtTime(volume, 0); + const pan = ctx.createStereoPanner(); + pan.pan.setValueAtTime(stereoPan, 0); const src = ctx.createBufferSource(); src.buffer = buffer; - src.connect(gain).connect(ctx.destination); + src.connect(gain).connect(pan).connect(ctx.destination); const p = new Promise((r) => src.addEventListener("ended", () => r())); src.start(); return p; @@ -47,6 +54,7 @@ interface Props { */ sounds: PrefetchedSounds | null; latencyHint: AudioContextLatencyCategory; + muted?: boolean; } interface UseAudioContext { @@ -62,8 +70,9 @@ interface UseAudioContext { export function useAudioContext( props: Props, ): UseAudioContext | null { - const [effectSoundVolume] = useSetting(effectSoundVolumeSetting); - const devices = useMediaDevices(); + const [soundEffectVolume] = useSetting(soundEffectVolumeSetting); + const { audioOutput } = useMediaDevices(); + const { controlledAudioDevices } = useUrlParams(); const [audioContext, setAudioContext] = useState(); const [audioBuffers, setAudioBuffers] = useState>(); @@ -102,26 +111,37 @@ export function useAudioContext( // Update the sink ID whenever we change devices. useEffect(() => { - if (audioContext && "setSinkId" in audioContext) { + if ( + audioContext && + "setSinkId" in audioContext && + !controlledAudioDevices + ) { // https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/setSinkId // @ts-expect-error - setSinkId doesn't exist yet in types, maybe because it's not supported everywhere. - audioContext.setSinkId(devices.audioOutput.selectedId).catch((ex) => { + audioContext.setSinkId(audioOutput.selectedId).catch((ex) => { logger.warn("Unable to change sink for audio context", ex); }); } - }, [audioContext, devices]); + }, [audioContext, audioOutput.selectedId, controlledAudioDevices]); + const { pan: earpiecePan, volume: earpieceVolume } = useEarpieceAudioConfig(); // Don't return a function until we're ready. - if (!audioContext || !audioBuffers) { + if (!audioContext || !audioBuffers || props.muted) { return null; } + return { playSound: async (name): Promise => { if (!audioBuffers[name]) { logger.debug(`Tried to play a sound that wasn't buffered (${name})`); return; } - return playSound(audioContext, audioBuffers[name], effectSoundVolume); + return playSound( + audioContext, + audioBuffers[name], + soundEffectVolume * earpieceVolume, + earpiecePan, + ); }, }; } diff --git a/src/useLocalStorage.ts b/src/useLocalStorage.ts index b9ae562b..1394e0d3 100644 --- a/src/useLocalStorage.ts +++ b/src/useLocalStorage.ts @@ -42,6 +42,14 @@ export const useLocalStorage = ( }; export const setLocalStorageItem = (key: string, value: string): void => { + // Avoid unnecessary updates. Not avoiding them so can cause unexpected state updates across hooks. + // For instance: + // - In call view uses useRoomEncryptionSystem + // - This will set the key again. + // - All other instances of useRoomEncryptionSystem will now do a useMemo update of the e2eeSystem + // - because the dependency `storedPassword = useInternalRoomSharedKey(roomId);` would change. + if (localStorage.getItem(key) === value) return; + localStorage.setItem(key, value); localStorageBus.emit(key, value); }; diff --git a/src/utils/abortHandle.ts b/src/utils/abortHandle.ts new file mode 100644 index 00000000..f4bb2ef5 --- /dev/null +++ b/src/utils/abortHandle.ts @@ -0,0 +1,18 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE in the repository root for full details. +*/ + +export class AbortHandle { + public constructor(private aborted = false) {} + + public abort(): void { + this.aborted = true; + } + + public isAborted(): boolean { + return this.aborted; + } +} diff --git a/src/utils/test.ts b/src/utils/test.ts index 039b6983..51ed1ed2 100644 --- a/src/utils/test.ts +++ b/src/utils/test.ts @@ -27,8 +27,14 @@ import { type RemoteParticipant, type RemoteTrackPublication, type Room as LivekitRoom, + Track, } from "livekit-client"; import { randomUUID } from "crypto"; +import { + type RoomAndToDeviceEvents, + type RoomAndToDeviceEventsHandlerMap, +} from "matrix-js-sdk/lib/matrixrtc/RoomAndToDeviceKeyTransport"; +import { type TrackReference } from "@livekit/components-core"; import { LocalUserMediaViewModel, @@ -269,8 +275,8 @@ export function mockConfig(config: Partial = {}): void { } export class MockRTCSession extends TypedEventEmitter< - MatrixRTCSessionEvent, - MatrixRTCSessionEventHandlerMap + MatrixRTCSessionEvent | RoomAndToDeviceEvents, + MatrixRTCSessionEventHandlerMap & RoomAndToDeviceEventsHandlerMap > { public readonly statistics = { counters: {}, @@ -305,3 +311,24 @@ export class MockRTCSession extends TypedEventEmitter< return this; } } + +export const mockTrack = (identity: string): TrackReference => + ({ + participant: { + identity, + }, + publication: { + kind: Track.Kind.Audio, + source: "mic", + trackSid: "123", + track: { + attach: vi.fn(), + detach: vi.fn(), + setAudioContext: vi.fn(), + setWebAudioPlugins: vi.fn(), + setVolume: vi.fn(), + }, + }, + track: {}, + source: {}, + }) as unknown as TrackReference; diff --git a/tsconfig.json b/tsconfig.json index be12658e..41ca7f8b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "target": "es2022", "module": "es2022", "jsx": "react-jsx", - "lib": ["es2022", "dom", "dom.iterable"], + "lib": ["es2024", "dom", "dom.iterable"], // From Matrix-JS-SDK "strict": true, @@ -22,6 +22,9 @@ // These imports within @livekit/components-core and // @livekit/components-react are broken under the "bundler" module // resolution mode, so we need to resolve them manually + "livekit-client/dist/src/room/types": [ + "./node_modules/livekit-client/dist/src/room/types.d.ts" + ], "livekit-client/dist/src/room/Room": [ "./node_modules/livekit-client/dist/src/room/Room.d.ts" ], diff --git a/vite.config.js b/vite.config.js index 590f3c16..5b800f7a 100644 --- a/vite.config.js +++ b/vite.config.js @@ -11,8 +11,8 @@ import { createHtmlPlugin } from "vite-plugin-html"; import { codecovVitePlugin } from "@codecov/vite-plugin"; import { sentryVitePlugin } from "@sentry/vite-plugin"; import react from "@vitejs/plugin-react"; -import basicSsl from "@vitejs/plugin-basic-ssl"; import { realpathSync } from "fs"; +import * as fs from "node:fs"; // https://vitejs.dev/config/ export default defineConfig(({ mode, packageType }) => { @@ -24,7 +24,6 @@ export default defineConfig(({ mode, packageType }) => { process.env.VITE_PACKAGE = packageType ?? "full"; const plugins = [ react(), - basicSsl(), svgrPlugin({ svgrOptions: { // This enables ref forwarding on SVGR components, which is needed, for @@ -84,6 +83,10 @@ export default defineConfig(({ mode, packageType }) => { server: { port: 3000, fs: { allow }, + https: { + key: fs.readFileSync("./backend/dev_tls_m.localhost.key"), + cert: fs.readFileSync("./backend/dev_tls_m.localhost.crt"), + }, }, build: { sourcemap: true, diff --git a/yarn.lock b/yarn.lock index 95137dbd..d78d4cac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -104,33 +104,51 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.26.5, @babel/compat-data@npm:^7.26.8": +"@babel/code-frame@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.27.1" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10c0/5dd9a18baa5fce4741ba729acc3a3272c49c25cb8736c4b18e113099520e7ef7b545a4096a26d600e4416157e63e87d66db46aa3fbf0a5f2286da2705c12da00 + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.26.5": version: 7.26.8 resolution: "@babel/compat-data@npm:7.26.8" checksum: 10c0/66408a0388c3457fff1c2f6c3a061278dd7b3d2f0455ea29bb7b187fa52c60ae8b4054b3c0a184e21e45f0eaac63cf390737bc7504d1f4a088a6e7f652c068ca languageName: node linkType: hard -"@babel/core@npm:^7.16.5, @babel/core@npm:^7.18.5, @babel/core@npm:^7.21.3, @babel/core@npm:^7.26.0": - version: 7.26.9 - resolution: "@babel/core@npm:7.26.9" +"@babel/compat-data@npm:^7.27.2": + version: 7.27.3 + resolution: "@babel/compat-data@npm:7.27.3" + checksum: 10c0/5736c42c98e38c788c1c53e9bc7c1aa42cb3dd907f3fa2c26c5a123bc957eb3df69acb2f4e96c2f208eb164410d5beddd8b4249353a7ef6e5d6e6eb4292c3587 + languageName: node + linkType: hard + +"@babel/core@npm:^7.16.5, @babel/core@npm:^7.18.5, @babel/core@npm:^7.21.3, @babel/core@npm:^7.26.10": + version: 7.27.3 + resolution: "@babel/core@npm:7.27.3" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.26.2" - "@babel/generator": "npm:^7.26.9" - "@babel/helper-compilation-targets": "npm:^7.26.5" - "@babel/helper-module-transforms": "npm:^7.26.0" - "@babel/helpers": "npm:^7.26.9" - "@babel/parser": "npm:^7.26.9" - "@babel/template": "npm:^7.26.9" - "@babel/traverse": "npm:^7.26.9" - "@babel/types": "npm:^7.26.9" + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.27.3" + "@babel/helper-compilation-targets": "npm:^7.27.2" + "@babel/helper-module-transforms": "npm:^7.27.3" + "@babel/helpers": "npm:^7.27.3" + "@babel/parser": "npm:^7.27.3" + "@babel/template": "npm:^7.27.2" + "@babel/traverse": "npm:^7.27.3" + "@babel/types": "npm:^7.27.3" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10c0/ed7212ff42a9453765787019b7d191b167afcacd4bd8fec10b055344ef53fa0cc648c9a80159ae4ecf870016a6318731e087042dcb68d1a2a9d34eb290dc014b + checksum: 10c0/c6ada8f64d238f1cc166e21e5d056f96e976fc5132cc6f4ebaf5369bc5b1c62bc802756feed15240e0e8448a9a9434796b11af2f304b5aa3781f125b4928a6ba languageName: node linkType: hard @@ -147,16 +165,16 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.26.9": - version: 7.26.9 - resolution: "@babel/generator@npm:7.26.9" +"@babel/generator@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/generator@npm:7.27.3" dependencies: - "@babel/parser": "npm:^7.26.9" - "@babel/types": "npm:^7.26.9" + "@babel/parser": "npm:^7.27.3" + "@babel/types": "npm:^7.27.3" "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^3.0.2" - checksum: 10c0/6b78872128205224a9a9761b9ea7543a9a7902a04b82fc2f6801ead4de8f59056bab3fd17b1f834ca7b049555fc4c79234b9a6230dd9531a06525306050becad + checksum: 10c0/341622e17c61d008fc746b655ab95ef7febb543df8efb4148f57cf06e60ade1abe091ed7d6811df17b064d04d64f69bb7f35ab0654137116d55c54a73145a61a languageName: node linkType: hard @@ -169,7 +187,16 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.25.9, @babel/helper-compilation-targets@npm:^7.26.5": +"@babel/helper-annotate-as-pure@npm:^7.27.1": + version: 7.27.3 + resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" + dependencies: + "@babel/types": "npm:^7.27.3" + checksum: 10c0/94996ce0a05b7229f956033e6dcd69393db2b0886d0db6aff41e704390402b8cdcca11f61449cb4f86cfd9e61b5ad3a73e4fa661eeed7846b125bd1c33dbc633 + languageName: node + linkType: hard + +"@babel/helper-compilation-targets@npm:^7.22.6": version: 7.26.5 resolution: "@babel/helper-compilation-targets@npm:7.26.5" dependencies: @@ -182,24 +209,37 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.25.9": - version: 7.26.9 - resolution: "@babel/helper-create-class-features-plugin@npm:7.26.9" +"@babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/helper-compilation-targets@npm:7.27.2" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.25.9" - "@babel/helper-member-expression-to-functions": "npm:^7.25.9" - "@babel/helper-optimise-call-expression": "npm:^7.25.9" - "@babel/helper-replace-supers": "npm:^7.26.5" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9" - "@babel/traverse": "npm:^7.26.9" + "@babel/compat-data": "npm:^7.27.2" + "@babel/helper-validator-option": "npm:^7.27.1" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10c0/808620b350ac012f22163fd44c38ed8e05b24ce5d37bc4aa99a44e9724205f11efcef6b25ccfa5bb5de82ac32b899f1e939123c688f335d2851f4b8d70742233 + checksum: 10c0/f338fa00dcfea931804a7c55d1a1c81b6f0a09787e528ec580d5c21b3ecb3913f6cb0f361368973ce953b824d910d3ac3e8a8ee15192710d3563826447193ad1 languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.25.9": +"@babel/helper-create-class-features-plugin@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-create-class-features-plugin@npm:7.27.1" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-member-expression-to-functions": "npm:^7.27.1" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/helper-replace-supers": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/4ee199671d6b9bdd4988aa2eea4bdced9a73abfc831d81b00c7634f49a8fc271b3ceda01c067af58018eb720c6151322015d463abea7072a368ee13f35adbb4c + languageName: node + linkType: hard + +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6": version: 7.26.3 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.26.3" dependencies: @@ -212,6 +252,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-regexp-features-plugin@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.27.1" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + regexpu-core: "npm:^6.2.0" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/591fe8bd3bb39679cc49588889b83bd628d8c4b99c55bafa81e80b1e605a348b64da955e3fd891c4ba3f36fd015367ba2eadea22af6a7de1610fbb5bcc2d3df0 + languageName: node + linkType: hard + "@babel/helper-define-polyfill-provider@npm:^0.6.3": version: 0.6.3 resolution: "@babel/helper-define-polyfill-provider@npm:0.6.3" @@ -227,98 +280,95 @@ __metadata: languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-member-expression-to-functions@npm:7.25.9" +"@babel/helper-member-expression-to-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-member-expression-to-functions@npm:7.27.1" dependencies: - "@babel/traverse": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" - checksum: 10c0/e08c7616f111e1fb56f398365e78858e26e466d4ac46dff25921adc5ccae9b232f66e952a2f4162bbe336627ba336c7fd9eca4835b6548935973d3380d77eaff + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10c0/5762ad009b6a3d8b0e6e79ff6011b3b8fdda0fefad56cfa8bfbe6aa02d5a8a8a9680a45748fe3ac47e735a03d2d88c0a676e3f9f59f20ae9fadcc8d51ccd5a53 languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-module-imports@npm:7.25.9" +"@babel/helper-module-imports@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-module-imports@npm:7.27.1" dependencies: - "@babel/traverse": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" - checksum: 10c0/078d3c2b45d1f97ffe6bb47f61961be4785d2342a4156d8b42c92ee4e1b7b9e365655dd6cb25329e8fe1a675c91eeac7e3d04f0c518b67e417e29d6e27b6aa70 + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10c0/e00aace096e4e29290ff8648455c2bc4ed982f0d61dbf2db1b5e750b9b98f318bf5788d75a4f974c151bd318fd549e81dbcab595f46b14b81c12eda3023f51e8 languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.25.9, @babel/helper-module-transforms@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/helper-module-transforms@npm:7.26.0" +"@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/helper-module-transforms@npm:7.27.3" dependencies: - "@babel/helper-module-imports": "npm:^7.25.9" - "@babel/helper-validator-identifier": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" + "@babel/helper-module-imports": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.3" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/ee111b68a5933481d76633dad9cdab30c41df4479f0e5e1cc4756dc9447c1afd2c9473b5ba006362e35b17f4ebddd5fca090233bef8dfc84dca9d9127e56ec3a + checksum: 10c0/fccb4f512a13b4c069af51e1b56b20f54024bcf1591e31e978a30f3502567f34f90a80da6a19a6148c249216292a8074a0121f9e52602510ef0f32dbce95ca01 languageName: node linkType: hard -"@babel/helper-optimise-call-expression@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-optimise-call-expression@npm:7.25.9" +"@babel/helper-optimise-call-expression@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" dependencies: - "@babel/types": "npm:^7.25.9" - checksum: 10c0/90203e6607edeadd2a154940803fd616c0ed92c1013d6774c4b8eb491f1a5a3448b68faae6268141caa5c456e55e3ee49a4ed2bd7ddaf2365daea321c435914c + "@babel/types": "npm:^7.27.1" + checksum: 10c0/6b861e7fcf6031b9c9fc2de3cd6c005e94a459d6caf3621d93346b52774925800ca29d4f64595a5ceacf4d161eb0d27649ae385110ed69491d9776686fa488e6 languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.25.9, @babel/helper-plugin-utils@npm:^7.26.5": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.25.9": version: 7.26.5 resolution: "@babel/helper-plugin-utils@npm:7.26.5" checksum: 10c0/cdaba71d4b891aa6a8dfbe5bac2f94effb13e5fa4c2c487667fdbaa04eae059b78b28d85a885071f45f7205aeb56d16759e1bed9c118b94b16e4720ef1ab0f65 languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-remap-async-to-generator@npm:7.25.9" +"@babel/helper-plugin-utils@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-plugin-utils@npm:7.27.1" + checksum: 10c0/94cf22c81a0c11a09b197b41ab488d416ff62254ce13c57e62912c85700dc2e99e555225787a4099ff6bae7a1812d622c80fbaeda824b79baa10a6c5ac4cf69b + languageName: node + linkType: hard + +"@babel/helper-remap-async-to-generator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.25.9" - "@babel/helper-wrap-function": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-wrap-function": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/6798b562f2788210980f29c5ee96056d90dc73458c88af5bd32f9c82e28e01975588aa2a57bb866c35556bd9b76bac937e824ee63ba472b6430224b91b4879e9 + checksum: 10c0/5ba6258f4bb57c7c9fa76b55f416b2d18c867b48c1af4f9f2f7cd7cc933fe6da7514811d08ceb4972f1493be46f4b69c40282b811d1397403febae13c2ec57b5 languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.25.9, @babel/helper-replace-supers@npm:^7.26.5": - version: 7.26.5 - resolution: "@babel/helper-replace-supers@npm:7.26.5" +"@babel/helper-replace-supers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-replace-supers@npm:7.27.1" dependencies: - "@babel/helper-member-expression-to-functions": "npm:^7.25.9" - "@babel/helper-optimise-call-expression": "npm:^7.25.9" - "@babel/traverse": "npm:^7.26.5" + "@babel/helper-member-expression-to-functions": "npm:^7.27.1" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/b19b1245caf835207aaaaac3a494f03a16069ae55e76a2e1350b5acd560e6a820026997a8160e8ebab82ae873e8208759aa008eb8422a67a775df41f0a4633d4 + checksum: 10c0/4f2eaaf5fcc196580221a7ccd0f8873447b5d52745ad4096418f6101a1d2e712e9f93722c9a32bc9769a1dc197e001f60d6f5438d4dfde4b9c6a9e4df719354c languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-simple-access@npm:7.25.9" +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" dependencies: - "@babel/traverse": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" - checksum: 10c0/3f1bcdb88ee3883ccf86959869a867f6bbf8c4737cd44fb9f799c38e54f67474590bc66802500ae9fe18161792875b2cfb7ec15673f48ed6c8663f6d09686ca8 - languageName: node - linkType: hard - -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.25.9" - dependencies: - "@babel/traverse": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" - checksum: 10c0/09ace0c6156961624ac9524329ce7f45350bab94bbe24335cbe0da7dfaa1448e658771831983cb83fe91cf6635b15d0a3cab57c03b92657480bfb49fb56dd184 + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10c0/f625013bcdea422c470223a2614e90d2c1cc9d832e97f32ca1b4f82b34bb4aa67c3904cb4b116375d3b5b753acfb3951ed50835a1e832e7225295c7b0c24dff7 languageName: node linkType: hard @@ -329,6 +379,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-string-parser@npm:7.27.1" + checksum: 10c0/8bda3448e07b5583727c103560bcf9c4c24b3c1051a4c516d4050ef69df37bb9a4734a585fe12725b8c2763de0a265aa1e909b485a4e3270b7cfd3e4dbe4b602 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.24.7, @babel/helper-validator-identifier@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-identifier@npm:7.25.9" @@ -336,6 +393,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-identifier@npm:7.27.1" + checksum: 10c0/c558f11c4871d526498e49d07a84752d1800bf72ac0d3dad100309a2eaba24efbf56ea59af5137ff15e3a00280ebe588560534b0e894a4750f8b1411d8f78b84 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-option@npm:7.25.9" @@ -343,24 +407,31 @@ __metadata: languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-wrap-function@npm:7.25.9" - dependencies: - "@babel/template": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" - checksum: 10c0/b6627d83291e7b80df020f8ee2890c52b8d49272962cac0114ef90f189889c90f1027985873d1b5261a4e986e109b2754292dc112392f0b1fcbfc91cc08bd003 +"@babel/helper-validator-option@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-option@npm:7.27.1" + checksum: 10c0/6fec5f006eba40001a20f26b1ef5dbbda377b7b68c8ad518c05baa9af3f396e780bdfded24c4eef95d14bb7b8fd56192a6ed38d5d439b97d10efc5f1a191d148 languageName: node linkType: hard -"@babel/helpers@npm:^7.26.9": - version: 7.26.9 - resolution: "@babel/helpers@npm:7.26.9" +"@babel/helper-wrap-function@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-wrap-function@npm:7.27.1" dependencies: - "@babel/template": "npm:^7.26.9" - "@babel/types": "npm:^7.26.9" - checksum: 10c0/3d4dbc4a33fe4181ed810cac52318b578294745ceaec07e2f6ecccf6cda55d25e4bfcea8f085f333bf911c9e1fc13320248dd1d5315ab47ad82ce1077410df05 + "@babel/template": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10c0/c472f75c0951bc657ab0a117538c7c116566ae7579ed47ac3f572c42dc78bd6f1e18f52ebe80d38300c991c3fcaa06979e2f8864ee919369dabd59072288de30 + languageName: node + linkType: hard + +"@babel/helpers@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/helpers@npm:7.27.3" + dependencies: + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.27.3" + checksum: 10c0/b6c9a5bddcda88e39e87b15d7fed592828ed9b7b75e055bbc00212bbff2ba78d00d26358fbe878d7a052aebd3c33d39882b9e7f2ea9865180897b18efdfaf739 languageName: node linkType: hard @@ -409,62 +480,73 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.9" +"@babel/parser@npm:^7.27.2, @babel/parser@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/parser@npm:7.27.3" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10c0/7aab47fcbb8c1ddc195a3cd66609edcad54c5022f018db7de40185f0182950389690e953e952f117a1737b72f665ff02ad30de6c02b49b97f1d8f4ccdffedc34 + "@babel/types": "npm:^7.27.3" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/d96363c7548710ab9c28649cee752e2d0713ed25bf910923da45d2fbc67fed5bbdfb867274fec7d72437f4e910577d27c04e160da52d95f1b63fdf0b19035d26 languageName: node linkType: hard -"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.9" +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/3a652b3574ca62775c5f101f8457950edc540c3581226579125da535d67765f41ad7f0e6327f8efeb2540a5dad5bb0c60a89fb934af3f67472e73fb63612d004 + checksum: 10c0/7dfffa978ae1cd179641a7c4b4ad688c6828c2c58ec96b118c2fb10bc3715223de6b88bff1ebff67056bb5fccc568ae773e3b83c592a1b843423319f80c99ebd languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.9" +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/18fc9004104a150f9f5da9f3307f361bc3104d16778bb593b7523d5110f04a8df19a2587e6bdd5e726fb1d397191add45223f4f731bb556c33f14f2779d596e8 + checksum: 10c0/2cd7a55a856e5e59bbd9484247c092a41e0d9f966778e7019da324d9e0928892d26afc4fbb2ac3d76a3c5a631cd3cf0d72dd2653b44f634f6c663b9e6f80aacd languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.25.9" +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9" - "@babel/plugin-transform-optional-chaining": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/cf29835498c4a25bd470908528919729a0799b2ec94e89004929a5532c94a5e4b1a49bc5d6673a22e5afe05d08465873e14ee3b28c42eb3db489cdf5ca47c680 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/plugin-transform-optional-chaining": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.13.0 - checksum: 10c0/3f6c8781a2f7aa1791a31d2242399ca884df2ab944f90c020b6f112fb19f05fa6dad5be143d274dad1377e40415b63d24d5489faf5060b9c4a99e55d8f0c317c + checksum: 10c0/eddcd056f76e198868cbff883eb148acfade8f0890973ab545295df0c08e39573a72e65372bcc0b0bfadba1b043fe1aea6b0907d0b4889453ac154c404194ebc languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.9" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/02b365f0cc4df8b8b811c68697c93476da387841e5f153fe42766f34241b685503ea51110d5ed6df7132759820b93e48d9fa3743cffc091eed97c19f7e5fe272 + checksum: 10c0/b94e6c3fc019e988b1499490829c327a1067b4ddea8ad402f6d0554793c9124148c2125338c723661b6dff040951abc1f092afbf3f2d234319cd580b68e52445 languageName: node linkType: hard @@ -477,47 +559,47 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.26.0" +"@babel/plugin-syntax-import-assertions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/525b174e60b210d96c1744c1575fc2ddedcc43a479cba64a5344cf77bd0541754fc58120b5a11ff832ba098437bb05aa80900d1f49bb3d888c5e349a4a3a356e + checksum: 10c0/06a954ee672f7a7c44d52b6e55598da43a7064e80df219765c51c37a0692641277e90411028f7cae4f4d1dedeed084f0c453576fa421c35a81f1603c5e3e0146 languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.26.0" +"@babel/plugin-syntax-import-attributes@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e594c185b12bfe0bbe7ca78dfeebe870e6d569a12128cac86f3164a075fe0ff70e25ddbd97fd0782906b91f65560c9dc6957716b7b4a68aba2516c9b7455e352 + checksum: 10c0/e66f7a761b8360419bbb93ab67d87c8a97465ef4637a985ff682ce7ba6918b34b29d81190204cf908d0933058ee7b42737423cd8a999546c21b3aabad4affa9a languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-syntax-jsx@npm:7.25.9" +"@babel/plugin-syntax-jsx@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-jsx@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/d56597aff4df39d3decda50193b6dfbe596ca53f437ff2934622ce19a743bf7f43492d3fb3308b0289f5cee2b825d99ceb56526a2b9e7b68bf04901546c5618c + checksum: 10c0/bc5afe6a458d5f0492c02a54ad98c5756a0c13bd6d20609aae65acd560a9e141b0876da5f358dce34ea136f271c1016df58b461184d7ae9c4321e0f98588bc84 languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-syntax-typescript@npm:7.25.9" +"@babel/plugin-syntax-typescript@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-typescript@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5192ebe11bd46aea68b7a60fd9555465c59af7e279e71126788e59121b86e00b505816685ab4782abe159232b0f73854e804b54449820b0d950b397ee158caa2 + checksum: 10c0/11589b4c89c66ef02d57bf56c6246267851ec0c361f58929327dc3e070b0dab644be625bbe7fb4c4df30c3634bfdfe31244e1f517be397d2def1487dbbe3c37d languageName: node linkType: hard @@ -533,487 +615,475 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.25.9" +"@babel/plugin-transform-arrow-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/851fef9f58be60a80f46cc0ce1e46a6f7346a6f9d50fa9e0fa79d46ec205320069d0cc157db213e2bea88ef5b7d9bd7618bb83f0b1996a836e2426c3a3a1f622 + checksum: 10c0/19abd7a7d11eef58c9340408a4c2594503f6c4eaea1baa7b0e5fbdda89df097e50663edb3448ad2300170b39efca98a75e5767af05cad3b0facb4944326896a3 languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.26.8": - version: 7.26.8 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.26.8" +"@babel/plugin-transform-async-generator-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.26.5" - "@babel/helper-remap-async-to-generator": "npm:^7.25.9" - "@babel/traverse": "npm:^7.26.8" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-remap-async-to-generator": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/f6fefce963fe2e6268dde1958975d7adbce65fba94ca6f4bc554c90da03104ad1dd2e66d03bc0462da46868498428646e30b03a218ef0e5a84bfc87a7e375cec + checksum: 10c0/772e449c69ee42a466443acefb07083bd89efb1a1d95679a4dc99ea3be9d8a3c43a2b74d2da95d7c818e9dd9e0b72bfa7c03217a1feaf108f21b7e542f0943c0 languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.25.9" +"@babel/plugin-transform-async-to-generator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.27.1" dependencies: - "@babel/helper-module-imports": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-remap-async-to-generator": "npm:^7.25.9" + "@babel/helper-module-imports": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-remap-async-to-generator": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c443d9e462ddef733ae56360064f32fc800105803d892e4ff32d7d6a6922b3765fa97b9ddc9f7f1d3f9d8c2d95721d85bef9dbf507804214c6cf6466b105c168 + checksum: 10c0/e76b1f6f9c3bbf72e17d7639406d47f09481806de4db99a8de375a0bb40957ea309b20aa705f0c25ab1d7c845e3f365af67eafa368034521151a0e352a03ef2f languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.26.5": - version: 7.26.5 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.26.5" +"@babel/plugin-transform-block-scoped-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.26.5" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/2f3060800ead46b09971dd7bf830d66383b7bc61ced9945633b4ef9bf87787956ea83fcf49b387cecb377812588c6b81681714c760f9cf89ecba45edcbab1192 + checksum: 10c0/3313130ba3bf0699baad0e60da1c8c3c2f0c2c0a7039cd0063e54e72e739c33f1baadfc9d8c73b3fea8c85dd7250c3964fb09c8e1fa62ba0b24a9fefe0a8dbde languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-block-scoping@npm:7.25.9" +"@babel/plugin-transform-block-scoping@npm:^7.27.1": + version: 7.27.3 + resolution: "@babel/plugin-transform-block-scoping@npm:7.27.3" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/a76e30becb6c75b4d87a2cd53556fddb7c88ddd56bfadb965287fd944810ac159aa8eb5705366fc37336041f63154ed9fab3862fb10482a45bf5ede63fd55fda + checksum: 10c0/87c7f29e9d2b2991e5da0bf7f71aec3c863d7969b93888e2ad2dc95392574502a04120b8a04b18ff65c22ee09152254c06ce32fbb3001ce7cc1543e1994b86d0 languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-class-properties@npm:7.25.9" +"@babel/plugin-transform-class-properties@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-class-properties@npm:7.27.1" dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-class-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/f0603b6bd34d8ba62c03fc0572cb8bbc75874d097ac20cc7c5379e001081210a84dba1749e7123fca43b978382f605bb9973c99caf2c5b4c492d5c0a4a441150 + checksum: 10c0/cc0662633c0fe6df95819fef223506ddf26c369c8d64ab21a728d9007ec866bf9436a253909819216c24a82186b6ccbc1ec94d7aaf3f82df227c7c02fa6a704b languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-transform-class-static-block@npm:7.26.0" +"@babel/plugin-transform-class-static-block@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-class-static-block@npm:7.27.1" dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-class-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.12.0 - checksum: 10c0/cdcf5545ae6514ed75fbd73cccfa209c6a5dfdf0c2bb7bb62c0fb4ec334a32281bcf1bc16ace494d9dbe93feb8bdc0bd3cf9d9ccb6316e634a67056fa13b741b + checksum: 10c0/396997dd81fc1cf242b921e337d25089d6b9dc3596e81322ff11a6359326dc44f2f8b82dcc279c2e514cafaf8964dc7ed39e9fab4b8af1308b57387d111f6a20 languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-classes@npm:7.25.9" +"@babel/plugin-transform-classes@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-classes@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.25.9" - "@babel/helper-compilation-targets": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-replace-supers": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-compilation-targets": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-replace-supers": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" globals: "npm:^11.1.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/02742ea7cd25be286c982e672619effca528d7a931626a6f3d6cea11852951b7ee973276127eaf6418ac0e18c4d749a16b520709c707e86a67012bd23ff2927d + checksum: 10c0/1071f4cb1ed5deb5e6f8d0442f2293a540cac5caa5ab3c25ad0571aadcbf961f61e26d367a67894976165a543e02f3a19e40b63b909afbed6e710801a590635c languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-computed-properties@npm:7.25.9" +"@babel/plugin-transform-computed-properties@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/template": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/template": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/948c0ae3ce0ba2375241d122a9bc7cda4a7ac8110bd8a62cd804bc46a5fdb7a7a42c7799c4cd972e14e0a579d2bd0999b92e53177b73f240bb0d4b09972c758b + checksum: 10c0/e09a12f8c8ae0e6a6144c102956947b4ec05f6c844169121d0ec4529c2d30ad1dc59fee67736193b87a402f44552c888a519a680a31853bdb4d34788c28af3b0 languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-destructuring@npm:7.25.9" +"@babel/plugin-transform-destructuring@npm:^7.27.1, @babel/plugin-transform-destructuring@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/plugin-transform-destructuring@npm:7.27.3" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7beec5fda665d108f69d5023aa7c298a1e566b973dd41290faa18aeea70f6f571295c1ece0a058f3ceb6c6c96de76de7cd34f5a227fbf09a1b8d8a735d28ca49 + checksum: 10c0/f8ac96deef6f9a4cb1dff148dfa2a43116ca1c48434bba433964498c4ef5cef5557693b47463e64a71ffaaf10191c7fab0270844e8dbdc47dc4d120435025df5 languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.25.9" +"@babel/plugin-transform-dotall-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-regexp-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7c3471ae5cf7521fd8da5b03e137e8d3733fc5ee4524ce01fb0c812f0bb77cb2c9657bc8a6253186be3a15bb4caa8974993c7ddc067f554ecc6a026f0a3b5e12 + checksum: 10c0/f9caddfad9a551b4dabe0dcb7c040f458fbaaa7bbb44200c20198b32c8259be8e050e58d2c853fdac901a4cfe490b86aa857036d8d461b192dd010d0e242dedb languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.25.9" +"@babel/plugin-transform-duplicate-keys@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/d0c74894b9bf6ff2a04189afffb9cd43d87ebd7b7943e51a827c92d2aaa40fa89ac81565a2fd6fbeabf9e38413a9264c45862eee2b017f1d49046cc3c8ff06b4 + checksum: 10c0/22a822e5342b7066f83eaedc4fd9bb044ac6bc68725484690b33ba04a7104980e43ea3229de439286cb8db8e7db4a865733a3f05123ab58a10f189f03553746f languageName: node linkType: hard -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.9" +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-regexp-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/a8039a6d2b90e011c7b30975edee47b5b1097cf3c2f95ec1f5ddd029898d783a995f55f7d6eb8d6bb8873c060fb64f9f1ccba938dfe22d118d09cf68e0cd3bf6 + checksum: 10c0/121502a252b3206913e1e990a47fea34397b4cbf7804d4cd872d45961bc45b603423f60ca87f3a3023a62528f5feb475ac1c9ec76096899ec182fcb135eba375 languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-dynamic-import@npm:7.25.9" +"@babel/plugin-transform-dynamic-import@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5e643a8209072b668350f5788f23c64e9124f81f958b595c80fecca6561086d8ef346c04391b9e5e4cad8b8cbe22c258f0cd5f4ea89b97e74438e7d1abfd98cf + checksum: 10c0/8dcd3087aca134b064fc361d2cc34eec1f900f6be039b6368104afcef10bb75dea726bb18cabd046716b89b0edaa771f50189fa16bc5c5914a38cbcf166350f7 languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.26.3": - version: 7.26.3 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.26.3" +"@babel/plugin-transform-exponentiation-operator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/cac922e851c6a0831fdd2e3663564966916015aeff7f4485825fc33879cbc3a313ceb859814c9200248e2875d65bb13802a723e5d7d7b40a2e90da82a5a1e15c + checksum: 10c0/953d21e01fed76da8e08fb5094cade7bf8927c1bb79301916bec2db0593b41dbcfbca1024ad5db886b72208a93ada8f57a219525aad048cf15814eeb65cf760d languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-export-namespace-from@npm:7.25.9" +"@babel/plugin-transform-export-namespace-from@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/f291ea2ec5f36de9028a00cbd5b32f08af281b8183bf047200ff001f4cb260be56f156b2449f42149448a4a033bd6e86a3a7f06d0c2825532eb0ae6b03058dfb + checksum: 10c0/d7165cad11f571a54c8d9263d6c6bf2b817aff4874f747cb51e6e49efb32f2c9b37a6850cdb5e3b81e0b638141bb77dc782a6ec1a94128859fbdf7767581e07c languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.26.9": - version: 7.26.9 - resolution: "@babel/plugin-transform-for-of@npm:7.26.9" +"@babel/plugin-transform-for-of@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-for-of@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.26.5" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e28a521521cf9f84ddd69ca8da7c89fb9f7aa38e4dea35742fe973e4e1d7c23f9cee1a4861a2fdd9e9f18ff945886a44d7335cea1c603b96bfcb1c7c8791ef09 + checksum: 10c0/4635763173a23aae24480681f2b0996b4f54a0cb2368880301a1801638242e263132d1e8adbe112ab272913d1d900ee0d6f7dea79443aef9d3325168cd88b3fb languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-function-name@npm:7.25.9" +"@babel/plugin-transform-function-name@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-function-name@npm:7.27.1" dependencies: - "@babel/helper-compilation-targets": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" + "@babel/helper-compilation-targets": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/8e67fbd1dd367927b8b6afdf0a6e7cb3a3fd70766c52f700ca77428b6d536f6c9d7ec643e7762d64b23093233765c66bffa40e31aabe6492682879bcb45423e1 + checksum: 10c0/5abdc7b5945fbd807269dcc6e76e52b69235056023b0b35d311e8f5dfd6c09d9f225839798998fc3b663f50cf701457ddb76517025a0d7a5474f3fe56e567a4c languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-json-strings@npm:7.25.9" +"@babel/plugin-transform-json-strings@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-json-strings@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/00bc2d4751dfc9d44ab725be16ee534de13cfd7e77dfb386e5dac9e48101ce8fcbc5971df919dc25b3f8a0fa85d6dc5f2a0c3cf7ec9d61c163d9823c091844f0 + checksum: 10c0/2379714aca025516452a7c1afa1ca42a22b9b51a5050a653cc6198a51665ab82bdecf36106d32d731512706a1e373c5637f5ff635737319aa42f3827da2326d6 languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-literals@npm:7.25.9" +"@babel/plugin-transform-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-literals@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/00b14e9c14cf1e871c1f3781bf6334cac339c360404afd6aba63d2f6aca9270854d59a2b40abff1c4c90d4ffdca614440842d3043316c2f0ceb155fdf7726b3b + checksum: 10c0/c40dc3eb2f45a92ee476412314a40e471af51a0f51a24e91b85cef5fc59f4fe06758088f541643f07f949d2c67ee7bdce10e11c5ec56791ae09b15c3b451eeca languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.25.9" +"@babel/plugin-transform-logical-assignment-operators@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/6e2051e10b2d6452980fc4bdef9da17c0d6ca48f81b8529e8804b031950e4fff7c74a7eb3de4a2b6ad22ffb631d0b67005425d232cce6e2b29ce861c78ed04f5 + checksum: 10c0/5b0abc7c0d09d562bf555c646dce63a30288e5db46fd2ce809a61d064415da6efc3b2b3c59b8e4fe98accd072c89a2f7c3765b400e4bf488651735d314d9feeb languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.25.9" +"@babel/plugin-transform-member-expression-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/91d17b451bcc5ea9f1c6f8264144057ade3338d4b92c0b248366e4db3a7790a28fd59cc56ac433a9627a9087a17a5684e53f4995dd6ae92831cb72f1bd540b54 + checksum: 10c0/0874ccebbd1c6a155e5f6b3b29729fade1221b73152567c1af1e1a7c12848004dffecbd7eded6dc463955120040ae57c17cb586b53fb5a7a27fcd88177034c30 languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-modules-amd@npm:7.25.9" +"@babel/plugin-transform-modules-amd@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-amd@npm:7.27.1" dependencies: - "@babel/helper-module-transforms": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-module-transforms": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/849957d9484d0a2d93331226ed6cf840cee7d57454549534c447c93f8b839ef8553eae9877f8f550e3c39f14d60992f91244b2e8e7502a46064b56c5d68ba855 + checksum: 10c0/76e86cd278b6a3c5b8cca8dfb3428e9cd0c81a5df7096e04c783c506696b916a9561386d610a9d846ef64804640e0bd818ea47455fed0ee89b7f66c555b29537 languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.25.9" +"@babel/plugin-transform-modules-commonjs@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.27.1" dependencies: - "@babel/helper-module-transforms": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-simple-access": "npm:^7.25.9" + "@babel/helper-module-transforms": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/6ce771fb04d4810257fc8900374fece877dacaed74b05eaa16ad9224b390f43795c4d046cbe9ae304e1eb5aad035d37383895e3c64496d647c2128d183916e74 + checksum: 10c0/4def972dcd23375a266ea1189115a4ff61744b2c9366fc1de648b3fab2c650faf1a94092de93a33ff18858d2e6c4dddeeee5384cb42ba0129baeab01a5cdf1e2 languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.26.3": - version: 7.26.3 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.26.3" +"@babel/plugin-transform-modules-systemjs@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.27.1" dependencies: - "@babel/helper-module-transforms": "npm:^7.26.0" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-module-transforms": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/82e59708f19f36da29531a64a7a94eabbf6ff46a615e0f5d9b49f3f59e8ef10e2bac607d749091508d3fa655146c9e5647c3ffeca781060cdabedb4c7a33c6f2 + checksum: 10c0/f16fca62d144d9cbf558e7b5f83e13bb6d0f21fdeff3024b0cecd42ffdec0b4151461da42bd0963512783ece31aafa5ffe03446b4869220ddd095b24d414e2b5 languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.9" +"@babel/plugin-transform-modules-umd@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-umd@npm:7.27.1" dependencies: - "@babel/helper-module-transforms": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-validator-identifier": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" + "@babel/helper-module-transforms": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/8299e3437542129c2684b86f98408c690df27db4122a79edded4782cf04e755d6ecb05b1e812c81a34224a81e664303392d5f3c36f3d2d51fdc99bb91c881e9a + checksum: 10c0/e5962a8874889da2ab1aa32eb93ec21d419c7423c766e4befb39b4bb512b9ad44b47837b6cd1c8f1065445cbbcc6dc2be10298ac6e734e5ca1059fc23698daed languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-modules-umd@npm:7.25.9" +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.27.1" dependencies: - "@babel/helper-module-transforms": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/fa11a621f023e2ac437b71d5582f819e667c94306f022583d77da9a8f772c4128861a32bbb63bef5cba581a70cd7dbe87a37238edaafcfacf889470c395e7076 - languageName: node - linkType: hard - -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.25.9" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-regexp-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/32b14fda5c885d1706863f8af2ee6c703d39264355b57482d3a24fce7f6afbd4c7a0896e501c0806ed2b0759beb621bf7f3f7de1fbbc82026039a98d961e78ef + checksum: 10c0/8eaa8c9aee00a00f3bd8bd8b561d3f569644d98cb2cfe3026d7398aabf9b29afd62f24f142b4112fa1f572d9b0e1928291b099cde59f56d6b59f4d565e58abf2 languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-new-target@npm:7.25.9" +"@babel/plugin-transform-new-target@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-new-target@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7b5f1b7998f1cf183a7fa646346e2f3742e5805b609f28ad5fee22d666a15010f3e398b7e1ab78cddb7901841a3d3f47135929af23d54e8bf4ce69b72051f71e + checksum: 10c0/9b0581412fcc5ab1b9a2d86a0c5407bd959391f0a1e77a46953fef9f7a57f3f4020d75f71098c5f9e5dcc680a87f9fd99b3205ab12e25ef8c19eed038c1e4b28 languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.26.6": - version: 7.26.6 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.26.6" +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.26.5" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/574d6db7cbc5c092db5d1dece8ce26195e642b9c40dbfeaf3082058a78ad7959c1c333471cdd45f38b784ec488850548075d527b178c5010ee9bff7aa527cc7a + checksum: 10c0/a435fc03aaa65c6ef8e99b2d61af0994eb5cdd4a28562d78c3b0b0228ca7e501aa255e1dff091a6996d7d3ea808eb5a65fd50ecd28dfb10687a8a1095dcadc7a languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-numeric-separator@npm:7.25.9" +"@babel/plugin-transform-numeric-separator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/ad63ad341977844b6f9535fcca15ca0d6d6ad112ed9cc509d4f6b75e9bf4b1b1a96a0bcb1986421a601505d34025373608b5f76d420d924b4e21f86b1a1f2749 + checksum: 10c0/b72cbebbfe46fcf319504edc1cf59f3f41c992dd6840db766367f6a1d232cd2c52143c5eaf57e0316710bee251cae94be97c6d646b5022fcd9274ccb131b470c languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.25.9" +"@babel/plugin-transform-object-rest-spread@npm:^7.27.2": + version: 7.27.3 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.27.3" dependencies: - "@babel/helper-compilation-targets": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/plugin-transform-parameters": "npm:^7.25.9" + "@babel/helper-compilation-targets": "npm:^7.27.2" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/plugin-transform-destructuring": "npm:^7.27.3" + "@babel/plugin-transform-parameters": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/02077d8abd83bf6a48ff0b59e98d7561407cf75b591cffd3fdc5dc5e9a13dec1c847a7a690983762a3afecddb244831e897e0515c293e7c653b262c30cd614af + checksum: 10c0/f2d04f59f773a9480bbaabd082fecdb5fb2b6ae5e77147ae8df34a8b773b6148d0c4260d2beaa4755eb5f548a105f2069124b9cea96f9387128656cbb0730ee4 languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-object-super@npm:7.25.9" +"@babel/plugin-transform-object-super@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-object-super@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-replace-supers": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-replace-supers": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/0348d00e76f1f15ada44481a76e8c923d24cba91f6e49ee9b30d6861eb75344e7f84d62a18df8a6f9e9a7eacf992f388174b7f9cc4ce48287bcefca268c07600 + checksum: 10c0/efa2d092ef55105deb06d30aff4e460c57779b94861188128489b72378bf1f0ab0f06a4a4d68b9ae2a59a79719fbb2d148b9a3dca19ceff9c73b1f1a95e0527c languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.25.9" +"@babel/plugin-transform-optional-catch-binding@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/722fd5ee12ab905309d4e84421584fce4b6d9e6b639b06afb20b23fa809e6ab251e908a8d5e8b14d066a28186b8ef8f58d69fd6eca9ce1b9ef7af08333378f6c + checksum: 10c0/807a4330f1fac08e2682d57bc82e714868fc651c8876f9a8b3a3fd8f53c129e87371f8243e712ac7dae11e090b737a2219a02fe1b6459a29e664fa073c3277bb languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.25.9" +"@babel/plugin-transform-optional-chaining@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/041ad2beae5affb8e68a0bcb6882a2dadb758db3c629a0e012f57488ab43a822ac1ea17a29db8ef36560a28262a5dfa4dbbbf06ed6e431db55abe024b7cd3961 + checksum: 10c0/5b18ff5124e503f0a25d6b195be7351a028b3992d6f2a91fb4037e2a2c386400d66bc1df8f6df0a94c708524f318729e81a95c41906e5a7919a06a43e573a525 languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-parameters@npm:7.25.9" +"@babel/plugin-transform-parameters@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-parameters@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/aecb446754b9e09d6b6fa95fd09e7cf682f8aaeed1d972874ba24c0a30a7e803ad5f014bb1fffc7bfeed22f93c0d200947407894ea59bf7687816f2f464f8df3 + checksum: 10c0/453a9618735eeff5551d4c7f02c250606586fe1dd210ec9f69a4f15629ace180cd944339ebff2b0f11e1a40567d83a229ba1c567620e70b2ebedea576e12196a languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-private-methods@npm:7.25.9" +"@babel/plugin-transform-private-methods@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-private-methods@npm:7.27.1" dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-class-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/64bd71de93d39daefa3e6c878d6f2fd238ed7d4ecfb13b0e771ddbbc131487def3ceb405b62b534a5cbb5043046b504e1b189b0a45229cc75af979a9fbcaa7bd + checksum: 10c0/232bedfe9d28df215fb03cc7623bdde468b1246bdd6dc24465ff4bf9cc5f5a256ae33daea1fafa6cc59705e4d29da9024bb79baccaa5cd92811ac5db9b9244f2 languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-private-property-in-object@npm:7.25.9" +"@babel/plugin-transform-private-property-in-object@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.25.9" - "@babel/helper-create-class-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-create-class-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/d4965de19d9f204e692cc74dbc39f0bb469e5f29df96dd4457ea23c5e5596fba9d5af76eaa96f9d48a9fc20ec5f12a94c679285e36b8373406868ea228109e27 + checksum: 10c0/a8c4536273ca716dcc98e74ea25ca76431528554922f184392be3ddaf1761d4aa0e06f1311577755bd1613f7054fb51d29de2ada1130f743d329170a1aa1fe56 languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-property-literals@npm:7.25.9" +"@babel/plugin-transform-property-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-property-literals@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/1639e35b2438ccf3107af760d34e6a8e4f9acdd3ae6186ae771a6e3029bd59dfe778e502d67090f1185ecda5c16addfed77561e39c518a3f51ff10d41790e106 + checksum: 10c0/15713a87edd6db620d6e66eb551b4fbfff5b8232c460c7c76cedf98efdc5cd21080c97040231e19e06594c6d7dfa66e1ab3d0951e29d5814fb25e813f6d6209c languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-react-display-name@npm:7.25.9" +"@babel/plugin-transform-react-display-name@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-display-name@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/63a0f962d64e71baf87c212755419e25c637d2d95ea6fdc067df26b91e606ae186442ae815b99a577eca9bf5404d9577ecad218a3cf42d0e9e286ca7b003a992 + checksum: 10c0/6cd474b5fb30a2255027d8fc19975aee1c1da54dd8bc8b79802676096182ca4136302ce65a24fbb277f8fe30f266006bbf327ef6be2846d3681eb57509744125 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-development@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-react-jsx-development@npm:7.25.9" +"@babel/plugin-transform-react-jsx-development@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.27.1" dependencies: - "@babel/plugin-transform-react-jsx": "npm:^7.25.9" + "@babel/plugin-transform-react-jsx": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c0b92ff9eb029620abf320ff74aae182cea87524723d740fb48a4373d0d16bddf5edbe1116e7ba341332a5337e55c2ceaee8b8cad5549e78af7f4b3cfe77debb + checksum: 10c0/eb8c4b6a79dc5c49b41e928e2037e1ee0bbfa722e4fd74c0b7c0d11103c82c2c25c434000e1b051d534c7261ab5c92b6d1e85313bf1b26e37db3f051ae217b58 languageName: node linkType: hard @@ -1039,253 +1109,252 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-react-jsx@npm:7.25.9" +"@babel/plugin-transform-react-jsx@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-jsx@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.25.9" - "@babel/helper-module-imports": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/plugin-syntax-jsx": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-module-imports": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/plugin-syntax-jsx": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5c9947e8ed141f7606f54da3e05eea1074950c5b8354c39df69cb7f43cb5a83c6c9d7973b24bc3d89341c8611f8ad50830a98ab10d117d850e6bdd8febdce221 + checksum: 10c0/1a08637c39fc78c9760dd4a3ed363fdbc762994bf83ed7872ad5bda0232fcd0fc557332f2ce36b522c0226dfd9cc8faac6b88eddda535f24825198a689e571af languageName: node linkType: hard -"@babel/plugin-transform-react-pure-annotations@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.25.9" +"@babel/plugin-transform-react-pure-annotations@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7c8eac04644ad19dcd71bb8e949b0ae22b9e548fa4a58e545d3d0342f647fb89db7f8789a7c5b8074d478ce6d3d581eaf47dd4b36027e16fd68211c383839abc + checksum: 10c0/34bc090f4a7e460d82a851971b4d0f32e4bb519bafb927154f4174506283fe02b0f471fc20655c6050a8bf7b748bfa31c7e8f7d688849476d8266623554fbb28 languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-regenerator@npm:7.25.9" +"@babel/plugin-transform-regenerator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-regenerator@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - regenerator-transform: "npm:^0.15.2" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/eef3ffc19f7d291b863635f32b896ad7f87806d9219a0d3404a470219abcfc5b43aabecd691026c48e875b965760d9c16abee25e6447272233f30cd07f453ec7 + checksum: 10c0/42395908899310bb107d9ca31ebd4c302e14c582e3ad3ebfe1498fabafc43155c8f10850265c1e686a2afcf50d1f402cc5c5218fba72e167852607a4d8d6492e languageName: node linkType: hard -"@babel/plugin-transform-regexp-modifiers@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.26.0" +"@babel/plugin-transform-regexp-modifiers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-regexp-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/4abc1db6c964efafc7a927cda814c7275275afa4b530483e0936fd614de23cb5802f7ca43edaa402008a723d4e7eac282b6f5283aa2eeb3b27da6d6c1dd7f8ed + checksum: 10c0/31ae596ab56751cf43468a6c0a9d6bc3521d306d2bee9c6957cdb64bea53812ce24bd13a32f766150d62b737bca5b0650b2c62db379382fff0dccbf076055c33 languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-reserved-words@npm:7.25.9" +"@babel/plugin-transform-reserved-words@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-reserved-words@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/8b028b80d1983e3e02f74e21924323cc66ba930e5c5758909a122aa7d80e341b8b0f42e1698e42b50d47a6ba911332f584200b28e1a4e2104b7514d9dc011e96 + checksum: 10c0/e1a87691cce21a644a474d7c9a8107d4486c062957be32042d40f0a3d0cc66e00a3150989655019c255ff020d2640ac16aaf544792717d586f219f3bad295567 languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.25.9" +"@babel/plugin-transform-shorthand-properties@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/05a20d45f0fb62567644c507ccd4e379c1a74dacf887d2b2cac70247415e3f6d7d3bf4850c8b336053144715fedb6200fc38f7130c4b76c94eec9b9c0c2a8e9b + checksum: 10c0/bd5544b89520a22c41a6df5ddac9039821d3334c0ef364d18b0ba9674c5071c223bcc98be5867dc3865cb10796882b7594e2c40dedaff38e1b1273913fe353e1 languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-spread@npm:7.25.9" +"@babel/plugin-transform-spread@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-spread@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/996c8fed238efc30e0664f9f58bd7ec8c148f4659f84425f68923a094fe891245711d26eb10d1f815f50c124434e076e860dbe9662240844d1b77cd09907dcdf + checksum: 10c0/b34fc58b33bd35b47d67416655c2cbc8578fbb3948b4592bc15eb6d8b4046986e25c06e3b9929460fa4ab08e9653582415e7ef8b87d265e1239251bdf5a4c162 languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.25.9" +"@babel/plugin-transform-sticky-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e9612b0615dab4c4fba1c560769616a9bd7b9226c73191ef84b6c3ee185c8b719b4f887cdd8336a0a13400ce606ab4a0d33bc8fa6b4fcdb53e2896d07f2568f6 + checksum: 10c0/5698df2d924f0b1b7bdb7ef370e83f99ed3f0964eb3b9c27d774d021bee7f6d45f9a73e2be369d90b4aff1603ce29827f8743f091789960e7669daf9c3cda850 languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.26.8": - version: 7.26.8 - resolution: "@babel/plugin-transform-template-literals@npm:7.26.8" +"@babel/plugin-transform-template-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-template-literals@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.26.5" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/205a938ded9554857a604416d369023a961334b6c20943bd861b45f0e5dbbeca1cf6fda1c2049126e38a0d18865993433fdc78eae3028e94836b3b643c08ba0d + checksum: 10c0/c90f403e42ef062b60654d1c122c70f3ec6f00c2f304b0931ebe6d0b432498ef8a5ef9266ddf00debc535f8390842207e44d3900eff1d2bab0cc1a700f03e083 languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.26.7": - version: 7.26.7 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.26.7" +"@babel/plugin-transform-typeof-symbol@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.26.5" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/d5640e3457637e6eee1d7205d255602ccca124ed30e4de10ec75ba179d167e0a826ceeab424e119921f5c995dfddf39ef1f2c91efd2dcbf3f0dc1e7931dfd1d1 + checksum: 10c0/a13c68015311fefa06a51830bc69d5badd06c881b13d5cf9ba04bf7c73e3fc6311cc889e18d9645ce2a64a79456dc9c7be88476c0b6802f62a686cb6f662ecd6 languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-typescript@npm:7.25.9" +"@babel/plugin-transform-typescript@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-typescript@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.25.9" - "@babel/helper-create-class-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.25.9" - "@babel/plugin-syntax-typescript": "npm:^7.25.9" + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-create-class-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/plugin-syntax-typescript": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c607ddb45f7e33cfcb928aad05cb1b18b1ecb564d2329d8f8e427f75192511aa821dee42d26871f1bdffbd883853e150ba81436664646c6e6b13063e65ce1475 + checksum: 10c0/48f1db5de17a0f9fc365ff4fb046010aedc7aad813a7aa42fb73fcdab6442f9e700dde2cc0481086e01b0dae662ae4d3e965a52cde154f0f146d243a8ac68e93 languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.25.9" +"@babel/plugin-transform-unicode-escapes@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/615c84d7c53e1575d54ba9257e753e0b98c5de1e3225237d92f55226eaab8eb5bceb74df43f50f4aa162b0bbcc934ed11feafe2b60b8ec4934ce340fad4b8828 + checksum: 10c0/a6809e0ca69d77ee9804e0c1164e8a2dea5e40718f6dcf234aeddf7292e7414f7ee331d87f17eb6f160823a329d1d6751bd49b35b392ac4a6efc032e4d3038d8 languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.25.9" +"@babel/plugin-transform-unicode-property-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-regexp-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/1685836fc38af4344c3d2a9edbd46f7c7b28d369b63967d5b83f2f6849ec45b97223461cea3d14cc3f0be6ebb284938e637a5ca3955c0e79c873d62f593d615c + checksum: 10c0/a332bc3cb3eeea67c47502bc52d13a0f8abae5a7bfcb08b93a8300ddaff8d9e1238f912969494c1b494c1898c6f19687054440706700b6d12cb0b90d88beb4d0 languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.25.9" +"@babel/plugin-transform-unicode-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-regexp-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/448004f978279e726af26acd54f63f9002c9e2582ecd70d1c5c4436f6de490fcd817afb60016d11c52f5ef17dbaac2590e8cc7bfaf4e91b58c452cf188c7920f + checksum: 10c0/6abda1bcffb79feba6f5c691859cdbe984cc96481ea65d5af5ba97c2e843154005f0886e25006a37a2d213c0243506a06eaeafd93a040dbe1f79539016a0d17a languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.9" +"@babel/plugin-transform-unicode-sets-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" + "@babel/helper-create-regexp-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/56ee04fbe236b77cbcd6035cbf0be7566d1386b8349154ac33244c25f61170c47153a9423cd1d92855f7d6447b53a4a653d9e8fd1eaeeee14feb4b2baf59bd9f + checksum: 10c0/236645f4d0a1fba7c18dc8ffe3975933af93e478f2665650c2d91cf528cfa1587cde5cfe277e0e501fc03b5bf57638369575d6539cef478632fb93bd7d7d7178 languageName: node linkType: hard "@babel/preset-env@npm:^7.22.20": - version: 7.26.9 - resolution: "@babel/preset-env@npm:7.26.9" + version: 7.27.2 + resolution: "@babel/preset-env@npm:7.27.2" dependencies: - "@babel/compat-data": "npm:^7.26.8" - "@babel/helper-compilation-targets": "npm:^7.26.5" - "@babel/helper-plugin-utils": "npm:^7.26.5" - "@babel/helper-validator-option": "npm:^7.25.9" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.9" - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.9" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.9" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.25.9" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.9" + "@babel/compat-data": "npm:^7.27.2" + "@babel/helper-compilation-targets": "npm:^7.27.2" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-validator-option": "npm:^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.27.1" + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.27.1" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.27.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.27.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.27.1" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions": "npm:^7.26.0" - "@babel/plugin-syntax-import-attributes": "npm:^7.26.0" + "@babel/plugin-syntax-import-assertions": "npm:^7.27.1" + "@babel/plugin-syntax-import-attributes": "npm:^7.27.1" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" - "@babel/plugin-transform-arrow-functions": "npm:^7.25.9" - "@babel/plugin-transform-async-generator-functions": "npm:^7.26.8" - "@babel/plugin-transform-async-to-generator": "npm:^7.25.9" - "@babel/plugin-transform-block-scoped-functions": "npm:^7.26.5" - "@babel/plugin-transform-block-scoping": "npm:^7.25.9" - "@babel/plugin-transform-class-properties": "npm:^7.25.9" - "@babel/plugin-transform-class-static-block": "npm:^7.26.0" - "@babel/plugin-transform-classes": "npm:^7.25.9" - "@babel/plugin-transform-computed-properties": "npm:^7.25.9" - "@babel/plugin-transform-destructuring": "npm:^7.25.9" - "@babel/plugin-transform-dotall-regex": "npm:^7.25.9" - "@babel/plugin-transform-duplicate-keys": "npm:^7.25.9" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.9" - "@babel/plugin-transform-dynamic-import": "npm:^7.25.9" - "@babel/plugin-transform-exponentiation-operator": "npm:^7.26.3" - "@babel/plugin-transform-export-namespace-from": "npm:^7.25.9" - "@babel/plugin-transform-for-of": "npm:^7.26.9" - "@babel/plugin-transform-function-name": "npm:^7.25.9" - "@babel/plugin-transform-json-strings": "npm:^7.25.9" - "@babel/plugin-transform-literals": "npm:^7.25.9" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.25.9" - "@babel/plugin-transform-member-expression-literals": "npm:^7.25.9" - "@babel/plugin-transform-modules-amd": "npm:^7.25.9" - "@babel/plugin-transform-modules-commonjs": "npm:^7.26.3" - "@babel/plugin-transform-modules-systemjs": "npm:^7.25.9" - "@babel/plugin-transform-modules-umd": "npm:^7.25.9" - "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.25.9" - "@babel/plugin-transform-new-target": "npm:^7.25.9" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.26.6" - "@babel/plugin-transform-numeric-separator": "npm:^7.25.9" - "@babel/plugin-transform-object-rest-spread": "npm:^7.25.9" - "@babel/plugin-transform-object-super": "npm:^7.25.9" - "@babel/plugin-transform-optional-catch-binding": "npm:^7.25.9" - "@babel/plugin-transform-optional-chaining": "npm:^7.25.9" - "@babel/plugin-transform-parameters": "npm:^7.25.9" - "@babel/plugin-transform-private-methods": "npm:^7.25.9" - "@babel/plugin-transform-private-property-in-object": "npm:^7.25.9" - "@babel/plugin-transform-property-literals": "npm:^7.25.9" - "@babel/plugin-transform-regenerator": "npm:^7.25.9" - "@babel/plugin-transform-regexp-modifiers": "npm:^7.26.0" - "@babel/plugin-transform-reserved-words": "npm:^7.25.9" - "@babel/plugin-transform-shorthand-properties": "npm:^7.25.9" - "@babel/plugin-transform-spread": "npm:^7.25.9" - "@babel/plugin-transform-sticky-regex": "npm:^7.25.9" - "@babel/plugin-transform-template-literals": "npm:^7.26.8" - "@babel/plugin-transform-typeof-symbol": "npm:^7.26.7" - "@babel/plugin-transform-unicode-escapes": "npm:^7.25.9" - "@babel/plugin-transform-unicode-property-regex": "npm:^7.25.9" - "@babel/plugin-transform-unicode-regex": "npm:^7.25.9" - "@babel/plugin-transform-unicode-sets-regex": "npm:^7.25.9" + "@babel/plugin-transform-arrow-functions": "npm:^7.27.1" + "@babel/plugin-transform-async-generator-functions": "npm:^7.27.1" + "@babel/plugin-transform-async-to-generator": "npm:^7.27.1" + "@babel/plugin-transform-block-scoped-functions": "npm:^7.27.1" + "@babel/plugin-transform-block-scoping": "npm:^7.27.1" + "@babel/plugin-transform-class-properties": "npm:^7.27.1" + "@babel/plugin-transform-class-static-block": "npm:^7.27.1" + "@babel/plugin-transform-classes": "npm:^7.27.1" + "@babel/plugin-transform-computed-properties": "npm:^7.27.1" + "@babel/plugin-transform-destructuring": "npm:^7.27.1" + "@babel/plugin-transform-dotall-regex": "npm:^7.27.1" + "@babel/plugin-transform-duplicate-keys": "npm:^7.27.1" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.27.1" + "@babel/plugin-transform-dynamic-import": "npm:^7.27.1" + "@babel/plugin-transform-exponentiation-operator": "npm:^7.27.1" + "@babel/plugin-transform-export-namespace-from": "npm:^7.27.1" + "@babel/plugin-transform-for-of": "npm:^7.27.1" + "@babel/plugin-transform-function-name": "npm:^7.27.1" + "@babel/plugin-transform-json-strings": "npm:^7.27.1" + "@babel/plugin-transform-literals": "npm:^7.27.1" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.27.1" + "@babel/plugin-transform-member-expression-literals": "npm:^7.27.1" + "@babel/plugin-transform-modules-amd": "npm:^7.27.1" + "@babel/plugin-transform-modules-commonjs": "npm:^7.27.1" + "@babel/plugin-transform-modules-systemjs": "npm:^7.27.1" + "@babel/plugin-transform-modules-umd": "npm:^7.27.1" + "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.27.1" + "@babel/plugin-transform-new-target": "npm:^7.27.1" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.27.1" + "@babel/plugin-transform-numeric-separator": "npm:^7.27.1" + "@babel/plugin-transform-object-rest-spread": "npm:^7.27.2" + "@babel/plugin-transform-object-super": "npm:^7.27.1" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.27.1" + "@babel/plugin-transform-optional-chaining": "npm:^7.27.1" + "@babel/plugin-transform-parameters": "npm:^7.27.1" + "@babel/plugin-transform-private-methods": "npm:^7.27.1" + "@babel/plugin-transform-private-property-in-object": "npm:^7.27.1" + "@babel/plugin-transform-property-literals": "npm:^7.27.1" + "@babel/plugin-transform-regenerator": "npm:^7.27.1" + "@babel/plugin-transform-regexp-modifiers": "npm:^7.27.1" + "@babel/plugin-transform-reserved-words": "npm:^7.27.1" + "@babel/plugin-transform-shorthand-properties": "npm:^7.27.1" + "@babel/plugin-transform-spread": "npm:^7.27.1" + "@babel/plugin-transform-sticky-regex": "npm:^7.27.1" + "@babel/plugin-transform-template-literals": "npm:^7.27.1" + "@babel/plugin-transform-typeof-symbol": "npm:^7.27.1" + "@babel/plugin-transform-unicode-escapes": "npm:^7.27.1" + "@babel/plugin-transform-unicode-property-regex": "npm:^7.27.1" + "@babel/plugin-transform-unicode-regex": "npm:^7.27.1" + "@babel/plugin-transform-unicode-sets-regex": "npm:^7.27.1" "@babel/preset-modules": "npm:0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2: "npm:^0.4.10" babel-plugin-polyfill-corejs3: "npm:^0.11.0" @@ -1294,7 +1363,7 @@ __metadata: semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/6812ca76bd38165a58fe8354bab5e7204e1aa17d8b9270bd8f8babb08cc7fa94cd29525fe41b553f2ba0e84033d566f10da26012b8ee0f81897005c5225d0051 + checksum: 10c0/fd7ec310832a9ff26ed8d56bc0832cdbdb3a188e022050b74790796650649fb8373568af05b320b58b3ff922507979bad50ff95a4d504ab0081134480103504e languageName: node linkType: hard @@ -1312,33 +1381,33 @@ __metadata: linkType: hard "@babel/preset-react@npm:^7.22.15": - version: 7.26.3 - resolution: "@babel/preset-react@npm:7.26.3" + version: 7.27.1 + resolution: "@babel/preset-react@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-validator-option": "npm:^7.25.9" - "@babel/plugin-transform-react-display-name": "npm:^7.25.9" - "@babel/plugin-transform-react-jsx": "npm:^7.25.9" - "@babel/plugin-transform-react-jsx-development": "npm:^7.25.9" - "@babel/plugin-transform-react-pure-annotations": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-validator-option": "npm:^7.27.1" + "@babel/plugin-transform-react-display-name": "npm:^7.27.1" + "@babel/plugin-transform-react-jsx": "npm:^7.27.1" + "@babel/plugin-transform-react-jsx-development": "npm:^7.27.1" + "@babel/plugin-transform-react-pure-annotations": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/b470dcba11032ef6c832066f4af5c75052eaed49feb0f445227231ef1b5c42aacd6e216988c0bd469fd5728cd27b6b059ca307c9ecaa80c6bb5da4bf1c833e12 + checksum: 10c0/a80b02ef08b026cb9830d6512d08c7cd378eef4c0631dacba4aa1106240d9bb76af6373463f0255f4bbdbfcce40375a61e92735375906ba5871629b0c314bc45 languageName: node linkType: hard "@babel/preset-typescript@npm:^7.23.0": - version: 7.26.0 - resolution: "@babel/preset-typescript@npm:7.26.0" + version: 7.27.1 + resolution: "@babel/preset-typescript@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-validator-option": "npm:^7.25.9" - "@babel/plugin-syntax-jsx": "npm:^7.25.9" - "@babel/plugin-transform-modules-commonjs": "npm:^7.25.9" - "@babel/plugin-transform-typescript": "npm:^7.25.9" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-validator-option": "npm:^7.27.1" + "@babel/plugin-syntax-jsx": "npm:^7.27.1" + "@babel/plugin-transform-modules-commonjs": "npm:^7.27.1" + "@babel/plugin-transform-typescript": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/20d86bc45d2bbfde2f84fc7d7b38746fa6481d4bde6643039ad4b1ff0b804c6d210ee43e6830effd8571f2ff43fa7ffd27369f42f2b3a2518bb92dc86c780c61 + checksum: 10c0/cba6ca793d915f8aff9fe2f13b0dfbf5fd3f2e9a17f17478ec9878e9af0d206dcfe93154b9fd353727f16c1dca7c7a3ceb4943f8d28b216235f106bc0fbbcaa3 languageName: node linkType: hard @@ -1360,7 +1429,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.8.4": +"@babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.25.0": version: 7.26.9 resolution: "@babel/runtime@npm:7.26.9" dependencies: @@ -1369,7 +1438,14 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.25.9, @babel/template@npm:^7.26.9": +"@babel/runtime@npm:^7.26.10": + version: 7.27.3 + resolution: "@babel/runtime@npm:7.27.3" + checksum: 10c0/b860fe374a36fddbeeb238e52e59443abcacc046eebda1bf278bffbc67b5c8f713b939e09c126b086ca5f97cba1987ea17fd1737568bc50fedb1f6ef1cf46f69 + languageName: node + linkType: hard + +"@babel/template@npm:^7.25.9": version: 7.26.9 resolution: "@babel/template@npm:7.26.9" dependencies: @@ -1380,6 +1456,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/template@npm:7.27.2" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/parser": "npm:^7.27.2" + "@babel/types": "npm:^7.27.1" + checksum: 10c0/ed9e9022651e463cc5f2cc21942f0e74544f1754d231add6348ff1b472985a3b3502041c0be62dc99ed2d12cfae0c51394bf827452b98a2f8769c03b87aadc81 + languageName: node + linkType: hard + "@babel/traverse@npm:^7.10.3": version: 7.25.9 resolution: "@babel/traverse@npm:7.25.9" @@ -1395,18 +1482,18 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.5, @babel/traverse@npm:^7.26.8, @babel/traverse@npm:^7.26.9": - version: 7.26.9 - resolution: "@babel/traverse@npm:7.26.9" +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/traverse@npm:7.27.3" dependencies: - "@babel/code-frame": "npm:^7.26.2" - "@babel/generator": "npm:^7.26.9" - "@babel/parser": "npm:^7.26.9" - "@babel/template": "npm:^7.26.9" - "@babel/types": "npm:^7.26.9" + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.27.3" + "@babel/parser": "npm:^7.27.3" + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.27.3" debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: 10c0/51dd57fa39ea34d04816806bfead04c74f37301269d24c192d1406dc6e244fea99713b3b9c5f3e926d9ef6aa9cd5c062ad4f2fc1caa9cf843d5e864484ac955e + checksum: 10c0/63edf0755cc7307470fefeca69c5205b259eaf45df79a4f7be0f28d8937d916bfb090ad9ffbc62edd7e1bbc4309c1f202a9a6904ed3af847504bcefd5ac58c16 languageName: node linkType: hard @@ -1440,6 +1527,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/types@npm:7.27.3" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + checksum: 10c0/bafdfc98e722a6b91a783b6f24388f478fd775f0c0652e92220e08be2cc33e02d42088542f1953ac5e5ece2ac052172b3dadedf12bec9aae57899e92fb9a9757 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^1.0.2": version: 1.0.2 resolution: "@bcoe/v8-coverage@npm:1.0.2" @@ -1454,9 +1551,9 @@ __metadata: languageName: node linkType: hard -"@codecov/bundler-plugin-core@npm:^1.9.0": - version: 1.9.0 - resolution: "@codecov/bundler-plugin-core@npm:1.9.0" +"@codecov/bundler-plugin-core@npm:^1.9.1": + version: 1.9.1 + resolution: "@codecov/bundler-plugin-core@npm:1.9.1" dependencies: "@actions/core": "npm:^1.10.1" "@actions/github": "npm:^6.0.0" @@ -1464,29 +1561,29 @@ __metadata: semver: "npm:^7.5.4" unplugin: "npm:^1.10.1" zod: "npm:^3.22.4" - checksum: 10c0/c29c5e0cc40151d499c779e44f54b36f82e28dad66dcb005ec226b35c8e7c80145e136b4d880cd454071f3233c6334e154dd228ff30dec5ce7d4b2d637d2bb9e + checksum: 10c0/82366e6a0c7ee1c1c810b71c1773ea12ba3c395d812d3172f3155cf2930eae1bb8d2fe660be3d0c2e60eb0f6db2bbf4b5d327344d846523d3e54848549b55aee languageName: node linkType: hard "@codecov/vite-plugin@npm:^1.3.0": - version: 1.9.0 - resolution: "@codecov/vite-plugin@npm:1.9.0" + version: 1.9.1 + resolution: "@codecov/vite-plugin@npm:1.9.1" dependencies: - "@codecov/bundler-plugin-core": "npm:^1.9.0" + "@codecov/bundler-plugin-core": "npm:^1.9.1" unplugin: "npm:^1.10.1" peerDependencies: vite: 4.x || 5.x || 6.x - checksum: 10c0/fcab778bbbc8d8d190f40d7108d0dc5e6bff0179a8bcc4218c4fd5bfcc32e25b6a1d9e431d8b142ea16c2335857c9dd8e2d2b0e49a0fe3e856e7cb197f363145 + checksum: 10c0/b4e640a23f4af4a140038a68a1fbc8d4de555d7064c68d8f5dbd0d99c983a66113f9262035f98f4fd8ecadf93f4d7daf1aafd1f138f947edf4f6c24c26475571 languageName: node linkType: hard -"@csstools/cascade-layer-name-parser@npm:^2.0.4": - version: 2.0.4 - resolution: "@csstools/cascade-layer-name-parser@npm:2.0.4" +"@csstools/cascade-layer-name-parser@npm:^2.0.5": + version: 2.0.5 + resolution: "@csstools/cascade-layer-name-parser@npm:2.0.5" peerDependencies: - "@csstools/css-parser-algorithms": ^3.0.4 - "@csstools/css-tokenizer": ^3.0.3 - checksum: 10c0/774f2bcc96a576183853191bdfd31df15e22c51901ee01678ee47f1d1afcb4ab0e6d9a78e08f7383ac089c7e0b390013633f45ff1f1d577c9aefd252589bcced + "@csstools/css-parser-algorithms": ^3.0.5 + "@csstools/css-tokenizer": ^3.0.4 + checksum: 10c0/b6c73d5c8132f922edc88b9df5272c93c9753945f1e1077b80d03b314076ffe03c2cc9bf6cbc85501ee7c7f27e477263df96997c9125fd2fd0cfe82fe2d7c141 languageName: node linkType: hard @@ -1514,13 +1611,26 @@ __metadata: languageName: node linkType: hard -"@csstools/css-calc@npm:^2.1.2": - version: 2.1.2 - resolution: "@csstools/css-calc@npm:2.1.2" +"@csstools/css-calc@npm:^2.1.4": + version: 2.1.4 + resolution: "@csstools/css-calc@npm:2.1.4" peerDependencies: - "@csstools/css-parser-algorithms": ^3.0.4 - "@csstools/css-tokenizer": ^3.0.3 - checksum: 10c0/34ced30553968ef5d5f9e00e3b90b48c47480cf130e282e99d57ec9b09f803aab8bc06325683e72a1518b5e7180a3da8b533f1b462062757c21989a53b482e1a + "@csstools/css-parser-algorithms": ^3.0.5 + "@csstools/css-tokenizer": ^3.0.4 + checksum: 10c0/42ce5793e55ec4d772083808a11e9fb2dfe36db3ec168713069a276b4c3882205b3507c4680224c28a5d35fe0bc2d308c77f8f2c39c7c09aad8747708eb8ddd8 + languageName: node + linkType: hard + +"@csstools/css-color-parser@npm:^3.0.10": + version: 3.0.10 + resolution: "@csstools/css-color-parser@npm:3.0.10" + dependencies: + "@csstools/color-helpers": "npm:^5.0.2" + "@csstools/css-calc": "npm:^2.1.4" + peerDependencies: + "@csstools/css-parser-algorithms": ^3.0.5 + "@csstools/css-tokenizer": ^3.0.4 + checksum: 10c0/8f8a2395b117c2f09366b5c9bf49bc740c92a65b6330fe3cc1e76abafd0d1000e42a657d7b0a3814846a66f1d69896142f7e36d7a4aca77de977e5cc5f944747 languageName: node linkType: hard @@ -1537,19 +1647,6 @@ __metadata: languageName: node linkType: hard -"@csstools/css-color-parser@npm:^3.0.8": - version: 3.0.8 - resolution: "@csstools/css-color-parser@npm:3.0.8" - dependencies: - "@csstools/color-helpers": "npm:^5.0.2" - "@csstools/css-calc": "npm:^2.1.2" - peerDependencies: - "@csstools/css-parser-algorithms": ^3.0.4 - "@csstools/css-tokenizer": ^3.0.3 - checksum: 10c0/90722c5a62ca94e9d578ddf59be604a76400b932bd3d4bd23cb1ae9b7ace8fcf83c06995d2b31f96f4afef24a7cefba79beb11ed7ee4999d7ecfec3869368359 - languageName: node - linkType: hard - "@csstools/css-parser-algorithms@npm:^3.0.4": version: 3.0.4 resolution: "@csstools/css-parser-algorithms@npm:3.0.4" @@ -1559,6 +1656,15 @@ __metadata: languageName: node linkType: hard +"@csstools/css-parser-algorithms@npm:^3.0.5": + version: 3.0.5 + resolution: "@csstools/css-parser-algorithms@npm:3.0.5" + peerDependencies: + "@csstools/css-tokenizer": ^3.0.4 + checksum: 10c0/d9a1c888bd43849ae3437ca39251d5c95d2c8fd6b5ccdb7c45491dfd2c1cbdc3075645e80901d120e4d2c1993db9a5b2d83793b779dbbabcfb132adb142eb7f7 + languageName: node + linkType: hard + "@csstools/css-tokenizer@npm:^3.0.3": version: 3.0.3 resolution: "@csstools/css-tokenizer@npm:3.0.3" @@ -1566,13 +1672,20 @@ __metadata: languageName: node linkType: hard -"@csstools/media-query-list-parser@npm:^4.0.2": - version: 4.0.2 - resolution: "@csstools/media-query-list-parser@npm:4.0.2" +"@csstools/css-tokenizer@npm:^3.0.4": + version: 3.0.4 + resolution: "@csstools/css-tokenizer@npm:3.0.4" + checksum: 10c0/3b589f8e9942075a642213b389bab75a2d50d05d203727fcdac6827648a5572674caff07907eff3f9a2389d86a4ee47308fafe4f8588f4a77b7167c588d2559f + languageName: node + linkType: hard + +"@csstools/media-query-list-parser@npm:^4.0.3": + version: 4.0.3 + resolution: "@csstools/media-query-list-parser@npm:4.0.3" peerDependencies: - "@csstools/css-parser-algorithms": ^3.0.4 - "@csstools/css-tokenizer": ^3.0.3 - checksum: 10c0/5d008a70f5d4fd96224066a433f5cdefa76cfd78a74416a20d6d5b2bb1bc8282b140e8373015d807d4dadb91daf3deb73eb13f853ec4e0479d0cb92e80c6f20d + "@csstools/css-parser-algorithms": ^3.0.5 + "@csstools/css-tokenizer": ^3.0.4 + checksum: 10c0/e29d856d57e9a036694662163179fc061a99579f05e7c3c35438b3e063790ae8a9ee9f1fb4b4693d8fc7672ae0801764fe83762ab7b9df2921fcc6172cfd5584 languageName: node linkType: hard @@ -1588,60 +1701,75 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-color-function@npm:^4.0.8": - version: 4.0.8 - resolution: "@csstools/postcss-color-function@npm:4.0.8" +"@csstools/postcss-color-function@npm:^4.0.10": + version: 4.0.10 + resolution: "@csstools/postcss-color-function@npm:4.0.10" dependencies: - "@csstools/css-color-parser": "npm:^3.0.8" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/d52c65bb4ed28f62b3fc9c0b2ce068e58395345dcead797ed8f7e4f5f469a9311607d39dd409c571ccc94d6c5c84171aff62d51d4f53fdcf6e1cca23fc31d4f1 + checksum: 10c0/a6e65d37a114f95634a07660daa1aa52f4abfb6ddd740cc9267967a5948f5c72469a6ba2432ab1f31616d6f1a4ab963b69f778497496986535831b0b2b399f75 languageName: node linkType: hard -"@csstools/postcss-color-mix-function@npm:^3.0.8": - version: 3.0.8 - resolution: "@csstools/postcss-color-mix-function@npm:3.0.8" +"@csstools/postcss-color-mix-function@npm:^3.0.10": + version: 3.0.10 + resolution: "@csstools/postcss-color-mix-function@npm:3.0.10" dependencies: - "@csstools/css-color-parser": "npm:^3.0.8" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/3fe7093b38f2b469462fa942af5a54a1ad68b07cd33267288e5c9e865d3a871c04774463136e4af24955316f40560dda1371d02cfd5595475a742afae13a37ba + checksum: 10c0/9505a09a805f52555bd06c8f54d537a99578efe5c7e643c9fdaca8cbb7d74d4d3e07b829c6aed315c75ec5ce113261fb402e01b67e4a423ed39ea8991a6dded0 languageName: node linkType: hard -"@csstools/postcss-content-alt-text@npm:^2.0.4": - version: 2.0.4 - resolution: "@csstools/postcss-content-alt-text@npm:2.0.4" +"@csstools/postcss-color-mix-variadic-function-arguments@npm:^1.0.0": + version: 1.0.0 + resolution: "@csstools/postcss-color-mix-variadic-function-arguments@npm:1.0.0" dependencies: - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/84caccedd8a519df434babd58b14104c5a92cd326057ce509bdbaa2a4bb3130afb1c1456caf30235ba14da52d1628a5411ea4f5d2fb558d603d234f795538017 + checksum: 10c0/dd45bd19931cc4780247173b793e5f1e6409b76f92b04fe26e07b0fa048aedc7bcbd92356a558581f695654c2f2d189e1b40b14a9c3f246e86e83b0edf646066 languageName: node linkType: hard -"@csstools/postcss-exponential-functions@npm:^2.0.7": - version: 2.0.7 - resolution: "@csstools/postcss-exponential-functions@npm:2.0.7" +"@csstools/postcss-content-alt-text@npm:^2.0.6": + version: 2.0.6 + resolution: "@csstools/postcss-content-alt-text@npm:2.0.6" dependencies: - "@csstools/css-calc": "npm:^2.1.2" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" + "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/9d02076135ee9bf82bf911f577c9fda42bf00347f3c519fa83e32e83f5b8a98649b97e13ba3a42ed906467729d7b69574595556dfb9e865c86d3bbae5ffbc918 + checksum: 10c0/e7d21002a84d0fba4fe815fb7d3d19b81fb1719a7b6fdd240eb6639d58937b64d6f5c9aa11ffe8a64891a2ed181818cd56d346f58949c2eaa9df7c82ee95ef8e + languageName: node + linkType: hard + +"@csstools/postcss-exponential-functions@npm:^2.0.9": + version: 2.0.9 + resolution: "@csstools/postcss-exponential-functions@npm:2.0.9" + dependencies: + "@csstools/css-calc": "npm:^2.1.4" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + peerDependencies: + postcss: ^8.4 + checksum: 10c0/78ea627a87fb23e12616c4e54150363b0e8793064634983dbe0368a0aca1ff73206c2d1f29845773daaf42787e7d1f180ce1b57c43e2b0d10da450101f9f34b6 languageName: node linkType: hard @@ -1657,59 +1785,59 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-gamut-mapping@npm:^2.0.8": - version: 2.0.8 - resolution: "@csstools/postcss-gamut-mapping@npm:2.0.8" +"@csstools/postcss-gamut-mapping@npm:^2.0.10": + version: 2.0.10 + resolution: "@csstools/postcss-gamut-mapping@npm:2.0.10" dependencies: - "@csstools/css-color-parser": "npm:^3.0.8" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" peerDependencies: postcss: ^8.4 - checksum: 10c0/81daaba0e774ed3ab97e2c7c93dcae16d1e8447a27f0e82ddf8a176e8f1e93b444f463284105fd312c6234d4210372d6d69d96efcfb05bc5b6adfba6fcfd6f44 + checksum: 10c0/87cd8289478bf88195469fcf4f80c8fed9e0e5ef76a335a10c4c21582542acb16cced1e00e7da90deaf2e62e383a5c6fe402f429f227c87a2c20e2545a69c537 languageName: node linkType: hard -"@csstools/postcss-gradients-interpolation-method@npm:^5.0.8": - version: 5.0.8 - resolution: "@csstools/postcss-gradients-interpolation-method@npm:5.0.8" +"@csstools/postcss-gradients-interpolation-method@npm:^5.0.10": + version: 5.0.10 + resolution: "@csstools/postcss-gradients-interpolation-method@npm:5.0.10" dependencies: - "@csstools/css-color-parser": "npm:^3.0.8" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/832bfb663b334be9783f49c354cbeec3cede1830a576b91a101456db33207e9651f97624f0df92e5d01a39b68a215ad4b20621ee229b92b51607e889093bc590 + checksum: 10c0/206d079d7679a9609a4fb227ddaf3443d04cff88b55bcfec1cf63c9de372b8720edde8614fc51d2237e4edbff8ce34697f912bc25c2ae41390353fce88455515 languageName: node linkType: hard -"@csstools/postcss-hwb-function@npm:^4.0.8": - version: 4.0.8 - resolution: "@csstools/postcss-hwb-function@npm:4.0.8" +"@csstools/postcss-hwb-function@npm:^4.0.10": + version: 4.0.10 + resolution: "@csstools/postcss-hwb-function@npm:4.0.10" dependencies: - "@csstools/css-color-parser": "npm:^3.0.8" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/d6196e2acfc0a6fd61fe254385049fb784abb862c724543940dbba8ffe29bbdbedd83985a517132a21073435445486f918da170fb0f710dbe40a798b9abc41e7 + checksum: 10c0/defb9b319b14228307196b9a88e3cbf0acd1d3768b936716dca846875068ad4453e7a2a3d75d1fab5534c8655e9c555e1fa70d30e2c85d68ed2117a7cfe7837c languageName: node linkType: hard -"@csstools/postcss-ic-unit@npm:^4.0.0": - version: 4.0.0 - resolution: "@csstools/postcss-ic-unit@npm:4.0.0" +"@csstools/postcss-ic-unit@npm:^4.0.2": + version: 4.0.2 + resolution: "@csstools/postcss-ic-unit@npm:4.0.2" dependencies: - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/6f94ec31002a245768a30d240c432b8712af4d9ea76a62403e16d4e0afb5be7636348a2d4619046ed29aa7726f88a0c191ca41c96d7ab0f3da940025c91b056e + checksum: 10c0/26adb8351143e591080f542d87b223ee5ebc5f33f6d03b217505b249ceb19c46a06732a88000e3a1857ae712a6ea0ffa089a24ad8b8042421490539de5c3d0e8 languageName: node linkType: hard @@ -1734,17 +1862,17 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-light-dark-function@npm:^2.0.7": - version: 2.0.7 - resolution: "@csstools/postcss-light-dark-function@npm:2.0.7" +"@csstools/postcss-light-dark-function@npm:^2.0.9": + version: 2.0.9 + resolution: "@csstools/postcss-light-dark-function@npm:2.0.9" dependencies: - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/c116bfd2d3f4d0caabdedf8954c2a25908ffb29f9bbe2c57d44a2974277c7e46ee79862eea848385dc040275d343f2330350394a2095ec30f0aa17f72e2f4e39 + checksum: 10c0/ee2937f0e5dcaafd10349f0914596e8e1ef6f9d46939c6a6b0e2e63cab0552594e5140bf56e485048c3bca6634dd9673a176c57b9e77001332787f4263835c0f languageName: node linkType: hard @@ -1786,42 +1914,42 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-logical-viewport-units@npm:^3.0.3": - version: 3.0.3 - resolution: "@csstools/postcss-logical-viewport-units@npm:3.0.3" +"@csstools/postcss-logical-viewport-units@npm:^3.0.4": + version: 3.0.4 + resolution: "@csstools/postcss-logical-viewport-units@npm:3.0.4" dependencies: - "@csstools/css-tokenizer": "npm:^3.0.3" + "@csstools/css-tokenizer": "npm:^3.0.4" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/8ec746598d7ce8697c3dafd83cb3a319a90079ad755dd78e3ec92f4ba9ad849c4cdaba33b16e9dcbac1e9489b3d7c48262030110c20ce1d88cdacbe9f5987cec + checksum: 10c0/f0b5ba38acde3bf0ca880c6e0a883950c99fa9919b0e6290c894d5716569663590f26aa1170fd9483ce14544e46afac006ab3b02781410d5e7c8dd1467c674ce languageName: node linkType: hard -"@csstools/postcss-media-minmax@npm:^2.0.7": - version: 2.0.7 - resolution: "@csstools/postcss-media-minmax@npm:2.0.7" +"@csstools/postcss-media-minmax@npm:^2.0.9": + version: 2.0.9 + resolution: "@csstools/postcss-media-minmax@npm:2.0.9" dependencies: - "@csstools/css-calc": "npm:^2.1.2" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/media-query-list-parser": "npm:^4.0.2" + "@csstools/css-calc": "npm:^2.1.4" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/media-query-list-parser": "npm:^4.0.3" peerDependencies: postcss: ^8.4 - checksum: 10c0/03b7a5603437d5be17e9c0d951ca0b7b3b6f437fd4e24e3ac3f70ed9d573ef67641821fe209b5764c54aa36e841c830a5d8cf3a3dd97fd2fa774b7ceba7ba038 + checksum: 10c0/d82622ee9de6eacba1abbf31718cd58759d158ed8a575f36f08e982d07a7d83e51fb184178b96c6f7b76cb333bb33cac04d06a750b6b9c5c43ae1c56232880f9 languageName: node linkType: hard -"@csstools/postcss-media-queries-aspect-ratio-number-values@npm:^3.0.4": - version: 3.0.4 - resolution: "@csstools/postcss-media-queries-aspect-ratio-number-values@npm:3.0.4" +"@csstools/postcss-media-queries-aspect-ratio-number-values@npm:^3.0.5": + version: 3.0.5 + resolution: "@csstools/postcss-media-queries-aspect-ratio-number-values@npm:3.0.5" dependencies: - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/media-query-list-parser": "npm:^4.0.2" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/media-query-list-parser": "npm:^4.0.3" peerDependencies: postcss: ^8.4 - checksum: 10c0/27dc9419b0f4315774647588f599348e7cc593984f59b414c51c910066501fd087cbe232deb762907c18bd21dd4184e7b6e0e0b730e5c72341ab9cc696c75739 + checksum: 10c0/a47abdaa7f4b26596bd9d6bb77aed872a232fc12bd144d2c062d9da626e8dfd8336e2fff67617dba61a1666c2b8027145b390d70d5cd4d4f608604e077cfb04e languageName: node linkType: hard @@ -1848,57 +1976,57 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-oklab-function@npm:^4.0.8": - version: 4.0.8 - resolution: "@csstools/postcss-oklab-function@npm:4.0.8" +"@csstools/postcss-oklab-function@npm:^4.0.10": + version: 4.0.10 + resolution: "@csstools/postcss-oklab-function@npm:4.0.10" dependencies: - "@csstools/css-color-parser": "npm:^3.0.8" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/8a62f3875bb9026c95758a0b834e876a8f07dd1a5ba36c3967e230565fbd9afd21ec714c8590cb4ea594fd214e68f2ccf58456ed6e919a47d2ed17d5b63a925a + checksum: 10c0/421d1f2574941c3caecd608588533581fc0766998cc85474008a49b5f1011249cb2be7ef9f21a346fd3895598da18e58860fde06d34b1b833918fa880c41c18f languageName: node linkType: hard -"@csstools/postcss-progressive-custom-properties@npm:^4.0.0": - version: 4.0.0 - resolution: "@csstools/postcss-progressive-custom-properties@npm:4.0.0" +"@csstools/postcss-progressive-custom-properties@npm:^4.1.0": + version: 4.1.0 + resolution: "@csstools/postcss-progressive-custom-properties@npm:4.1.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/517e5e0b1525667ea1c4469bb2af52995934b9ab3165bba33e3bfdfac63b20bb51c878da582d805957dc0291e396e5a540cac18d1220a08190d98d5463d26ce2 + checksum: 10c0/175081a5c53e37a282f596e01359d4411800e4017c2d389caaa2b7c9b7507a50c5f1ac3d937f27f000be3ac2ac788cad9c1490ec6bc1d4de51331f3cc8ccda8e languageName: node linkType: hard -"@csstools/postcss-random-function@npm:^1.0.3": - version: 1.0.3 - resolution: "@csstools/postcss-random-function@npm:1.0.3" +"@csstools/postcss-random-function@npm:^2.0.1": + version: 2.0.1 + resolution: "@csstools/postcss-random-function@npm:2.0.1" dependencies: - "@csstools/css-calc": "npm:^2.1.2" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" + "@csstools/css-calc": "npm:^2.1.4" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" peerDependencies: postcss: ^8.4 - checksum: 10c0/c3bf319a6f79c0e372e4754e7888a4cd3a97b81e480662b1d1cb193949670bbcd5995c42483390a996e66d6dd81c9ad753836cc617aac2e3acbd542faa56f907 + checksum: 10c0/475bacf685b8bb82942d388e9e3b95f4156800f370299f19f5acc490475dc2813100de81a5a6bf48b696b4d83247622005b616af3166a668556b4b1aceded70d languageName: node linkType: hard -"@csstools/postcss-relative-color-syntax@npm:^3.0.8": - version: 3.0.8 - resolution: "@csstools/postcss-relative-color-syntax@npm:3.0.8" +"@csstools/postcss-relative-color-syntax@npm:^3.0.10": + version: 3.0.10 + resolution: "@csstools/postcss-relative-color-syntax@npm:3.0.10" dependencies: - "@csstools/css-color-parser": "npm:^3.0.8" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/fcd14fb1c3f103dbaaf88afa2540f9946313d48515fa24fffcde4200e7dc4aa767d186ecf2e12bb0501dd946a824f118cd4ad5d44899c8d6d9d8d9d9b99a123e + checksum: 10c0/de9c41a936a77dab68cdb2dd23a26ba1b92d90bf2a7cf463fada2f2daf6ad0d7394fa2b1ed444f509006992961d993383a34a9afd3a48a9dc67a3793afcd9bb8 languageName: node linkType: hard @@ -1913,29 +2041,29 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-sign-functions@npm:^1.1.2": - version: 1.1.2 - resolution: "@csstools/postcss-sign-functions@npm:1.1.2" +"@csstools/postcss-sign-functions@npm:^1.1.4": + version: 1.1.4 + resolution: "@csstools/postcss-sign-functions@npm:1.1.4" dependencies: - "@csstools/css-calc": "npm:^2.1.2" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" + "@csstools/css-calc": "npm:^2.1.4" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" peerDependencies: postcss: ^8.4 - checksum: 10c0/15a1c434c3059ab884634d32374d53265c0ea5b5d1f6cb979dcfef18903edbafbf334fcbabd5b24869356db93792adfe95d88efef998b7d6b4c6f4b8393faca1 + checksum: 10c0/ff58108b2527832a84c571a1f40224b5c8d2afa8db2fe3b1e3599ff6f3469d9f4c528a70eb3c25c5d7801e30474fabfec04e7c23bfdad8572ad492053cd4f899 languageName: node linkType: hard -"@csstools/postcss-stepped-value-functions@npm:^4.0.7": - version: 4.0.7 - resolution: "@csstools/postcss-stepped-value-functions@npm:4.0.7" +"@csstools/postcss-stepped-value-functions@npm:^4.0.9": + version: 4.0.9 + resolution: "@csstools/postcss-stepped-value-functions@npm:4.0.9" dependencies: - "@csstools/css-calc": "npm:^2.1.2" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" + "@csstools/css-calc": "npm:^2.1.4" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" peerDependencies: postcss: ^8.4 - checksum: 10c0/1e664f0b169abe0e8ad832844ff06b219702ba7e6af795801109bd2e90403295d5cdb2e27c17f92e60d9704b30726b4564da79e0bf66dec852d50704a8813053 + checksum: 10c0/f143ca06338c30abb2aa37adc3d7e43a78f3b4493093160cb5babe3ec8cf6b86d83876746ee8e162db87b5e9af6e0066958d89fe8b4a503a29568e5c57c1bf8a languageName: node linkType: hard @@ -1951,16 +2079,16 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-trigonometric-functions@npm:^4.0.7": - version: 4.0.7 - resolution: "@csstools/postcss-trigonometric-functions@npm:4.0.7" +"@csstools/postcss-trigonometric-functions@npm:^4.0.9": + version: 4.0.9 + resolution: "@csstools/postcss-trigonometric-functions@npm:4.0.9" dependencies: - "@csstools/css-calc": "npm:^2.1.2" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" + "@csstools/css-calc": "npm:^2.1.4" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" peerDependencies: postcss: ^8.4 - checksum: 10c0/2b01608a9f7dba6f73febfdd75269f6f88eb2a653de38a0adc6e81de57de4248bedd39b3e8b219cc49ce73b99118e285a870711953a553ddddb0bd5b2f9a5852 + checksum: 10c0/6ba3d381c977c224f01d47a36f78c9b99d3b89d060a357a9f8840537fdf497d9587a28165dc74e96abdf02f8db0a277d3558646355085a74c8915ee73c6780d1 languageName: node linkType: hard @@ -2000,6 +2128,34 @@ __metadata: languageName: node linkType: hard +"@emnapi/core@npm:^1.4.3": + version: 1.4.3 + resolution: "@emnapi/core@npm:1.4.3" + dependencies: + "@emnapi/wasi-threads": "npm:1.0.2" + tslib: "npm:^2.4.0" + checksum: 10c0/e30101d16d37ef3283538a35cad60e22095aff2403fb9226a35330b932eb6740b81364d525537a94eb4fb51355e48ae9b10d779c0dd1cdcd55d71461fe4b45c7 + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.4.3": + version: 1.4.3 + resolution: "@emnapi/runtime@npm:1.4.3" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/3b7ab72d21cb4e034f07df80165265f85f445ef3f581d1bc87b67e5239428baa00200b68a7d5e37a0425c3a78320b541b07f76c5530f6f6f95336a6294ebf30b + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.0.2": + version: 1.0.2 + resolution: "@emnapi/wasi-threads@npm:1.0.2" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/f0621b1fc715221bd2d8332c0ca922617bcd77cdb3050eae50a124eb8923c54fa425d23982dc8f29d505c8798a62d1049bace8b0686098ff9dd82270e06d772e + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/aix-ppc64@npm:0.25.1" @@ -2197,6 +2353,17 @@ __metadata: languageName: node linkType: hard +"@eslint-community/eslint-utils@npm:^4.7.0": + version: 4.7.0 + resolution: "@eslint-community/eslint-utils@npm:4.7.0" + dependencies: + eslint-visitor-keys: "npm:^3.4.3" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10c0/c0f4f2bd73b7b7a9de74b716a664873d08ab71ab439e51befe77d61915af41a81ecec93b408778b3a7856185244c34c2c8ee28912072ec14def84ba2dec70adf + languageName: node + linkType: hard + "@eslint-community/regexpp@npm:^4.10.0": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" @@ -2251,17 +2418,7 @@ __metadata: languageName: node linkType: hard -"@floating-ui/dom@npm:1.6.11": - version: 1.6.11 - resolution: "@floating-ui/dom@npm:1.6.11" - dependencies: - "@floating-ui/core": "npm:^1.6.0" - "@floating-ui/utils": "npm:^0.2.8" - checksum: 10c0/02ef34a75a515543c772880338eea7b66724997bd5ec7cd58d26b50325709d46d480a306b84e7d5509d734434411a4bcf23af5680c2e461e6e6a8bf45d751df8 - languageName: node - linkType: hard - -"@floating-ui/dom@npm:^1.0.0": +"@floating-ui/dom@npm:1.6.13, @floating-ui/dom@npm:^1.0.0": version: 1.6.13 resolution: "@floating-ui/dom@npm:1.6.13" dependencies: @@ -2297,7 +2454,7 @@ __metadata: languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.8, @floating-ui/utils@npm:^0.2.9": +"@floating-ui/utils@npm:^0.2.9": version: 0.2.9 resolution: "@floating-ui/utils@npm:0.2.9" checksum: 10c0/48bbed10f91cb7863a796cc0d0e917c78d11aeb89f98d03fc38d79e7eb792224a79f538ed8a2d5d5584511d4ca6354ef35f1712659fd569868e342df4398ad6f @@ -2305,68 +2462,68 @@ __metadata: linkType: hard "@fontsource/inconsolata@npm:^5.1.0": - version: 5.1.1 - resolution: "@fontsource/inconsolata@npm:5.1.1" - checksum: 10c0/7aa166f77c55a313444de1f76f5417a2285df99e6aec1ecd0ffc83e6e83f2659d83f825d7449699b0bebfff4616b0606ced72ed847759c0eeac0a69f78650592 + version: 5.2.5 + resolution: "@fontsource/inconsolata@npm:5.2.5" + checksum: 10c0/95e337719f90f45fa8d0e0bebf36bea43711c923cb67441ff166253d61687e4dd9612e2de42a758c1981cdce56f3c731f81663323415f1f8c9fbfe9356ce6e01 languageName: node linkType: hard "@fontsource/inter@npm:^5.1.0": - version: 5.1.1 - resolution: "@fontsource/inter@npm:5.1.1" - checksum: 10c0/ec7a371bd54fbf8c452a461161dda2fdd2d6989617c670e101e7623429becc917801c107dcce84e263010ecd1a381a01e04b6e7c07275469720c1496a7365bdc + version: 5.2.5 + resolution: "@fontsource/inter@npm:5.2.5" + checksum: 10c0/071e12a6a9c8cf6e95da43ba532e80eb8e35c1ffd2384c9c6555d7f222e306e22968f7c4fff5065b9f81503db622cf3de8a688fbc1cb0c04aa3803c797f6f6a0 languageName: node linkType: hard -"@formatjs/ecma402-abstract@npm:2.3.3": - version: 2.3.3 - resolution: "@formatjs/ecma402-abstract@npm:2.3.3" +"@formatjs/ecma402-abstract@npm:2.3.4": + version: 2.3.4 + resolution: "@formatjs/ecma402-abstract@npm:2.3.4" dependencies: - "@formatjs/fast-memoize": "npm:2.2.6" - "@formatjs/intl-localematcher": "npm:0.6.0" - decimal.js: "npm:10" - tslib: "npm:2" - checksum: 10c0/63de990c380a1800bc54d97c4aa13a88a92e73b1680f0f561d03f9bf3e23289b7aafd1a92037527c285bd587a44e20504258ac2cbd4564a4138ce2b4612c1495 + "@formatjs/fast-memoize": "npm:2.2.7" + "@formatjs/intl-localematcher": "npm:0.6.1" + decimal.js: "npm:^10.4.3" + tslib: "npm:^2.8.0" + checksum: 10c0/2644bc618a34dc610ef9691281eeb45ae6175e6982cf19f1bd140672fc95c748747ce3c85b934649ea7e4a304f7ae0060625fd53d5df76f92ca3acf743e1eb0a languageName: node linkType: hard -"@formatjs/fast-memoize@npm:2.2.6": - version: 2.2.6 - resolution: "@formatjs/fast-memoize@npm:2.2.6" +"@formatjs/fast-memoize@npm:2.2.7": + version: 2.2.7 + resolution: "@formatjs/fast-memoize@npm:2.2.7" dependencies: - tslib: "npm:2" - checksum: 10c0/dccdc21105af673e58ec7b04eb17cd6fde1fb1a7e7a446273ca43f7ab97c26d5c0fcc2b9e80d5b54bf9b80354f9e1e681273c0ed26633ec72f0adc2d116dfd7f + tslib: "npm:^2.8.0" + checksum: 10c0/f5eabb0e4ab7162297df8252b4cfde194b23248120d9df267592eae2be2d2f7c4f670b5a70523d91b4ecdc35d40e65823bb8eeba8dd79fbf8601a972bf3b8866 languageName: node linkType: hard "@formatjs/intl-durationformat@npm:^0.7.0": - version: 0.7.3 - resolution: "@formatjs/intl-durationformat@npm:0.7.3" + version: 0.7.4 + resolution: "@formatjs/intl-durationformat@npm:0.7.4" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.3" - "@formatjs/intl-localematcher": "npm:0.6.0" - tslib: "npm:2" - checksum: 10c0/77691ebe75e54419c34c54ae2f7b935661e99bd772cab99f87166a2522cf3e43acd5625a1238d4345a87c91279a066e541ce30feab2646532f1f1c5b8f99c0a7 + "@formatjs/ecma402-abstract": "npm:2.3.4" + "@formatjs/intl-localematcher": "npm:0.6.1" + tslib: "npm:^2.8.0" + checksum: 10c0/e340cab41fcb52639c73f25a422a2cf252c0fb8d328b88bd72b8f995e2d7ffa5d6aa7bb4f4e11862d45bd7eef398d9c8a1cf9d400bcf89c42ff3c38e63196dbe languageName: node linkType: hard -"@formatjs/intl-localematcher@npm:0.6.0": - version: 0.6.0 - resolution: "@formatjs/intl-localematcher@npm:0.6.0" +"@formatjs/intl-localematcher@npm:0.6.1": + version: 0.6.1 + resolution: "@formatjs/intl-localematcher@npm:0.6.1" dependencies: - tslib: "npm:2" - checksum: 10c0/90238e633426ff7237ab2bbe017be044fb2fb185a8d59a0652096ddab9cb1ddf64106d58fafd711ea19c4d3455bd966516ab93574ac3b169d9af2325875fae59 + tslib: "npm:^2.8.0" + checksum: 10c0/bacbedd508519c1bb5ca2620e89dc38f12101be59439aa14aa472b222915b462cb7d679726640f6dcf52a05dd218b5aa27ccd60f2e5010bb96f1d4929848cde0 languageName: node linkType: hard "@formatjs/intl-segmenter@npm:^11.7.3": - version: 11.7.9 - resolution: "@formatjs/intl-segmenter@npm:11.7.9" + version: 11.7.10 + resolution: "@formatjs/intl-segmenter@npm:11.7.10" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.3" - "@formatjs/intl-localematcher": "npm:0.6.0" - tslib: "npm:2" - checksum: 10c0/e775c615e97bfd0f5b09659bab60c5e5ce494edaf79f001a5ecb820c101d50d0022c36a638382d9b7aab898ee74997d2530f24a5ff45e4c96fc9864787c9e9dd + "@formatjs/ecma402-abstract": "npm:2.3.4" + "@formatjs/intl-localematcher": "npm:0.6.1" + tslib: "npm:^2.8.0" + checksum: 10c0/f84974d00a020cf9f7c153c56f2bb20a104b1cce33c6672c491c842f2b2367d6746bc903a7f18e922da1a89c7ee6edd9e79bf6971dd26c41b6c9faaa76e6c57e languageName: node linkType: hard @@ -2486,37 +2643,37 @@ __metadata: languageName: node linkType: hard -"@livekit/components-core@npm:0.12.1, @livekit/components-core@npm:^0.12.0": - version: 0.12.1 - resolution: "@livekit/components-core@npm:0.12.1" +"@livekit/components-core@npm:0.12.7, @livekit/components-core@npm:^0.12.0": + version: 0.12.7 + resolution: "@livekit/components-core@npm:0.12.7" dependencies: - "@floating-ui/dom": "npm:1.6.11" + "@floating-ui/dom": "npm:1.6.13" loglevel: "npm:1.9.1" - rxjs: "npm:7.8.1" + rxjs: "npm:7.8.2" peerDependencies: - livekit-client: ^2.8.1 + livekit-client: ^2.13.1 tslib: ^2.6.2 - checksum: 10c0/f995e40ae981de9fd8da64f8a99b41eea4f6edb733cdfae1ebfd0fbb861de0c399d7a46caacecdfde3a072c8707242dc710ade5b7dfc9983849fb96931316e0e + checksum: 10c0/11024e120f2b1b81688d507dc8441f663730956d4c79f66014a9f19a3723fcdee9517a09239f21d501067cc299bf97659655404048c415314c39bf6af5d8ab9d languageName: node linkType: hard "@livekit/components-react@npm:^2.0.0": - version: 2.8.1 - resolution: "@livekit/components-react@npm:2.8.1" + version: 2.9.9 + resolution: "@livekit/components-react@npm:2.9.9" dependencies: - "@livekit/components-core": "npm:0.12.1" + "@livekit/components-core": "npm:0.12.7" clsx: "npm:2.1.1" - usehooks-ts: "npm:3.1.0" + usehooks-ts: "npm:3.1.1" peerDependencies: "@livekit/krisp-noise-filter": ^0.2.12 - livekit-client: ^2.8.1 + livekit-client: ^2.13.1 react: ">=18" react-dom: ">=18" tslib: ^2.6.2 peerDependenciesMeta: "@livekit/krisp-noise-filter": optional: true - checksum: 10c0/94103ed63186ddc789daba819f0ffc55533c41082648d32f27be6eab797fd42251f6e489069d9f2883c5abcdfbdcc6461e9b01a5f0b9c68c7a961997a4c92e1e + checksum: 10c0/7b3dad637b0bfd91c5636b1bb2c72ecde6136a4222d552690a3b3088c6fe4a28fbc30d2e8fec643c7e90316d8419393e7636001d5d192f5f1c9254df1307df0d languageName: node linkType: hard @@ -2527,19 +2684,31 @@ __metadata: languageName: node linkType: hard -"@livekit/protocol@npm:1.36.1, @livekit/protocol@npm:^1.33.0": - version: 1.36.1 - resolution: "@livekit/protocol@npm:1.36.1" +"@livekit/protocol@npm:1.38.0, @livekit/protocol@npm:^1.38.0": + version: 1.38.0 + resolution: "@livekit/protocol@npm:1.38.0" dependencies: "@bufbuild/protobuf": "npm:^1.10.0" - checksum: 10c0/bb2e56785c542446bef3e2f2fd20b33d01db43b786be87ccb834feee8a664fd32c8231e249b4e1915d7a8eda13af0d59eea479fa710327079a1a370daf05c42e + checksum: 10c0/ca64d4f984853054ff60574730b08a761afcd3bdc084e5218663e54b0e7f395aa2022d9d15d982fa094bbc0179cb19ef6a96ec74b1aa3265d118a85d1a4fde33 languageName: node linkType: hard -"@matrix-org/matrix-sdk-crypto-wasm@npm:^14.0.1": - version: 14.0.1 - resolution: "@matrix-org/matrix-sdk-crypto-wasm@npm:14.0.1" - checksum: 10c0/6e98abb61f8d6c43b26f04e83db92b39db74352861495eda9ac472b2f58411a45b2f150e4361c44c6800f98f99e89350d11941e87b9bf22204c9cab83ca93e27 +"@livekit/track-processors@npm:^0.5.5": + version: 0.5.7 + resolution: "@livekit/track-processors@npm:0.5.7" + dependencies: + "@mediapipe/tasks-vision": "npm:0.10.14" + peerDependencies: + "@types/dom-mediacapture-transform": ^0.1.9 + livekit-client: ^1.12.0 || ^2.1.0 + checksum: 10c0/e06c1a393303290184574386c705d4b8d93e323f360aabfc417c026d2128669aaca67e99b8bf5481650d38ae7c142d0d69585f4d3bf5bbbbaa474cd3d1de0046 + languageName: node + linkType: hard + +"@matrix-org/matrix-sdk-crypto-wasm@npm:^14.2.0": + version: 14.2.0 + resolution: "@matrix-org/matrix-sdk-crypto-wasm@npm:14.2.0" + checksum: 10c0/cc51417d71ffe506401dbb85ff4930bf89b33b6718c9052ba3cc1b2989e989e5e7e6fceea7c5fb58576d64e7a5c947c4cece89dbfa785083d293508c80e0713d languageName: node linkType: hard @@ -2550,6 +2719,24 @@ __metadata: languageName: node linkType: hard +"@mediapipe/tasks-vision@npm:^0.10.18": + version: 0.10.21 + resolution: "@mediapipe/tasks-vision@npm:0.10.21" + checksum: 10c0/11b2bdf98b8cb6e044f2a954e7c8393169e62c86ff49b3d0b61c3b327d18e1ccd47a187999b023bad48380c9da41bfa66eb165301c80da07746390482cb18a19 + languageName: node + linkType: hard + +"@napi-rs/wasm-runtime@npm:^0.2.9": + version: 0.2.10 + resolution: "@napi-rs/wasm-runtime@npm:0.2.10" + dependencies: + "@emnapi/core": "npm:^1.4.3" + "@emnapi/runtime": "npm:^1.4.3" + "@tybys/wasm-util": "npm:^0.9.0" + checksum: 10c0/4dce9bbb94a8969805574e1b55fdbeb7623348190265d77f6507ba32e535610deeb53a33ba0bb8b05a6520f379d418b92e8a01c5cd7b9486b136d2c0c26be0bd + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -2560,16 +2747,6 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.scandir@npm:4.0.1": - version: 4.0.1 - resolution: "@nodelib/fs.scandir@npm:4.0.1" - dependencies: - "@nodelib/fs.stat": "npm:4.0.0" - run-parallel: "npm:^1.2.0" - checksum: 10c0/b5d73e3c705ea3fa88795448d330bf02c214a225475793ccb5e7da88a7067e5eb03197691112f0b3f60367d9d5239293a1dd23bd0192435c98b6efae6461e5b5 - languageName: node - linkType: hard - "@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": version: 2.0.5 resolution: "@nodelib/fs.stat@npm:2.0.5" @@ -2577,23 +2754,6 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.stat@npm:4.0.0": - version: 4.0.0 - resolution: "@nodelib/fs.stat@npm:4.0.0" - checksum: 10c0/f44ff60c76a83484d929d231510c8d9f8a9162674bf63b03149ed25ab944010b4603770d845ac671ddba1c9615f3201e46fc22b782d8d4b28ad4d62f5fd19125 - languageName: node - linkType: hard - -"@nodelib/fs.walk@npm:3.0.1": - version: 3.0.1 - resolution: "@nodelib/fs.walk@npm:3.0.1" - dependencies: - "@nodelib/fs.scandir": "npm:4.0.1" - fastq: "npm:^1.15.0" - checksum: 10c0/1c14b9bd4d9429fca2c4dd89a07fb7d85421d32bca2c5edf2654afe9600c8137c7785dc055da7ddc8b2a1f194f0987b101706edff408976c6a8808fa0eeb691c - languageName: node - linkType: hard - "@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" @@ -2746,12 +2906,12 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/api-logs@npm:0.57.2": - version: 0.57.2 - resolution: "@opentelemetry/api-logs@npm:0.57.2" +"@opentelemetry/api-logs@npm:0.201.1": + version: 0.201.1 + resolution: "@opentelemetry/api-logs@npm:0.201.1" dependencies: "@opentelemetry/api": "npm:^1.3.0" - checksum: 10c0/1e514d3fd4ca68e7e8b008794a95ee0562a5d9e1d3ebb02647b245afaa6c2d72cc14e99e3ea47a1d1007f8a965c62bfb6170e1aa26756230bea063cfde2898bf + checksum: 10c0/f5652a7d1dbfcba9d9a9b0e53a1debb428c99f859e833f14c09e471c0f01614245558bf3a4c0e9bda39c2031c10fa172ba3a564509aad56e5c8a30550a488170 languageName: node linkType: hard @@ -2762,135 +2922,220 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/core@npm:1.30.1, @opentelemetry/core@npm:^1.25.1": - version: 1.30.1 - resolution: "@opentelemetry/core@npm:1.30.1" +"@opentelemetry/core@npm:2.0.1, @opentelemetry/core@npm:^2.0.0": + version: 2.0.1 + resolution: "@opentelemetry/core@npm:2.0.1" dependencies: - "@opentelemetry/semantic-conventions": "npm:1.28.0" + "@opentelemetry/semantic-conventions": "npm:^1.29.0" peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10c0/4c25ba50a6137c2ba9ca563fb269378f3c9ca6fd1b3f15dbb6eff78eebf5656f281997cbb7be8e51c01649fd6ad091083fcd8a42dd9b5dfac907dc06d7cfa092 + checksum: 10c0/d587b1289559757d80da98039f9f57612f84f72ec608cd665dc467c7c6c5ce3a987dfcc2c63b521c7c86ce984a2552b3ead15a0dc458de1cf6bde5cdfe4ca9d8 languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-http@npm:^0.57.0": - version: 0.57.2 - resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.57.2" +"@opentelemetry/exporter-trace-otlp-http@npm:^0.201.0": + version: 0.201.1 + resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.201.1" dependencies: - "@opentelemetry/core": "npm:1.30.1" - "@opentelemetry/otlp-exporter-base": "npm:0.57.2" - "@opentelemetry/otlp-transformer": "npm:0.57.2" - "@opentelemetry/resources": "npm:1.30.1" - "@opentelemetry/sdk-trace-base": "npm:1.30.1" + "@opentelemetry/core": "npm:2.0.1" + "@opentelemetry/otlp-exporter-base": "npm:0.201.1" + "@opentelemetry/otlp-transformer": "npm:0.201.1" + "@opentelemetry/resources": "npm:2.0.1" + "@opentelemetry/sdk-trace-base": "npm:2.0.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10c0/ccf0f8c573173ed3e735dc007600ec0cc04469f85784acff69fcdaa3423d25f87068618d1454b725f684fbc72481d0d383dac02406a27ba750ce38321bfe718a + checksum: 10c0/4577663406cb2f6f65735dad61eb95a482f2a60b2b9b7b7574350aa80a1a29872113673b5b3c3d2949e2af93f601eb033498e160c329216d6912da679c2c455c languageName: node linkType: hard -"@opentelemetry/otlp-exporter-base@npm:0.57.2": - version: 0.57.2 - resolution: "@opentelemetry/otlp-exporter-base@npm:0.57.2" +"@opentelemetry/otlp-exporter-base@npm:0.201.1": + version: 0.201.1 + resolution: "@opentelemetry/otlp-exporter-base@npm:0.201.1" dependencies: - "@opentelemetry/core": "npm:1.30.1" - "@opentelemetry/otlp-transformer": "npm:0.57.2" + "@opentelemetry/core": "npm:2.0.1" + "@opentelemetry/otlp-transformer": "npm:0.201.1" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10c0/56e0b7f3c7ff38a53c7976d87dc6bb4d4830f3be42c93f6d079d66b7e4f9f6004f62b853149e831ae936782716fb7ea7a7ca7871527fa7d09d73a2aa90880d21 + checksum: 10c0/3bdabddd24623e9545607d250dd772579a436cde2782aa4edcedc2184a619f3d3a9740dc41bf24b97f4b24ef00d1d51c8b8496ba91432fcb75760edaf447b123 languageName: node linkType: hard -"@opentelemetry/otlp-transformer@npm:0.57.2": - version: 0.57.2 - resolution: "@opentelemetry/otlp-transformer@npm:0.57.2" +"@opentelemetry/otlp-transformer@npm:0.201.1": + version: 0.201.1 + resolution: "@opentelemetry/otlp-transformer@npm:0.201.1" dependencies: - "@opentelemetry/api-logs": "npm:0.57.2" - "@opentelemetry/core": "npm:1.30.1" - "@opentelemetry/resources": "npm:1.30.1" - "@opentelemetry/sdk-logs": "npm:0.57.2" - "@opentelemetry/sdk-metrics": "npm:1.30.1" - "@opentelemetry/sdk-trace-base": "npm:1.30.1" + "@opentelemetry/api-logs": "npm:0.201.1" + "@opentelemetry/core": "npm:2.0.1" + "@opentelemetry/resources": "npm:2.0.1" + "@opentelemetry/sdk-logs": "npm:0.201.1" + "@opentelemetry/sdk-metrics": "npm:2.0.1" + "@opentelemetry/sdk-trace-base": "npm:2.0.1" protobufjs: "npm:^7.3.0" peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 10c0/094979421768c5ac0672d1ce62bbc710a8cc836eb24e1cdfe5fb2c5c55908d19cf35fd6810cd266e7444d5677087846d5a8959df5886dfe1774199a3ae1d50a4 + checksum: 10c0/c92eaca64c2d2c5299fa3778674e1fc06d58686bbb3e61c80a4dfc190d2d4fed37720e88e9301c5f0bea1c29eaa2e91a0a221d7c48ab0271b924483857e3f679 languageName: node linkType: hard -"@opentelemetry/resources@npm:1.30.1, @opentelemetry/resources@npm:^1.25.1": - version: 1.30.1 - resolution: "@opentelemetry/resources@npm:1.30.1" +"@opentelemetry/resources@npm:2.0.1, @opentelemetry/resources@npm:^2.0.0": + version: 2.0.1 + resolution: "@opentelemetry/resources@npm:2.0.1" dependencies: - "@opentelemetry/core": "npm:1.30.1" - "@opentelemetry/semantic-conventions": "npm:1.28.0" - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10c0/688e73258283c80662bfa9a858aaf73bf3b832a18d96e546d0dddfa6dcec556cdfa087a1d0df643435293406009e4122d7fb7eeea69aa87b539d3bab756fba74 - languageName: node - linkType: hard - -"@opentelemetry/sdk-logs@npm:0.57.2": - version: 0.57.2 - resolution: "@opentelemetry/sdk-logs@npm:0.57.2" - dependencies: - "@opentelemetry/api-logs": "npm:0.57.2" - "@opentelemetry/core": "npm:1.30.1" - "@opentelemetry/resources": "npm:1.30.1" - peerDependencies: - "@opentelemetry/api": ">=1.4.0 <1.10.0" - checksum: 10c0/dda61cf656a93d2f5ef1ca0495db59bfa33efc8ca7ee11018850a9ff78ee0459fb0393e70be7ae5d3cd084e0652d36fbf5778c7b3e9028c6668f9bf0d6c9473e - languageName: node - linkType: hard - -"@opentelemetry/sdk-metrics@npm:1.30.1": - version: 1.30.1 - resolution: "@opentelemetry/sdk-metrics@npm:1.30.1" - dependencies: - "@opentelemetry/core": "npm:1.30.1" - "@opentelemetry/resources": "npm:1.30.1" + "@opentelemetry/core": "npm:2.0.1" + "@opentelemetry/semantic-conventions": "npm:^1.29.0" peerDependencies: "@opentelemetry/api": ">=1.3.0 <1.10.0" - checksum: 10c0/7e60178e61eaf49db5d74f6c3701706762d71d370044253c72bb5668dba3a435030ed6847605ee55d0e1b8908ad123a2517b5f00415a2fb3d98468a0a318e3c0 + checksum: 10c0/96532b7553b26607a7a892d72f6b03ad12bd542dc23c95135a8ae40362da9c883c21a4cff3d2296d9e0e9bd899a5977e325ed52d83142621a8ffe81d08d99341 languageName: node linkType: hard -"@opentelemetry/sdk-trace-base@npm:1.30.1, @opentelemetry/sdk-trace-base@npm:^1.25.1": - version: 1.30.1 - resolution: "@opentelemetry/sdk-trace-base@npm:1.30.1" +"@opentelemetry/sdk-logs@npm:0.201.1": + version: 0.201.1 + resolution: "@opentelemetry/sdk-logs@npm:0.201.1" dependencies: - "@opentelemetry/core": "npm:1.30.1" - "@opentelemetry/resources": "npm:1.30.1" - "@opentelemetry/semantic-conventions": "npm:1.28.0" + "@opentelemetry/api-logs": "npm:0.201.1" + "@opentelemetry/core": "npm:2.0.1" + "@opentelemetry/resources": "npm:2.0.1" + peerDependencies: + "@opentelemetry/api": ">=1.4.0 <1.10.0" + checksum: 10c0/10ebac2d27802c6708cd38517dba847a629236fb32edf6a1f984b60580e884c7b4be8c6e70def6c3a328d581f5f780fbf09b934eba4e9aabfe9248be619f7341 + languageName: node + linkType: hard + +"@opentelemetry/sdk-metrics@npm:2.0.1": + version: 2.0.1 + resolution: "@opentelemetry/sdk-metrics@npm:2.0.1" + dependencies: + "@opentelemetry/core": "npm:2.0.1" + "@opentelemetry/resources": "npm:2.0.1" + peerDependencies: + "@opentelemetry/api": ">=1.9.0 <1.10.0" + checksum: 10c0/fcf7ae23d459e5da7cb6fe150064b6dc4e11e47925b08980c3b357bd5534ad388898bbacd0ff8befef6801f43b35142dc7123f028ffde2d0fe2bd72177d07639 + languageName: node + linkType: hard + +"@opentelemetry/sdk-trace-base@npm:2.0.1, @opentelemetry/sdk-trace-base@npm:^2.0.0": + version: 2.0.1 + resolution: "@opentelemetry/sdk-trace-base@npm:2.0.1" + dependencies: + "@opentelemetry/core": "npm:2.0.1" + "@opentelemetry/resources": "npm:2.0.1" + "@opentelemetry/semantic-conventions": "npm:^1.29.0" + peerDependencies: + "@opentelemetry/api": ">=1.3.0 <1.10.0" + checksum: 10c0/4e3c733296012b758d007e9c0d8a5b175edbe9a680c73ec75303476e7982b73ad4209f1a2791c1a94c428e5a53eba6c2a72faa430c70336005aa58744d6cb37b + languageName: node + linkType: hard + +"@opentelemetry/sdk-trace-web@npm:^2.0.0": + version: 2.0.1 + resolution: "@opentelemetry/sdk-trace-web@npm:2.0.1" + dependencies: + "@opentelemetry/core": "npm:2.0.1" + "@opentelemetry/sdk-trace-base": "npm:2.0.1" peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10c0/77019dc3efaeceb41b4c54dd83b92f0ccd81ecceca544cbbe8e0aee4b2c8727724bdb9dcecfe00622c16d60946ae4beb69a5c0e7d85c4bc7ef425bd84f8b970c + checksum: 10c0/48821b91430e24378b0b5b2632e78efdd018a3f840462a6aeba6ce318a6480bad2f623cc7f7f625a9266028ad44b78eb8456181778de6cb18725f26c44e2729b languageName: node linkType: hard -"@opentelemetry/sdk-trace-web@npm:^1.9.1": - version: 1.30.1 - resolution: "@opentelemetry/sdk-trace-web@npm:1.30.1" +"@opentelemetry/semantic-conventions@npm:^1.25.1, @opentelemetry/semantic-conventions@npm:^1.29.0": + version: 1.34.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.34.0" + checksum: 10c0/a51a32a5cf5c803bd2125a680d0abacbff632f3b255d0fe52379dac191114a0e8d72a34f9c46c5483ccfe91c4061c309f3cf61a19d11347e2a69779e82cfefd0 + languageName: node + linkType: hard + +"@oxc-resolver/binding-darwin-arm64@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-darwin-arm64@npm:9.0.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@oxc-resolver/binding-darwin-x64@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-darwin-x64@npm:9.0.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@oxc-resolver/binding-freebsd-x64@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-freebsd-x64@npm:9.0.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-arm-gnueabihf@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-arm-gnueabihf@npm:9.0.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-arm64-gnu@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-arm64-gnu@npm:9.0.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-arm64-musl@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-arm64-musl@npm:9.0.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-riscv64-gnu@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-riscv64-gnu@npm:9.0.2" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-s390x-gnu@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-s390x-gnu@npm:9.0.2" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-x64-gnu@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-x64-gnu@npm:9.0.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-resolver/binding-linux-x64-musl@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-linux-x64-musl@npm:9.0.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@oxc-resolver/binding-wasm32-wasi@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-wasm32-wasi@npm:9.0.2" dependencies: - "@opentelemetry/core": "npm:1.30.1" - "@opentelemetry/sdk-trace-base": "npm:1.30.1" - "@opentelemetry/semantic-conventions": "npm:1.28.0" - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10c0/8dd2901b5eef68a5896da0ad11f04c8990ce4ef2dcbec27bbc02d7e193097c270ba5f4c9ca363ea10fb53ca7cc515f18d9dc383a69a17720cd0590474c0ffdaf + "@napi-rs/wasm-runtime": "npm:^0.2.9" + conditions: cpu=wasm32 languageName: node linkType: hard -"@opentelemetry/semantic-conventions@npm:1.28.0": - version: 1.28.0 - resolution: "@opentelemetry/semantic-conventions@npm:1.28.0" - checksum: 10c0/deb8a0f744198071e70fea27143cf7c9f7ecb7e4d7b619488c917834ea09b31543c1c2bcea4ec5f3cf68797f0ef3549609c14e859013d9376400ac1499c2b9cb +"@oxc-resolver/binding-win32-arm64-msvc@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-win32-arm64-msvc@npm:9.0.2" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@opentelemetry/semantic-conventions@npm:^1.25.1": - version: 1.30.0 - resolution: "@opentelemetry/semantic-conventions@npm:1.30.0" - checksum: 10c0/0bf99552e3b4b7e8b7eb504b678d52f59c6f259df88e740a2011a0d858e523d36fee86047ae1b7f45849c77f00f970c3059ba58e0a06a7d47d6f01dbe8c455bd +"@oxc-resolver/binding-win32-x64-msvc@npm:9.0.2": + version: 9.0.2 + resolution: "@oxc-resolver/binding-win32-x64-msvc@npm:9.0.2" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -3045,14 +3290,14 @@ __metadata: languageName: node linkType: hard -"@playwright/test@npm:^1.51.0": - version: 1.51.0 - resolution: "@playwright/test@npm:1.51.0" +"@playwright/test@npm:^1.52.0": + version: 1.52.0 + resolution: "@playwright/test@npm:1.52.0" dependencies: - playwright: "npm:1.51.0" + playwright: "npm:1.52.0" bin: playwright: cli.js - checksum: 10c0/ae83dd2c3a32133de58f44a9dbcd73a8059155ebd8acc736ba8bd0a7ca99b194afe2e8f5a500861d18b1c8f06b4e4ea8de4a2402297c59053d4becc404b47e0a + checksum: 10c0/1c428b421593eb4f79b7c99783a389c3ab3526c9051ec772749f4fca61414dfa9f2344eba846faac5f238084aa96c836364a91d81d3034ac54924f239a93e247 languageName: node linkType: hard @@ -3129,10 +3374,10 @@ __metadata: languageName: node linkType: hard -"@radix-ui/number@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/number@npm:1.1.0" - checksum: 10c0/a48e34d5ff1484de1b7cf5d7317fefc831d49e96a2229f300fd37b657bd8cfb59c922830c00ec02838ab21de3b299a523474592e4f30882153412ed47edce6a4 +"@radix-ui/number@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/number@npm:1.1.1" + checksum: 10c0/0570ad92287398e8a7910786d7cee0a998174cdd6637ba61571992897c13204adf70b9ed02d0da2af554119411128e701d9c6b893420612897b438dc91db712b languageName: node linkType: hard @@ -3143,6 +3388,13 @@ __metadata: languageName: node linkType: hard +"@radix-ui/primitive@npm:1.1.2": + version: 1.1.2 + resolution: "@radix-ui/primitive@npm:1.1.2" + checksum: 10c0/5e2d2528d2fe37c16865e77b0beaac2b415a817ad13d8178db6e8187b2a092672568a64ee0041510abfde3034490a5cadd3057049bb15789020c06892047597c + languageName: node + linkType: hard + "@radix-ui/react-arrow@npm:1.1.1": version: 1.1.1 resolution: "@radix-ui/react-arrow@npm:1.1.1" @@ -3184,14 +3436,14 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-collection@npm:1.1.2": - version: 1.1.2 - resolution: "@radix-ui/react-collection@npm:1.1.2" +"@radix-ui/react-collection@npm:1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-collection@npm:1.1.7" dependencies: - "@radix-ui/react-compose-refs": "npm:1.1.1" - "@radix-ui/react-context": "npm:1.1.1" - "@radix-ui/react-primitive": "npm:2.0.2" - "@radix-ui/react-slot": "npm:1.1.2" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-slot": "npm:1.2.3" peerDependencies: "@types/react": "*" "@types/react-dom": "*" @@ -3202,7 +3454,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10c0/8376aa0c0f38efbb45e5c0a2e8724b0ca2ccdab511f5aee4c3eb62a89959b20be0d4dd410b7068bc13d722751cbc88e916e10573784fb26b084c43f930818715 + checksum: 10c0/fa321a7300095508491f75414f02b243f0c3f179dc0728cfd115e2ea9f6f48f1516532b59f526d9ac81bbab63cd98a052074b4703ec0b9428fac945ebabec5fd languageName: node linkType: hard @@ -3219,6 +3471,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-compose-refs@npm:1.1.2": + version: 1.1.2 + resolution: "@radix-ui/react-compose-refs@npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/d36a9c589eb75d634b9b139c80f916aadaf8a68a7c1c4b8c6c6b88755af1a92f2e343457042089f04cc3f23073619d08bb65419ced1402e9d4e299576d970771 + languageName: node + linkType: hard + "@radix-ui/react-context-menu@npm:^2.2.1": version: 2.2.4 resolution: "@radix-ui/react-context-menu@npm:2.2.4" @@ -3256,22 +3521,35 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-context@npm:1.1.2": + version: 1.1.2 + resolution: "@radix-ui/react-context@npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/cece731f8cc25d494c6589cc681e5c01a93867d895c75889973afa1a255f163c286e390baa7bc028858eaabe9f6b57270d0ca6377356f652c5557c1c7a41ccce + languageName: node + linkType: hard + "@radix-ui/react-dialog@npm:^1.0.4, @radix-ui/react-dialog@npm:^1.1.1": - version: 1.1.6 - resolution: "@radix-ui/react-dialog@npm:1.1.6" + version: 1.1.14 + resolution: "@radix-ui/react-dialog@npm:1.1.14" dependencies: - "@radix-ui/primitive": "npm:1.1.1" - "@radix-ui/react-compose-refs": "npm:1.1.1" - "@radix-ui/react-context": "npm:1.1.1" - "@radix-ui/react-dismissable-layer": "npm:1.1.5" - "@radix-ui/react-focus-guards": "npm:1.1.1" - "@radix-ui/react-focus-scope": "npm:1.1.2" - "@radix-ui/react-id": "npm:1.1.0" - "@radix-ui/react-portal": "npm:1.1.4" - "@radix-ui/react-presence": "npm:1.1.2" - "@radix-ui/react-primitive": "npm:2.0.2" - "@radix-ui/react-slot": "npm:1.1.2" - "@radix-ui/react-use-controllable-state": "npm:1.1.0" + "@radix-ui/primitive": "npm:1.1.2" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-dismissable-layer": "npm:1.1.10" + "@radix-ui/react-focus-guards": "npm:1.1.2" + "@radix-ui/react-focus-scope": "npm:1.1.7" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-portal": "npm:1.1.9" + "@radix-ui/react-presence": "npm:1.1.4" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-slot": "npm:1.2.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" aria-hidden: "npm:^1.2.4" react-remove-scroll: "npm:^2.6.3" peerDependencies: @@ -3284,7 +3562,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10c0/98e425549573c5d6fb0fee94ecd40427a8b8897bb2d9bb2a44fe64e484754376ff23b64fcf64e061d42fc774b9627a28cb5b1bb5652e567908dac9a8d8618705 + checksum: 10c0/ab7bc783510ed8fccfe91020b214f4a571d5a1d46d398faa33f4c151bc9f586c47483b307e72b67687b06694c194b3aa80dd1de728460fa765db9f3057690ba3 languageName: node linkType: hard @@ -3301,6 +3579,42 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-direction@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-direction@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/7a89d9291f846a3105e45f4df98d6b7a08f8d7b30acdcd253005dc9db107ee83cbbebc9e47a9af1e400bcd47697f1511ceab23a399b0da854488fc7220482ac9 + languageName: node + linkType: hard + +"@radix-ui/react-dismissable-layer@npm:1.1.10": + version: 1.1.10 + resolution: "@radix-ui/react-dismissable-layer@npm:1.1.10" + dependencies: + "@radix-ui/primitive": "npm:1.1.2" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + "@radix-ui/react-use-escape-keydown": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/21a2d03689f5e06586135b6a735937ef14f2571fdf6044a3019bc3f9fa368a9400b5a9b631f43e8ad3682693449e369ffa7cc8642764246ce18ebe7359a45faf + languageName: node + linkType: hard + "@radix-ui/react-dismissable-layer@npm:1.1.3": version: 1.1.3 resolution: "@radix-ui/react-dismissable-layer@npm:1.1.3" @@ -3324,29 +3638,6 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-dismissable-layer@npm:1.1.5": - version: 1.1.5 - resolution: "@radix-ui/react-dismissable-layer@npm:1.1.5" - dependencies: - "@radix-ui/primitive": "npm:1.1.1" - "@radix-ui/react-compose-refs": "npm:1.1.1" - "@radix-ui/react-primitive": "npm:2.0.2" - "@radix-ui/react-use-callback-ref": "npm:1.1.0" - "@radix-ui/react-use-escape-keydown": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/05c5adfcd42a736c456f50bdca25bf7f6b25eef7328e4c05de535fea128328666433a89d68cb1445e039c188d7f1397df6a4a02e2da0970762f2a80fd29b48ea - languageName: node - linkType: hard - "@radix-ui/react-dropdown-menu@npm:^2.1.1": version: 2.1.4 resolution: "@radix-ui/react-dropdown-menu@npm:2.1.4" @@ -3385,6 +3676,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-focus-guards@npm:1.1.2": + version: 1.1.2 + resolution: "@radix-ui/react-focus-guards@npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/8d6fa55752b9b6e55d1eebb643178e38a824e8ba418eb29031b2979077a12c4e3922892de9f984dd326f77071a14960cd81e99a960beea07598b8c80da618dc5 + languageName: node + linkType: hard + "@radix-ui/react-focus-scope@npm:1.1.1": version: 1.1.1 resolution: "@radix-ui/react-focus-scope@npm:1.1.1" @@ -3406,13 +3710,13 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-focus-scope@npm:1.1.2": - version: 1.1.2 - resolution: "@radix-ui/react-focus-scope@npm:1.1.2" +"@radix-ui/react-focus-scope@npm:1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-focus-scope@npm:1.1.7" dependencies: - "@radix-ui/react-compose-refs": "npm:1.1.1" - "@radix-ui/react-primitive": "npm:2.0.2" - "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" peerDependencies: "@types/react": "*" "@types/react-dom": "*" @@ -3423,7 +3727,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10c0/7b93866a9980bc938fc3fcfacfc49467c13144931c9b7a3b5423c0c3817685dc421499d73f58335f6c3c1c0f4fea9c9b7c16aa06a1d30571620787086082bea0 + checksum: 10c0/8a6071331bdeeb79b223463de75caf759b8ad19339cab838e537b8dbb2db236891a1f4df252445c854d375d43d9d315dfcce0a6b01553a2984ec372bb8f1300e languageName: node linkType: hard @@ -3466,6 +3770,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-id@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-id@npm:1.1.1" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/7d12e76818763d592c331277ef62b197e2e64945307e650bd058f0090e5ae48bbd07691b23b7e9e977901ef4eadcb3e2d5eaeb17a13859083384be83fc1292c7 + languageName: node + linkType: hard + "@radix-ui/react-label@npm:2.1.1": version: 2.1.1 resolution: "@radix-ui/react-label@npm:2.1.1" @@ -3569,12 +3888,12 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-portal@npm:1.1.4": - version: 1.1.4 - resolution: "@radix-ui/react-portal@npm:1.1.4" +"@radix-ui/react-portal@npm:1.1.9": + version: 1.1.9 + resolution: "@radix-ui/react-portal@npm:1.1.9" dependencies: - "@radix-ui/react-primitive": "npm:2.0.2" - "@radix-ui/react-use-layout-effect": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" peerDependencies: "@types/react": "*" "@types/react-dom": "*" @@ -3585,7 +3904,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10c0/e4038eb2f20be10d9754d099d00620f429711919d20c4c630946d9c4941f1c83ef1a3f4110c221c70486e65bc565ebba4ada22a0e7e2d179c039f2a014300793 + checksum: 10c0/45b432497c722720c72c493a29ef6085bc84b50eafe79d48b45c553121b63e94f9cdb77a3a74b9c49126f8feb3feee009fe400d48b7759d3552396356b192cd7 languageName: node linkType: hard @@ -3609,6 +3928,26 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-presence@npm:1.1.4": + version: 1.1.4 + resolution: "@radix-ui/react-presence@npm:1.1.4" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/8202647139d6f5097b0abcc43dfba471c00b69da95ca336afe3ea23a165e05ca21992f40fc801760fe442f3e064e54e2f2cbcb9ad758c4b07ef6c69a5b6777bd + languageName: node + linkType: hard + "@radix-ui/react-primitive@npm:2.0.1": version: 2.0.1 resolution: "@radix-ui/react-primitive@npm:2.0.1" @@ -3628,11 +3967,11 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-primitive@npm:2.0.2": - version: 2.0.2 - resolution: "@radix-ui/react-primitive@npm:2.0.2" +"@radix-ui/react-primitive@npm:2.1.3": + version: 2.1.3 + resolution: "@radix-ui/react-primitive@npm:2.1.3" dependencies: - "@radix-ui/react-slot": "npm:1.1.2" + "@radix-ui/react-slot": "npm:1.2.3" peerDependencies: "@types/react": "*" "@types/react-dom": "*" @@ -3643,7 +3982,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10c0/1af7a33a86f8bd2467f2300b1bb6ca9af67cae3950953ba543d2a625c17f341dff05d19056ece7b03e5ced8b9f8de99c74f806710ce0da6b9a000f2af063fffe + checksum: 10c0/fdff9b84913bb4172ef6d3af7442fca5f9bba5f2709cba08950071f819d7057aec3a4a2d9ef44cf9cbfb8014d02573c6884a04cff175895823aaef809ebdb034 languageName: node linkType: hard @@ -3714,20 +4053,20 @@ __metadata: linkType: hard "@radix-ui/react-slider@npm:^1.1.2": - version: 1.2.3 - resolution: "@radix-ui/react-slider@npm:1.2.3" + version: 1.3.5 + resolution: "@radix-ui/react-slider@npm:1.3.5" dependencies: - "@radix-ui/number": "npm:1.1.0" - "@radix-ui/primitive": "npm:1.1.1" - "@radix-ui/react-collection": "npm:1.1.2" - "@radix-ui/react-compose-refs": "npm:1.1.1" - "@radix-ui/react-context": "npm:1.1.1" - "@radix-ui/react-direction": "npm:1.1.0" - "@radix-ui/react-primitive": "npm:2.0.2" - "@radix-ui/react-use-controllable-state": "npm:1.1.0" - "@radix-ui/react-use-layout-effect": "npm:1.1.0" - "@radix-ui/react-use-previous": "npm:1.1.0" - "@radix-ui/react-use-size": "npm:1.1.0" + "@radix-ui/number": "npm:1.1.1" + "@radix-ui/primitive": "npm:1.1.2" + "@radix-ui/react-collection": "npm:1.1.7" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-direction": "npm:1.1.1" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + "@radix-ui/react-use-previous": "npm:1.1.1" + "@radix-ui/react-use-size": "npm:1.1.1" peerDependencies: "@types/react": "*" "@types/react-dom": "*" @@ -3738,7 +4077,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10c0/d1b3b193e3a290e734d911d99ddc2d8857c21cd1bebd3c6607c5e034c02e410b77be9d836479de2240c283cd9e2017ac6f5c5fec37f9b3c64e1abe46581327d1 + checksum: 10c0/2f5f37f953d78ac02ed74120afe76badf3a7d0e19036f4de6cdeda38220718a1d5113ffc2f43e0b3de73e14564cae9a09d1968ee3f9641625849d126a036717f languageName: node linkType: hard @@ -3757,18 +4096,18 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-slot@npm:1.1.2": - version: 1.1.2 - resolution: "@radix-ui/react-slot@npm:1.1.2" +"@radix-ui/react-slot@npm:1.2.3": + version: 1.2.3 + resolution: "@radix-ui/react-slot@npm:1.2.3" dependencies: - "@radix-ui/react-compose-refs": "npm:1.1.1" + "@radix-ui/react-compose-refs": "npm:1.1.2" peerDependencies: "@types/react": "*" react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/81d45091806c52b507cec80b4477e4f31189d76ffcd7845b382eb3a034e6cf1faef71b881612028d5893f7580bf9ab59daa18fbf2792042dccd755c99a18df67 + checksum: 10c0/5913aa0d760f505905779515e4b1f0f71a422350f077cc8d26d1aafe53c97f177fec0e6d7fbbb50d8b5e498aa9df9f707ca75ae3801540c283b26b0136138eef languageName: node linkType: hard @@ -3785,6 +4124,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-callback-ref@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-callback-ref@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/5f6aff8592dea6a7e46589808912aba3fb3b626cf6edd2b14f01638b61dbbe49eeb9f67cd5601f4c15b2fb547b9a7e825f7c4961acd4dd70176c969ae405f8d8 + languageName: node + linkType: hard + "@radix-ui/react-use-controllable-state@npm:1.1.0": version: 1.1.0 resolution: "@radix-ui/react-use-controllable-state@npm:1.1.0" @@ -3800,6 +4152,37 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-controllable-state@npm:1.2.2": + version: 1.2.2 + resolution: "@radix-ui/react-use-controllable-state@npm:1.2.2" + dependencies: + "@radix-ui/react-use-effect-event": "npm:0.0.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/f55c4b06e895293aed4b44c9ef26fb24432539f5346fcd6519c7745800535b571058685314e83486a45bf61dc83887e24826490d3068acc317fb0a9010516e63 + languageName: node + linkType: hard + +"@radix-ui/react-use-effect-event@npm:0.0.2": + version: 0.0.2 + resolution: "@radix-ui/react-use-effect-event@npm:0.0.2" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/e84ff72a3e76c5ae9c94941028bb4b6472f17d4104481b9eab773deab3da640ecea035e54da9d6f4df8d84c18ef6913baf92b7511bee06930dc58bd0c0add417 + languageName: node + linkType: hard + "@radix-ui/react-use-escape-keydown@npm:1.1.0": version: 1.1.0 resolution: "@radix-ui/react-use-escape-keydown@npm:1.1.0" @@ -3815,6 +4198,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-escape-keydown@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-escape-keydown@npm:1.1.1" + dependencies: + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/bff53be99e940fef1d3c4df7d560e1d9133182e5a98336255d3063327d1d3dd4ec54a95dc5afe15cca4fb6c184f0a956c70de2815578c318cf995a7f9beabaa1 + languageName: node + linkType: hard + "@radix-ui/react-use-layout-effect@npm:1.1.0": version: 1.1.0 resolution: "@radix-ui/react-use-layout-effect@npm:1.1.0" @@ -3828,16 +4226,29 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-use-previous@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-use-previous@npm:1.1.0" +"@radix-ui/react-use-layout-effect@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-layout-effect@npm:1.1.1" peerDependencies: "@types/react": "*" react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/9787d24790d4e330715127f2f4db56c4cbed9b0a47f97e11a68582c08a356a53c1ec41c7537382f6fb8d0db25de152770f17430e8eaf0fa59705be97760acbad + checksum: 10c0/9f98fdaba008dfc58050de60a77670b885792df473cf82c1cef8daee919a5dd5a77d270209f5f0b0abfaac78cb1627396e3ff56c81b735be550409426fe8b040 + languageName: node + linkType: hard + +"@radix-ui/react-use-previous@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-previous@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/52f1089d941491cd59b7f52a5679a14e9381711419a0557ce0f3bc9a4c117078224efec54dcced41a3653a13a386a7b6ec75435d61a273e8b9f5d00235f2b182 languageName: node linkType: hard @@ -3871,11 +4282,26 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-visually-hidden@npm:^1.0.3": - version: 1.1.2 - resolution: "@radix-ui/react-visually-hidden@npm:1.1.2" +"@radix-ui/react-use-size@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-size@npm:1.1.1" dependencies: - "@radix-ui/react-primitive": "npm:2.0.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/851d09a816f44282e0e9e2147b1b571410174cc048703a50c4fa54d672de994fd1dfff1da9d480ecfd12c77ae8f48d74f01adaf668f074156b8cd0043c6c21d8 + languageName: node + linkType: hard + +"@radix-ui/react-visually-hidden@npm:^1.0.3": + version: 1.2.3 + resolution: "@radix-ui/react-visually-hidden@npm:1.2.3" + dependencies: + "@radix-ui/react-primitive": "npm:2.1.3" peerDependencies: "@types/react": "*" "@types/react-dom": "*" @@ -3886,7 +4312,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10c0/ea6dc8ec284b32bca6f24809db257394802e14af7c95e4a237af51009fa222c42e3b7a55b3bfc94d753f509086636555058ae8e535be25956c46529abf41b448 + checksum: 10c0/cf86a37f1cbee50a964056f3dc4f6bb1ee79c76daa321f913aa20ff3e1ccdfafbf2b114d7bb616aeefc7c4b895e6ca898523fdb67710d89bd5d8edb739a0d9b6 languageName: node linkType: hard @@ -3963,6 +4389,13 @@ __metadata: languageName: node linkType: hard +"@rolldown/pluginutils@npm:1.0.0-beta.9": + version: 1.0.0-beta.9 + resolution: "@rolldown/pluginutils@npm:1.0.0-beta.9" + checksum: 10c0/21aebb7ebd093282efd96f63ddd465f76746b1d70282366d6ccc7fff6eb4da5c2f8f4bfaaaeb4283c2432600e5609e39e9897864575e593efc11d376ca1a6fa1 + languageName: node + linkType: hard + "@rollup/pluginutils@npm:^4.2.0": version: 4.2.1 resolution: "@rollup/pluginutils@npm:4.2.1" @@ -3989,142 +4422,142 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.37.0" +"@rollup/rollup-android-arm-eabi@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.40.2" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-android-arm64@npm:4.37.0" +"@rollup/rollup-android-arm64@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-android-arm64@npm:4.40.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-darwin-arm64@npm:4.37.0" +"@rollup/rollup-darwin-arm64@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.40.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-darwin-x64@npm:4.37.0" +"@rollup/rollup-darwin-x64@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-darwin-x64@npm:4.40.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.37.0" +"@rollup/rollup-freebsd-arm64@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.40.2" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-freebsd-x64@npm:4.37.0" +"@rollup/rollup-freebsd-x64@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-freebsd-x64@npm:4.40.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.37.0" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.40.2" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.37.0" +"@rollup/rollup-linux-arm-musleabihf@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.40.2" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.37.0" +"@rollup/rollup-linux-arm64-gnu@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.40.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.37.0" +"@rollup/rollup-linux-arm64-musl@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.40.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loongarch64-gnu@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.37.0" +"@rollup/rollup-linux-loongarch64-gnu@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.40.2" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.37.0" +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.2" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.37.0" +"@rollup/rollup-linux-riscv64-gnu@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.40.2" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.37.0" +"@rollup/rollup-linux-riscv64-musl@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.40.2" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.37.0" +"@rollup/rollup-linux-s390x-gnu@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.40.2" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.37.0" +"@rollup/rollup-linux-x64-gnu@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.40.2" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.37.0" +"@rollup/rollup-linux-x64-musl@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.40.2" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.37.0" +"@rollup/rollup-win32-arm64-msvc@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.40.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.37.0" +"@rollup/rollup-win32-ia32-msvc@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.40.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.37.0": - version: 4.37.0 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.37.0" +"@rollup/rollup-win32-x64-msvc@npm:4.40.2": + version: 4.40.2 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.40.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4174,10 +4607,10 @@ __metadata: languageName: node linkType: hard -"@sentry/babel-plugin-component-annotate@npm:3.2.1": - version: 3.2.1 - resolution: "@sentry/babel-plugin-component-annotate@npm:3.2.1" - checksum: 10c0/26ec2e7f8c0f46be4b78d109310cf07b218e6b288cf8dd19dd55226396f531beead93362bd2bf9e942a142d5db2bb9c4c0c4d202975ae620088d8b86b6ab5f50 +"@sentry/babel-plugin-component-annotate@npm:3.5.0": + version: 3.5.0 + resolution: "@sentry/babel-plugin-component-annotate@npm:3.5.0" + checksum: 10c0/875e898ddd23862384dfef455a60801fb1aae7b22744a61700bb3726c8a16c840bc2f0554ea4d2f887b606ceac29b1308e2da49f28b42ea58a0c20f60c2bd9e3 languageName: node linkType: hard @@ -4194,19 +4627,19 @@ __metadata: languageName: node linkType: hard -"@sentry/bundler-plugin-core@npm:3.2.1": - version: 3.2.1 - resolution: "@sentry/bundler-plugin-core@npm:3.2.1" +"@sentry/bundler-plugin-core@npm:3.5.0": + version: 3.5.0 + resolution: "@sentry/bundler-plugin-core@npm:3.5.0" dependencies: "@babel/core": "npm:^7.18.5" - "@sentry/babel-plugin-component-annotate": "npm:3.2.1" + "@sentry/babel-plugin-component-annotate": "npm:3.5.0" "@sentry/cli": "npm:2.42.2" dotenv: "npm:^16.3.1" find-up: "npm:^5.0.0" glob: "npm:^9.3.2" magic-string: "npm:0.30.8" unplugin: "npm:1.0.1" - checksum: 10c0/e88fea801534bde21d60cf325abb9933e0c2d2a992a918a331c684917416ace91eebc82a50f4f4dbe367d5094d57a09ba4da753dbdd2e16254f117d9f16e36d4 + checksum: 10c0/d7db2e2c67b0ccb8d5335e2fd77bfb1f403806b4cd3b94c8dd2233addf62c967891c67e720559600dae359e96a2ff1bde59fec678924fe31c3101b11f17e2b0c languageName: node linkType: hard @@ -4317,25 +4750,12 @@ __metadata: linkType: hard "@sentry/vite-plugin@npm:^3.0.0": - version: 3.2.1 - resolution: "@sentry/vite-plugin@npm:3.2.1" + version: 3.5.0 + resolution: "@sentry/vite-plugin@npm:3.5.0" dependencies: - "@sentry/bundler-plugin-core": "npm:3.2.1" + "@sentry/bundler-plugin-core": "npm:3.5.0" unplugin: "npm:1.0.1" - checksum: 10c0/7a85945d24d2c1bc1ecd52daa275c149087201166732cdd2836764ab41b1e0a58b7e1c49f51e6baff606a91be3b032544e95dbca9cf604e740e0d421794ac6cb - languageName: node - linkType: hard - -"@snyk/github-codeowners@npm:1.1.0": - version: 1.1.0 - resolution: "@snyk/github-codeowners@npm:1.1.0" - dependencies: - commander: "npm:^4.1.1" - ignore: "npm:^5.1.8" - p-map: "npm:^4.0.0" - bin: - github-codeowners: dist/cli.js - checksum: 10c0/92d860a904a1e67f8563d4ac4d540cc613f71193f7968933b4a4b1526e80a97f536f52d27762c158e3e39d48c2f3db4906ec78846309351c741abb1a28653af9 + checksum: 10c0/b0569ba6b1864c477d678f12f79d360087588f238d851e66662ff4dedf957d0470dc403ea5d4b3382224f60e3d21075181fd998bb1a33e5476501ca27593a5f5 languageName: node linkType: hard @@ -4513,8 +4933,8 @@ __metadata: linkType: hard "@testing-library/react@npm:^16.0.0": - version: 16.2.0 - resolution: "@testing-library/react@npm:16.2.0" + version: 16.3.0 + resolution: "@testing-library/react@npm:16.3.0" dependencies: "@babel/runtime": "npm:^7.12.5" peerDependencies: @@ -4528,7 +4948,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 10c0/7adaedaf237002b42e04a6261d2756074a19cbca0f0c79ba375660f618e123c0ee56256ced00aeb0bb7225ba1a8a81b92b692cca053521a21bb92a8cace1e4c6 + checksum: 10c0/3a2cb1f87c9a67e1ebbbcfd99b94b01e496fc35147be8bc5d8bf07a699c7d523a09d57ef2f7b1d91afccd1a28e21eda3b00d80187fbb51b1de01e422592d845e languageName: node linkType: hard @@ -4541,6 +4961,15 @@ __metadata: languageName: node linkType: hard +"@tybys/wasm-util@npm:^0.9.0": + version: 0.9.0 + resolution: "@tybys/wasm-util@npm:0.9.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/f9fde5c554455019f33af6c8215f1a1435028803dc2a2825b077d812bed4209a1a64444a4ca0ce2ea7e1175c8d88e2f9173a36a33c199e8a5c671aa31de8242d + languageName: node + linkType: hard + "@types/aria-query@npm:^5.0.1": version: 5.0.4 resolution: "@types/aria-query@npm:5.0.4" @@ -4596,14 +5025,30 @@ __metadata: languageName: node linkType: hard -"@types/cookie@npm:^0.6.0": - version: 0.6.0 - resolution: "@types/cookie@npm:0.6.0" - checksum: 10c0/5b326bd0188120fb32c0be086b141b1481fec9941b76ad537f9110e10d61ee2636beac145463319c71e4be67a17e85b81ca9e13ceb6e3bb63b93d16824d6c149 +"@types/dom-mediacapture-transform@npm:^0.1.11": + version: 0.1.11 + resolution: "@types/dom-mediacapture-transform@npm:0.1.11" + dependencies: + "@types/dom-webcodecs": "npm:*" + checksum: 10c0/19c76d54cf31aa2a925011fc5f973dff9a10bdecfdf2285e5e568e61850a0fa2b8c9f1807a1462cbefd57ec26d32eeaa9c359117aca9d9fe7f0d6f2fff33f51e languageName: node linkType: hard -"@types/estree@npm:1.0.6, @types/estree@npm:^1.0.0": +"@types/dom-webcodecs@npm:*": + version: 0.1.15 + resolution: "@types/dom-webcodecs@npm:0.1.15" + checksum: 10c0/1407f0352156c99c9b4378fb4c0c799b061520d031903a7f359ad09a6f706cc1fd56bafb272bb1a3decffcb32e54a51d2f07442eb72622464a950cff7f9e8862 + languageName: node + linkType: hard + +"@types/estree@npm:1.0.7": + version: 1.0.7 + resolution: "@types/estree@npm:1.0.7" + checksum: 10c0/be815254316882f7c40847336cd484c3bc1c3e34f710d197160d455dc9d6d050ffbf4c3bc76585dba86f737f020ab20bdb137ebe0e9116b0c86c7c0342221b8c + languageName: node + linkType: hard + +"@types/estree@npm:^1.0.0": version: 1.0.6 resolution: "@types/estree@npm:1.0.6" checksum: 10c0/cdfd751f6f9065442cd40957c07fd80361c962869aa853c1c2fd03e101af8b9389d8ff4955a43a6fcfa223dd387a089937f95be0f3eec21ca527039fd2d9859a @@ -4672,21 +5117,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*": - version: 22.8.4 - resolution: "@types/node@npm:22.8.4" +"@types/node@npm:*, @types/node@npm:>=13.7.0, @types/node@npm:^22.0.0": + version: 22.15.23 + resolution: "@types/node@npm:22.15.23" dependencies: - undici-types: "npm:~6.19.8" - checksum: 10c0/f88d030480630194a9168772462ec09b2d86454f34368c46d2b7fda5dc6e14594b1576fcc5c35cc53b57a4d1e8dd2865a85ae81f34ded0d1af753a0f5d294c25 - languageName: node - linkType: hard - -"@types/node@npm:>=13.7.0, @types/node@npm:^22.0.0": - version: 22.13.8 - resolution: "@types/node@npm:22.13.8" - dependencies: - undici-types: "npm:~6.20.0" - checksum: 10c0/bfc92b734a9dce6ac5daee0a52feccdf5dcb3804d895e4bc5384e2f4644612b8801725cd03c8c3c0888fb5eeb16b875877ac44b77641e0196dc1a837b1c2a366 + undici-types: "npm:~6.21.0" + checksum: 10c0/e3ae0629dfb4357dad2a7838c481656abf089d852d83f0d0f14368f03ad21ce276cbecfdf62be2276ef39920db6b114e5bc8d87c37714bbab9aefb0ce1eb1473 languageName: node linkType: hard @@ -4721,21 +5157,21 @@ __metadata: linkType: hard "@types/react-dom@npm:^18.3.0": - version: 18.3.5 - resolution: "@types/react-dom@npm:18.3.5" + version: 18.3.7 + resolution: "@types/react-dom@npm:18.3.7" peerDependencies: "@types/react": ^18.0.0 - checksum: 10c0/b163d35a6b32a79f5782574a7aeb12a31a647e248792bf437e6d596e2676961c394c5e3c6e91d1ce44ae90441dbaf93158efb4f051c0d61e2612f1cb04ce4faa + checksum: 10c0/8bd309e2c3d1604a28a736a24f96cbadf6c05d5288cfef8883b74f4054c961b6b3a5e997fd5686e492be903c8f3380dba5ec017eff3906b1256529cd2d39603e languageName: node linkType: hard "@types/react@npm:^18.3.0": - version: 18.3.18 - resolution: "@types/react@npm:18.3.18" + version: 18.3.23 + resolution: "@types/react@npm:18.3.23" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10c0/8fb2b00672072135d0858dc9db07873ea107cc238b6228aaa2a9afd1ef7a64a7074078250db38afbeb19064be8ea6af5eac32d404efdd5f45e093cc4829d87f8 + checksum: 10c0/49331800b76572eb2992a5c44801dbf8c612a5f99c8f4e4200f06c7de6f3a6e9455c661784a6c5469df96fa45622cb4a9d0982c44e6a0d5719be5f2ef1f545ed languageName: node linkType: hard @@ -4797,24 +5233,24 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^8.0.0": - version: 8.25.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.25.0" +"@typescript-eslint/eslint-plugin@npm:^8.31.0": + version: 8.33.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.33.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.25.0" - "@typescript-eslint/type-utils": "npm:8.25.0" - "@typescript-eslint/utils": "npm:8.25.0" - "@typescript-eslint/visitor-keys": "npm:8.25.0" + "@typescript-eslint/scope-manager": "npm:8.33.0" + "@typescript-eslint/type-utils": "npm:8.33.0" + "@typescript-eslint/utils": "npm:8.33.0" + "@typescript-eslint/visitor-keys": "npm:8.33.0" graphemer: "npm:^1.4.0" - ignore: "npm:^5.3.1" + ignore: "npm:^7.0.0" natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^2.0.1" + ts-api-utils: "npm:^2.1.0" peerDependencies: - "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + "@typescript-eslint/parser": ^8.33.0 eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/11d63850f5f03b29cd31166f8da111788dc74e46877c2e16a5c488d6c4aa4b6c68c0857b9a396ad920aa7f0f3e7166f4faecbb194c19cd2bb9d3f687c5d2b292 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/fdfbba2134bb8aa8effb3686a9ffe0a5d9916b41ccdf4339976e0205734f802fca2631939f892ccedd20eee104d8cd0e691720728baeeee17c0f40d7bfe4205d languageName: node linkType: hard @@ -4829,19 +5265,30 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^8.0.0": - version: 8.25.0 - resolution: "@typescript-eslint/parser@npm:8.25.0" +"@typescript-eslint/parser@npm:^8.31.0": + version: 8.33.0 + resolution: "@typescript-eslint/parser@npm:8.33.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.25.0" - "@typescript-eslint/types": "npm:8.25.0" - "@typescript-eslint/typescript-estree": "npm:8.25.0" - "@typescript-eslint/visitor-keys": "npm:8.25.0" + "@typescript-eslint/scope-manager": "npm:8.33.0" + "@typescript-eslint/types": "npm:8.33.0" + "@typescript-eslint/typescript-estree": "npm:8.33.0" + "@typescript-eslint/visitor-keys": "npm:8.33.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/9a54539ba297791f23093ff42a885cc57d36b26205d7a390e114d1f01cc584ce91ac6ead01819daa46b48f873cac6c829fcf399a436610bdbfa98e5cd78148a2 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/3f6aa8476d912a749a4f3e6ae6cbf90a881f1892efb7b3c88f6654fa03e770d8da511d0298615b0eda880b3811e157ed60e47e6a21aa309cbf912e2d5d79d73c + languageName: node + linkType: hard + +"@typescript-eslint/project-service@npm:8.33.0": + version: 8.33.0 + resolution: "@typescript-eslint/project-service@npm:8.33.0" + dependencies: + "@typescript-eslint/tsconfig-utils": "npm:^8.33.0" + "@typescript-eslint/types": "npm:^8.33.0" + debug: "npm:^4.3.4" + checksum: 10c0/a863d9e3be5ffb53c9d57b25b7a35149dae01afd942dd7fc36bd72a4230676ae12d0f37a789cddaf1baf71e3b35f09436bebbd081336e667b4181b48d0afe8f5 languageName: node linkType: hard @@ -4865,18 +5312,37 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.25.0": - version: 8.25.0 - resolution: "@typescript-eslint/type-utils@npm:8.25.0" +"@typescript-eslint/scope-manager@npm:8.33.0": + version: 8.33.0 + resolution: "@typescript-eslint/scope-manager@npm:8.33.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:8.25.0" - "@typescript-eslint/utils": "npm:8.25.0" + "@typescript-eslint/types": "npm:8.33.0" + "@typescript-eslint/visitor-keys": "npm:8.33.0" + checksum: 10c0/eb259add242ce40642e7272b414c92ae9407d97cb304981f17f0de0846d5c4ab47d41816ef13da3d3976fe0b7a74df291525be27e4fe4f0ab5d35e86d340faa0 + languageName: node + linkType: hard + +"@typescript-eslint/tsconfig-utils@npm:8.33.0, @typescript-eslint/tsconfig-utils@npm:^8.33.0": + version: 8.33.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.33.0" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/6e9a8e73e65b925f908f31e00be4f1b8d7e89f45d97fa703f468115943c297fc2cc6f9daa0c12b9607f39186f033ac244515f11710df7e1df8302c815ed57389 + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:8.33.0": + version: 8.33.0 + resolution: "@typescript-eslint/type-utils@npm:8.33.0" + dependencies: + "@typescript-eslint/typescript-estree": "npm:8.33.0" + "@typescript-eslint/utils": "npm:8.33.0" debug: "npm:^4.3.4" - ts-api-utils: "npm:^2.0.1" + ts-api-utils: "npm:^2.1.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/b7477a2d239cfd337f7d28641666763cf680a43a8d377a09dc42415f715670d35fbb4e772e103dfe8cd620c377e66bce740106bb3983ee65a739c28fab7325d1 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/4a81c654ba17e8a50e48249f781cb91cddb990044affda7315d9b259aabd638232c9a98ff5f4d45ea3b258098060864026b746fce93ad6b4dcde5e492d93c855 languageName: node linkType: hard @@ -4894,6 +5360,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:8.33.0, @typescript-eslint/types@npm:^8.33.0": + version: 8.33.0 + resolution: "@typescript-eslint/types@npm:8.33.0" + checksum: 10c0/348b64eb408719d7711a433fc9716e0c2aab8b3f3676f5a1cc2e00269044132282cf655deb6d0dd9817544116909513de3b709005352d186949d1014fad1a3cb + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" @@ -4930,6 +5403,26 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:8.33.0": + version: 8.33.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.33.0" + dependencies: + "@typescript-eslint/project-service": "npm:8.33.0" + "@typescript-eslint/tsconfig-utils": "npm:8.33.0" + "@typescript-eslint/types": "npm:8.33.0" + "@typescript-eslint/visitor-keys": "npm:8.33.0" + debug: "npm:^4.3.4" + fast-glob: "npm:^3.3.2" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/677b12b2e5780ffaef508bddbf8712fe2c3413f3d14fd8fd0cfbe22952a81c6642b3cc26984cf27fdfc3dd2457ae5f8aa04437d3b0ae32987a1895f9648ca7b2 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/utils@npm:5.62.0" @@ -4948,7 +5441,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.25.0, @typescript-eslint/utils@npm:^8.13.0": +"@typescript-eslint/utils@npm:8.33.0": + version: 8.33.0 + resolution: "@typescript-eslint/utils@npm:8.33.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.7.0" + "@typescript-eslint/scope-manager": "npm:8.33.0" + "@typescript-eslint/types": "npm:8.33.0" + "@typescript-eslint/typescript-estree": "npm:8.33.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/a0adb9e13d8f8d8f86ae2e905f3305ad60732e760364b291de66a857a551485d37c23e923299078a47f75d3cca643e1f2aefa010a0beb4cb0d08d0507c1038e1 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:^8.13.0": version: 8.25.0 resolution: "@typescript-eslint/utils@npm:8.25.0" dependencies: @@ -4983,6 +5491,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:8.33.0": + version: 8.33.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.33.0" + dependencies: + "@typescript-eslint/types": "npm:8.33.0" + eslint-visitor-keys: "npm:^4.2.0" + checksum: 10c0/41660f241e78314f69d251792f369ef1eeeab3b40fe4ab11b794d402c95bcb82b61d3e91763e7ab9b0f22011a7ac9c8f9dfd91734d61c9f4eaf4f7660555b53b + languageName: node + linkType: hard + "@ungap/structured-clone@npm:^1.2.0": version: 1.2.0 resolution: "@ungap/structured-clone@npm:1.2.0" @@ -5049,33 +5567,25 @@ __metadata: languageName: node linkType: hard -"@vitejs/plugin-basic-ssl@npm:^1.0.1": - version: 1.2.0 - resolution: "@vitejs/plugin-basic-ssl@npm:1.2.0" - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - checksum: 10c0/0d360fcca01f91ade6e451edbea09a107ff9e95cd3c3766c7a069d1a168709df92d96c0bd1eccc66e2739a153e07c75a45321ec487450c0da942606200d8441d - languageName: node - linkType: hard - "@vitejs/plugin-react@npm:^4.0.1": - version: 4.3.4 - resolution: "@vitejs/plugin-react@npm:4.3.4" + version: 4.5.0 + resolution: "@vitejs/plugin-react@npm:4.5.0" dependencies: - "@babel/core": "npm:^7.26.0" + "@babel/core": "npm:^7.26.10" "@babel/plugin-transform-react-jsx-self": "npm:^7.25.9" "@babel/plugin-transform-react-jsx-source": "npm:^7.25.9" + "@rolldown/pluginutils": "npm:1.0.0-beta.9" "@types/babel__core": "npm:^7.20.5" - react-refresh: "npm:^0.14.2" + react-refresh: "npm:^0.17.0" peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 - checksum: 10c0/38a47a1dbafae0b97142943d83ee3674cb3331153a60b1a3fd29d230c12c9dfe63b7c345b231a3450168ed8a9375a9a1a253c3d85e9efdc19478c0d56b98496c + checksum: 10c0/c9f75cde098b9aac62cb512103d7f898a0a173cb78dc9fcf79ca4b3f21a1458cd1955a4383c8c9e3841ce23c5e7f02ed1455e445c9574879b143d40734121fd8 languageName: node linkType: hard "@vitest/coverage-v8@npm:^3.0.0": - version: 3.0.7 - resolution: "@vitest/coverage-v8@npm:3.0.7" + version: 3.1.4 + resolution: "@vitest/coverage-v8@npm:3.1.4" dependencies: "@ampproject/remapping": "npm:^2.3.0" "@bcoe/v8-coverage": "npm:^1.0.2" @@ -5086,36 +5596,36 @@ __metadata: istanbul-reports: "npm:^3.1.7" magic-string: "npm:^0.30.17" magicast: "npm:^0.3.5" - std-env: "npm:^3.8.0" + std-env: "npm:^3.9.0" test-exclude: "npm:^7.0.1" tinyrainbow: "npm:^2.0.0" peerDependencies: - "@vitest/browser": 3.0.7 - vitest: 3.0.7 + "@vitest/browser": 3.1.4 + vitest: 3.1.4 peerDependenciesMeta: "@vitest/browser": optional: true - checksum: 10c0/37cce7091d8b75b5db515a6152f0f168506d3252789343630135f8341e5486293afb1ab2bdae882d84fe20879b078c14fd610c485baff16b3ab5cd87aa0303c0 + checksum: 10c0/e2073c06254772bfcaf00e40b76599aa9a3d66fc84c3d980941c4d216b4cf3db8b6f7f0ebcd4905c4ca08e8d19b505d9c428363e51a80a2d653a4a510b280e41 languageName: node linkType: hard -"@vitest/expect@npm:3.0.7": - version: 3.0.7 - resolution: "@vitest/expect@npm:3.0.7" +"@vitest/expect@npm:3.1.4": + version: 3.1.4 + resolution: "@vitest/expect@npm:3.1.4" dependencies: - "@vitest/spy": "npm:3.0.7" - "@vitest/utils": "npm:3.0.7" + "@vitest/spy": "npm:3.1.4" + "@vitest/utils": "npm:3.1.4" chai: "npm:^5.2.0" tinyrainbow: "npm:^2.0.0" - checksum: 10c0/70ec7ff758640e12a5335b7455d69a9589a4b5d3a4ce6fc421aa4548a38c5947b1e36ca8d89fcbe979c955dbb9b0941b8c487c466606a9db2ab75b163796daad + checksum: 10c0/9cfd7eb6d965a179b4ec0610a9c08b14dc97dbaf81925c8209a054f7a2a3d1eef59fa5e5cd4dd9bf8cb940d85aee5f5102555511a94be9933faf4cc734462a16 languageName: node linkType: hard -"@vitest/mocker@npm:3.0.7": - version: 3.0.7 - resolution: "@vitest/mocker@npm:3.0.7" +"@vitest/mocker@npm:3.1.4": + version: 3.1.4 + resolution: "@vitest/mocker@npm:3.1.4" dependencies: - "@vitest/spy": "npm:3.0.7" + "@vitest/spy": "npm:3.1.4" estree-walker: "npm:^3.0.3" magic-string: "npm:^0.30.17" peerDependencies: @@ -5126,16 +5636,16 @@ __metadata: optional: true vite: optional: true - checksum: 10c0/c6809c57a5df1870b53f8edcae921a4953a34edf6032b439ff66dd0a4b80af4350f5690e7ff1fe3774ed86c639431005cd97cb2b9099ef24b6cd3c7388105d67 + checksum: 10c0/d0b89e3974830d3893e7b8324a77ffeb9436db0969b57c01e2508ebd5b374c9d01f73796c8df8f555a3b1e1b502d40e725f159cd85966eebd3145b2f52e605e2 languageName: node linkType: hard -"@vitest/pretty-format@npm:3.0.7, @vitest/pretty-format@npm:^3.0.7": - version: 3.0.7 - resolution: "@vitest/pretty-format@npm:3.0.7" +"@vitest/pretty-format@npm:3.1.4, @vitest/pretty-format@npm:^3.1.4": + version: 3.1.4 + resolution: "@vitest/pretty-format@npm:3.1.4" dependencies: tinyrainbow: "npm:^2.0.0" - checksum: 10c0/c67fc7025f4e1bd431aaa5ff3d79430be6ea4f10b360756c711416659105ec14633249f7605fe10f5fbb47dbb1579bd6e77da218fc3f28cfdaacac7c8fadbc6e + checksum: 10c0/11e133640435822b8b8528be540b3d66c1de27ebc2dcf1de87608b7f01a44d15302c4d4bf8330fa848a435450d88a09d7e9442747a5739ae5f500ccdd1493159 languageName: node linkType: hard @@ -5148,44 +5658,44 @@ __metadata: languageName: node linkType: hard -"@vitest/runner@npm:3.0.7": - version: 3.0.7 - resolution: "@vitest/runner@npm:3.0.7" +"@vitest/runner@npm:3.1.4": + version: 3.1.4 + resolution: "@vitest/runner@npm:3.1.4" dependencies: - "@vitest/utils": "npm:3.0.7" + "@vitest/utils": "npm:3.1.4" pathe: "npm:^2.0.3" - checksum: 10c0/68cd7c0291ae7a20c4a5c1dbdf94ef49be7f471fe33d96d6f155ab50d257e01d9fda231a4dd008e8b4909870680e68a0606624fbf03ffa4958fd929ba18a0cd7 + checksum: 10c0/efb7512eebd3d786baa617eab332ec9ca6ce62eb1c9dd3945019f7510d745b3cd0fc2978868d792050905aacbf158eefc132359c83e61f0398b46be566013ee6 languageName: node linkType: hard -"@vitest/snapshot@npm:3.0.7": - version: 3.0.7 - resolution: "@vitest/snapshot@npm:3.0.7" +"@vitest/snapshot@npm:3.1.4": + version: 3.1.4 + resolution: "@vitest/snapshot@npm:3.1.4" dependencies: - "@vitest/pretty-format": "npm:3.0.7" + "@vitest/pretty-format": "npm:3.1.4" magic-string: "npm:^0.30.17" pathe: "npm:^2.0.3" - checksum: 10c0/012f3d2f921094f7580909717f3802872ad48bf735f5076b583031413c84afb9b65be00c392c8dfb5cb506eb5038a11ac62682e43ed84625a815fe420bedf775 + checksum: 10c0/ce9d51e1b03e4f91ffad160c570991a8a3c603cb7dc2a9020e58c012e62dccbe2c6ee45e1a1d8489e265b4485c6721eb73b5e91404d1c76da08dcd663f4e18d1 languageName: node linkType: hard -"@vitest/spy@npm:3.0.7": - version: 3.0.7 - resolution: "@vitest/spy@npm:3.0.7" +"@vitest/spy@npm:3.1.4": + version: 3.1.4 + resolution: "@vitest/spy@npm:3.1.4" dependencies: tinyspy: "npm:^3.0.2" - checksum: 10c0/eb361a64e7819b2ebc45d6a8f31bed5a65272dfadc27ab8ce7df869817ce26a11f35bab9136690c91630107961423c7187cf4097b77d7422f9b97b96e96ca1d7 + checksum: 10c0/747914ac18efa82d75349b0fb0ad8a5e2af6e04f5bbb50a980c9270dd8958f9ddf84cee0849a54e1645af088fc1f709add94a35e99cb14aca2cdb322622ba501 languageName: node linkType: hard -"@vitest/utils@npm:3.0.7": - version: 3.0.7 - resolution: "@vitest/utils@npm:3.0.7" +"@vitest/utils@npm:3.1.4": + version: 3.1.4 + resolution: "@vitest/utils@npm:3.1.4" dependencies: - "@vitest/pretty-format": "npm:3.0.7" + "@vitest/pretty-format": "npm:3.1.4" loupe: "npm:^3.1.3" tinyrainbow: "npm:^2.0.0" - checksum: 10c0/4023a4ebfa675dc3d9298764e1c62395e9fb1b5518d7f0f9d79bf25d98627166db620f8b5cb9bc5acbac2b74b1c635cce91d8ec99f065188a92611e5f7631220 + checksum: 10c0/78f1691a2dd578862b236f4962815e7475e547f006e7303a149dc5f910cc1ce6e0bdcbd7b4fd618122d62ca2dcc28bae464d31543f3898f5d88fa35017e00a95 languageName: node linkType: hard @@ -5248,16 +5758,6 @@ __metadata: languageName: node linkType: hard -"aggregate-error@npm:^3.0.0": - version: 3.1.0 - resolution: "aggregate-error@npm:3.1.0" - dependencies: - clean-stack: "npm:^2.0.0" - indent-string: "npm:^4.0.0" - checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 - languageName: node - linkType: hard - "ajv@npm:^6.12.4": version: 6.12.6 resolution: "ajv@npm:6.12.6" @@ -5521,28 +6021,21 @@ __metadata: languageName: node linkType: hard -"asynckit@npm:^0.4.0": - version: 0.4.0 - resolution: "asynckit@npm:0.4.0" - checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d - languageName: node - linkType: hard - -"autoprefixer@npm:^10.4.19": - version: 10.4.20 - resolution: "autoprefixer@npm:10.4.20" +"autoprefixer@npm:^10.4.21": + version: 10.4.21 + resolution: "autoprefixer@npm:10.4.21" dependencies: - browserslist: "npm:^4.23.3" - caniuse-lite: "npm:^1.0.30001646" + browserslist: "npm:^4.24.4" + caniuse-lite: "npm:^1.0.30001702" fraction.js: "npm:^4.3.7" normalize-range: "npm:^0.1.2" - picocolors: "npm:^1.0.1" + picocolors: "npm:^1.1.1" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.1.0 bin: autoprefixer: bin/autoprefixer - checksum: 10c0/e1f00978a26e7c5b54ab12036d8c13833fad7222828fc90914771b1263f51b28c7ddb5803049de4e77696cbd02bb25cfc3634e80533025bb26c26aacdf938940 + checksum: 10c0/de5b71d26d0baff4bbfb3d59f7cf7114a6030c9eeb66167acf49a32c5b61c68e308f1e0f869d92334436a221035d08b51cd1b2f2c4689b8d955149423c16d4d4 languageName: node linkType: hard @@ -5761,7 +6254,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.23.3, browserslist@npm:^4.24.0, browserslist@npm:^4.24.3, browserslist@npm:^4.24.4": +"browserslist@npm:^4.24.0, browserslist@npm:^4.24.3, browserslist@npm:^4.24.4": version: 4.24.4 resolution: "browserslist@npm:4.24.4" dependencies: @@ -5775,6 +6268,20 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.24.5": + version: 4.24.5 + resolution: "browserslist@npm:4.24.5" + dependencies: + caniuse-lite: "npm:^1.0.30001716" + electron-to-chromium: "npm:^1.5.149" + node-releases: "npm:^2.0.19" + update-browserslist-db: "npm:^1.1.3" + bin: + browserslist: cli.js + checksum: 10c0/f4c1ce1a7d8fdfab5e5b88bb6e93d09e8a883c393f86801537a252da0362dbdcde4dbd97b318246c5d84c6607b2f6b47af732c1b000d6a8a881ee024bad29204 + languageName: node + linkType: hard + "bs58@npm:^6.0.0": version: 6.0.0 resolution: "bs58@npm:6.0.0" @@ -5852,6 +6359,16 @@ __metadata: languageName: node linkType: hard +"call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + checksum: 10c0/47bd9901d57b857590431243fea704ff18078b16890a6b3e021e12d279bbf211d039155e27d7566b374d49ee1f8189344bac9833dec7a20cdec370506361c938 + languageName: node + linkType: hard + "call-bind@npm:^1.0.2, call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": version: 1.0.8 resolution: "call-bind@npm:1.0.8" @@ -5874,6 +6391,16 @@ __metadata: languageName: node linkType: hard +"call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + get-intrinsic: "npm:^1.3.0" + checksum: 10c0/f4796a6a0941e71c766aea672f63b72bc61234c4f4964dc6d7606e3664c307e7d77845328a8f3359ce39ddb377fed67318f9ee203dea1d47e46165dcf2917644 + languageName: node + linkType: hard + "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -5905,13 +6432,20 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001646, caniuse-lite@npm:^1.0.30001688": +"caniuse-lite@npm:^1.0.30001688": version: 1.0.30001701 resolution: "caniuse-lite@npm:1.0.30001701" checksum: 10c0/a814bd4dd8b49645ca51bc6ee42120660a36394bb54eb6084801d3f2bbb9471e5e1a9a8a25f44f83086a032d46e66b33031e2aa345f699b90a7e84a9836b819c languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001716": + version: 1.0.30001718 + resolution: "caniuse-lite@npm:1.0.30001718" + checksum: 10c0/67f9ad09bc16443e28d14f265d6e468480cd8dc1900d0d8b982222de80c699c4f2306599c3da8a3fa7139f110d4b30d49dbac78f215470f479abb6ffe141d5d3 + languageName: node + linkType: hard + "caseless@npm:~0.12.0": version: 0.12.0 resolution: "caseless@npm:0.12.0" @@ -6077,13 +6611,6 @@ __metadata: languageName: node linkType: hard -"clean-stack@npm:^2.0.0": - version: 2.2.0 - resolution: "clean-stack@npm:2.2.0" - checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 - languageName: node - linkType: hard - "cliui@npm:^6.0.0": version: 6.0.0 resolution: "cliui@npm:6.0.0" @@ -6113,13 +6640,6 @@ __metadata: languageName: node linkType: hard -"clone@npm:^1.0.2": - version: 1.0.4 - resolution: "clone@npm:1.0.4" - checksum: 10c0/2176952b3649293473999a95d7bebfc9dc96410f6cbd3d2595cf12fd401f63a4bf41a7adbfd3ab2ff09ed60cb9870c58c6acdd18b87767366fabfc163700f13b - languageName: node - linkType: hard - "clone@npm:^2.1.2": version: 2.1.2 resolution: "clone@npm:2.1.2" @@ -6180,15 +6700,6 @@ __metadata: languageName: node linkType: hard -"combined-stream@npm:^1.0.8": - version: 1.0.8 - resolution: "combined-stream@npm:1.0.8" - dependencies: - delayed-stream: "npm:~1.0.0" - checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5 - languageName: node - linkType: hard - "commander@npm:^12.1.0": version: 12.1.0 resolution: "commander@npm:12.1.0" @@ -6203,13 +6714,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^4.1.1": - version: 4.1.1 - resolution: "commander@npm:4.1.1" - checksum: 10c0/84a76c08fe6cc08c9c93f62ac573d2907d8e79138999312c92d4155bc2325d487d64d13f669b2000c9f8caf70493c1be2dac74fec3c51d5a04f8bc3ae1830bab - languageName: node - linkType: hard - "commander@npm:^8.3.0": version: 8.3.0 resolution: "commander@npm:8.3.0" @@ -6412,10 +6916,10 @@ __metadata: languageName: node linkType: hard -"cssdb@npm:^8.2.3": - version: 8.2.3 - resolution: "cssdb@npm:8.2.3" - checksum: 10c0/17c3ca6432ed02431db6b44bed74649ccef7d7b7b900ccbc7297525f030722c441dd67c71f28aef3cfa0814ba7b254a24adfb0dcd5728937da179ff437cdcd0c +"cssdb@npm:^8.3.0": + version: 8.3.0 + resolution: "cssdb@npm:8.3.0" + checksum: 10c0/56d13cbddd90e63f45f24f71f35314f9718b72760acdf15367e33014eb45df775ae97ec05c08afaa6b4b147c757e9554c1bf39ddcdaeeb26b6c2adfeee503ae7 languageName: node linkType: hard @@ -6551,13 +7055,6 @@ __metadata: languageName: node linkType: hard -"decimal.js@npm:10": - version: 10.5.0 - resolution: "decimal.js@npm:10.5.0" - checksum: 10c0/785c35279df32762143914668df35948920b6c1c259b933e0519a69b7003fc0a5ed2a766b1e1dda02574450c566b21738a45f15e274b47c2ac02072c0d1f3ac3 - languageName: node - linkType: hard - "decimal.js@npm:^10.4.3": version: 10.4.3 resolution: "decimal.js@npm:10.4.3" @@ -6565,6 +7062,13 @@ __metadata: languageName: node linkType: hard +"decimal.js@npm:^10.5.0": + version: 10.5.0 + resolution: "decimal.js@npm:10.5.0" + checksum: 10c0/785c35279df32762143914668df35948920b6c1c259b933e0519a69b7003fc0a5ed2a766b1e1dda02574450c566b21738a45f15e274b47c2ac02072c0d1f3ac3 + languageName: node + linkType: hard + "deep-eql@npm:^5.0.1": version: 5.0.2 resolution: "deep-eql@npm:5.0.2" @@ -6579,15 +7083,6 @@ __metadata: languageName: node linkType: hard -"defaults@npm:^1.0.3": - version: 1.0.4 - resolution: "defaults@npm:1.0.4" - dependencies: - clone: "npm:^1.0.2" - checksum: 10c0/9cfbe498f5c8ed733775db62dfd585780387d93c17477949e1670bfcfb9346e0281ce8c4bf9f4ac1fc0f9b851113bd6dc9e41182ea1644ccd97de639fa13c35a - languageName: node - linkType: hard - "define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": version: 1.1.4 resolution: "define-data-property@npm:1.1.4" @@ -6610,13 +7105,6 @@ __metadata: languageName: node linkType: hard -"delayed-stream@npm:~1.0.0": - version: 1.0.0 - resolution: "delayed-stream@npm:1.0.0" - checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19 - languageName: node - linkType: hard - "deprecation@npm:^2.0.0": version: 2.3.1 resolution: "deprecation@npm:2.3.1" @@ -6806,19 +7294,6 @@ __metadata: languageName: node linkType: hard -"easy-table@npm:1.2.0": - version: 1.2.0 - resolution: "easy-table@npm:1.2.0" - dependencies: - ansi-regex: "npm:^5.0.1" - wcwidth: "npm:^1.0.1" - dependenciesMeta: - wcwidth: - optional: true - checksum: 10c0/2d37937cd608586ba02e1ec479f90ccec581d366b3b0d1bb26b99ee6005f8d724e32a07a873759893461ca45b99e2d08c30326529d967ce9eedc1e9b68d4aa63 - languageName: node - linkType: hard - "ejs@npm:^3.1.6, ejs@npm:^3.1.9": version: 3.1.10 resolution: "ejs@npm:3.1.10" @@ -6830,6 +7305,13 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.5.149": + version: 1.5.159 + resolution: "electron-to-chromium@npm:1.5.159" + checksum: 10c0/dc5b60a235ad04b1637b3b2af4914ac900c42813b02262a91a41d950223316f7b12de715697cf9c2d9f572f716f9422bf259ee65d86599cd2cc66e92c499ebd1 + languageName: node + linkType: hard + "electron-to-chromium@npm:^1.5.73": version: 1.5.109 resolution: "electron-to-chromium@npm:1.5.109" @@ -6852,15 +7334,17 @@ __metadata: "@formatjs/intl-segmenter": "npm:^11.7.3" "@livekit/components-core": "npm:^0.12.0" "@livekit/components-react": "npm:^2.0.0" - "@livekit/protocol": "npm:^1.33.0" + "@livekit/protocol": "npm:^1.38.0" + "@livekit/track-processors": "npm:^0.5.5" + "@mediapipe/tasks-vision": "npm:^0.10.18" "@opentelemetry/api": "npm:^1.4.0" - "@opentelemetry/core": "npm:^1.25.1" - "@opentelemetry/exporter-trace-otlp-http": "npm:^0.57.0" - "@opentelemetry/resources": "npm:^1.25.1" - "@opentelemetry/sdk-trace-base": "npm:^1.25.1" - "@opentelemetry/sdk-trace-web": "npm:^1.9.1" + "@opentelemetry/core": "npm:^2.0.0" + "@opentelemetry/exporter-trace-otlp-http": "npm:^0.201.0" + "@opentelemetry/resources": "npm:^2.0.0" + "@opentelemetry/sdk-trace-base": "npm:^2.0.0" + "@opentelemetry/sdk-trace-web": "npm:^2.0.0" "@opentelemetry/semantic-conventions": "npm:^1.25.1" - "@playwright/test": "npm:^1.51.0" + "@playwright/test": "npm:^1.52.0" "@radix-ui/react-dialog": "npm:^1.0.4" "@radix-ui/react-slider": "npm:^1.1.2" "@radix-ui/react-visually-hidden": "npm:^1.0.3" @@ -6873,6 +7357,7 @@ __metadata: "@testing-library/react": "npm:^16.0.0" "@testing-library/user-event": "npm:^14.5.1" "@types/content-type": "npm:^1.1.5" + "@types/dom-mediacapture-transform": "npm:^0.1.11" "@types/grecaptcha": "npm:^3.0.9" "@types/jsdom": "npm:^21.1.7" "@types/lodash-es": "npm:^4.17.12" @@ -6883,12 +7368,11 @@ __metadata: "@types/react-dom": "npm:^18.3.0" "@types/sdp-transform": "npm:^2.4.5" "@types/uuid": "npm:10" - "@typescript-eslint/eslint-plugin": "npm:^8.0.0" - "@typescript-eslint/parser": "npm:^8.0.0" + "@typescript-eslint/eslint-plugin": "npm:^8.31.0" + "@typescript-eslint/parser": "npm:^8.31.0" "@use-gesture/react": "npm:^10.2.11" "@vector-im/compound-design-tokens": "npm:^3.0.0" "@vector-im/compound-web": "npm:^7.2.0" - "@vitejs/plugin-basic-ssl": "npm:^1.0.1" "@vitejs/plugin-react": "npm:^4.0.1" "@vitest/coverage-v8": "npm:^3.0.0" babel-plugin-transform-vite-meta-env: "npm:^1.0.3" @@ -6899,7 +7383,7 @@ __metadata: eslint-plugin-deprecate: "npm:^0.8.2" eslint-plugin-import: "npm:^2.26.0" eslint-plugin-jsx-a11y: "npm:^6.5.1" - eslint-plugin-matrix-org: "npm:^2.0.0" + eslint-plugin-matrix-org: "npm:2.1.0" eslint-plugin-react: "npm:^7.29.4" eslint-plugin-react-hooks: "npm:^5.0.0" eslint-plugin-rxjs: "npm:^5.0.3" @@ -6910,11 +7394,11 @@ __metadata: i18next-parser: "npm:^9.1.0" jsdom: "npm:^26.0.0" knip: "npm:^5.27.2" - livekit-client: "npm:2.11.2" + livekit-client: "npm:^2.13.0" lodash-es: "npm:^4.17.21" loglevel: "npm:^1.9.1" - matrix-js-sdk: "github:matrix-org/matrix-js-sdk#64e27f5d3cdab6aafeb7c22f1264416ffa72b83f" - matrix-widget-api: "npm:1.11.0" + matrix-js-sdk: "github:matrix-org/matrix-js-sdk#head=develop" + matrix-widget-api: "npm:^1.13.0" normalize.css: "npm:^8.0.1" observable-hooks: "npm:^4.2.3" pako: "npm:^2.0.4" @@ -6931,12 +7415,12 @@ __metadata: react-use-measure: "npm:^2.1.1" rxjs: "npm:^7.8.1" sass: "npm:^1.42.1" - typescript: "npm:^5.1.6" + typescript: "npm:^5.8.3" typescript-eslint-language-service: "npm:^5.0.5" unique-names-generator: "npm:^4.6.0" vaul: "npm:^1.0.0" vite: "npm:^6.0.0" - vite-plugin-generate-file: "npm:^0.2.0" + vite-plugin-generate-file: "npm:^0.3.0" vite-plugin-html: "npm:^3.2.2" vite-plugin-svgr: "npm:^4.0.0" vitest: "npm:^3.0.0" @@ -6977,16 +7461,6 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.18.0": - version: 5.18.1 - resolution: "enhanced-resolve@npm:5.18.1" - dependencies: - graceful-fs: "npm:^4.2.4" - tapable: "npm:^2.2.0" - checksum: 10c0/4cffd9b125225184e2abed9fdf0ed3dbd2224c873b165d0838fd066cde32e0918626cba2f1f4bf6860762f13a7e2364fd89a82b99566be2873d813573ac71846 - languageName: node - linkType: hard - "ensure-posix-path@npm:^1.1.0": version: 1.1.1 resolution: "ensure-posix-path@npm:1.1.1" @@ -7135,10 +7609,10 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^1.6.0": - version: 1.6.0 - resolution: "es-module-lexer@npm:1.6.0" - checksum: 10c0/667309454411c0b95c476025929881e71400d74a746ffa1ff4cb450bd87f8e33e8eef7854d68e401895039ac0bac64e7809acbebb6253e055dd49ea9e3ea9212 +"es-module-lexer@npm:^1.7.0": + version: 1.7.0 + resolution: "es-module-lexer@npm:1.7.0" + checksum: 10c0/4c935affcbfeba7fb4533e1da10fa8568043df1e3574b869385980de9e2d475ddc36769891936dbb07036edb3c3786a8b78ccf44964cd130dedc1f2c984b6c7b languageName: node linkType: hard @@ -7151,6 +7625,15 @@ __metadata: languageName: node linkType: hard +"es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 10c0/65364812ca4daf48eb76e2a3b7a89b3f6a2e62a1c420766ce9f692665a29d94fe41fe88b65f24106f449859549711e4b40d9fb8002d862dfd7eb1c512d10be0c + languageName: node + linkType: hard + "es-set-tostringtag@npm:^2.0.3, es-set-tostringtag@npm:^2.1.0": version: 2.1.0 resolution: "es-set-tostringtag@npm:2.1.0" @@ -7300,13 +7783,13 @@ __metadata: linkType: hard "eslint-config-prettier@npm:^10.0.0": - version: 10.0.2 - resolution: "eslint-config-prettier@npm:10.0.2" + version: 10.1.5 + resolution: "eslint-config-prettier@npm:10.1.5" peerDependencies: eslint: ">=7.0.0" bin: - eslint-config-prettier: build/bin/cli.js - checksum: 10c0/e0ef3c442661a26fc6e82acec5bb9a418c4a8f65ec8adf0983d3aaba7716d2ed448358b063cce6e3c272c847d14cb856ddf30031770c6571e2b2c3e2a439afd4 + eslint-config-prettier: bin/cli.js + checksum: 10c0/5486255428e4577e8064b40f27db299faf7312b8e43d7b4bc913a6426e6c0f5950cd519cad81ae24e9aecb4002c502bc665c02e3b52efde57af2debcf27dd6e0 languageName: node linkType: hard @@ -7410,7 +7893,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-matrix-org@npm:^2.0.0": +"eslint-plugin-matrix-org@npm:2.1.0": version: 2.1.0 resolution: "eslint-plugin-matrix-org@npm:2.1.0" peerDependencies: @@ -7437,17 +7920,17 @@ __metadata: linkType: hard "eslint-plugin-react-hooks@npm:^5.0.0": - version: 5.1.0 - resolution: "eslint-plugin-react-hooks@npm:5.1.0" + version: 5.2.0 + resolution: "eslint-plugin-react-hooks@npm:5.2.0" peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - checksum: 10c0/37ef76e1d916d46ab8e93a596078efcf2162e2c653614437e0c54e31d02a5dadabec22802fab717effe257aeb4bdc20c2a710666a89ab1cf07e01e614dde75d8 + checksum: 10c0/1c8d50fa5984c6dea32470651807d2922cc3934cf3425e78f84a24c2dfd972e7f019bee84aefb27e0cf2c13fea0ac1d4473267727408feeb1c56333ca1489385 languageName: node linkType: hard "eslint-plugin-react@npm:^7.29.4": - version: 7.37.4 - resolution: "eslint-plugin-react@npm:7.37.4" + version: 7.37.5 + resolution: "eslint-plugin-react@npm:7.37.5" dependencies: array-includes: "npm:^3.1.8" array.prototype.findlast: "npm:^1.2.5" @@ -7459,7 +7942,7 @@ __metadata: hasown: "npm:^2.0.2" jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.8" + object.entries: "npm:^1.1.9" object.fromentries: "npm:^2.0.8" object.values: "npm:^1.2.1" prop-types: "npm:^15.8.1" @@ -7469,7 +7952,7 @@ __metadata: string.prototype.repeat: "npm:^1.0.0" peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - checksum: 10c0/4acbbdb19669dfa9a162ed8847c3ad1918f6aea1ceb675ee320b5d903b4e463fdef25e15233295b6d0a726fef2ea8b015c527da769c7690932ddc52d5b82ba12 + checksum: 10c0/c850bfd556291d4d9234f5ca38db1436924a1013627c8ab1853f77cac73ec19b020e861e6c7b783436a48b6ffcdfba4547598235a37ad4611b6739f65fd8ad57 languageName: node linkType: hard @@ -7685,10 +8168,10 @@ __metadata: languageName: node linkType: hard -"expect-type@npm:^1.1.0": - version: 1.2.0 - resolution: "expect-type@npm:1.2.0" - checksum: 10c0/6069e1980bf16b9385646800e23499c1447df636c433014f6bbabe4bb0e20bd0033f30d38a6f9ae0938b0203a9e870cc82cdfd74b7c837b480cefb8e8240d8e8 +"expect-type@npm:^1.2.1": + version: 1.2.1 + resolution: "expect-type@npm:1.2.1" + checksum: 10c0/b775c9adab3c190dd0d398c722531726cdd6022849b4adba19dceab58dda7e000a7c6c872408cd73d665baa20d381eca36af4f7b393a4ba60dd10232d1fb8898 languageName: node linkType: hard @@ -7753,7 +8236,7 @@ __metadata: languageName: node linkType: hard -"fastq@npm:^1.13.0, fastq@npm:^1.15.0, fastq@npm:^1.6.0": +"fastq@npm:^1.13.0, fastq@npm:^1.6.0": version: 1.19.1 resolution: "fastq@npm:1.19.1" dependencies: @@ -7762,6 +8245,27 @@ __metadata: languageName: node linkType: hard +"fd-package-json@npm:^1.2.0": + version: 1.2.0 + resolution: "fd-package-json@npm:1.2.0" + dependencies: + walk-up-path: "npm:^3.0.1" + checksum: 10c0/712a78a12bd8ec8482867b26bbcb2ff1dca9b096a416150c138e1512f1879c6d23dfb41b03b8e9226afc1e58a35df4738e9f9ae57032ff1dbbae75acfb70343b + languageName: node + linkType: hard + +"fdir@npm:^6.4.4": + version: 6.4.4 + resolution: "fdir@npm:6.4.4" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10c0/6ccc33be16945ee7bc841e1b4178c0b4cf18d3804894cb482aa514651c962a162f96da7ffc6ebfaf0df311689fb70091b04dd6caffe28d56b9ebdc0e7ccadfdd + languageName: node + linkType: hard + "fflate@npm:^0.4.8": version: 0.4.8 resolution: "fflate@npm:0.4.8" @@ -7853,14 +8357,14 @@ __metadata: languageName: node linkType: hard -"form-data@npm:^4.0.1": - version: 4.0.1 - resolution: "form-data@npm:4.0.1" +"formatly@npm:^0.2.3": + version: 0.2.3 + resolution: "formatly@npm:0.2.3" dependencies: - asynckit: "npm:^0.4.0" - combined-stream: "npm:^1.0.8" - mime-types: "npm:^2.1.12" - checksum: 10c0/bb102d570be8592c23f4ea72d7df9daa50c7792eb0cf1c5d7e506c1706e7426a4e4ae48a35b109e91c85f1c0ec63774a21ae252b66f4eb981cb8efef7d0463c8 + fd-package-json: "npm:^1.2.0" + bin: + formatly: bin/index.mjs + checksum: 10c0/d63e492b9f281ce68a40baab609536acc6e7e09343e53f261b2203726cebd8db145d329c6bca2f8a494f4e16db3ade6c9d1a62c32c66df170d04fbc82893ceda languageName: node linkType: hard @@ -8054,6 +8558,24 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.3.0": + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + math-intrinsics: "npm:^1.1.0" + checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a + languageName: node + linkType: hard + "get-nonce@npm:^1.0.0": version: 1.0.1 resolution: "get-nonce@npm:1.0.1" @@ -8221,7 +8743,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.8": +"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.8": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -8444,11 +8966,11 @@ __metadata: linkType: hard "i18next-browser-languagedetector@npm:^8.0.0": - version: 8.0.4 - resolution: "i18next-browser-languagedetector@npm:8.0.4" + version: 8.1.0 + resolution: "i18next-browser-languagedetector@npm:8.1.0" dependencies: "@babel/runtime": "npm:^7.23.2" - checksum: 10c0/82fb7333af5afdda6c31679713571a28095635a2120c95446e57d29cc1792afec42c437e2926f770c760ea58c372980c299233245c54756069b2e3fd6a05e53a + checksum: 10c0/d55162f8062e4fdca07403273ef352e7122e1f9abe479404c6711f5a9b75ddb4b33d49b5a50416637d3a3f0553881ba6a570062c8f6e6c52b031eceb0bb8669e languageName: node linkType: hard @@ -8480,16 +9002,16 @@ __metadata: linkType: hard "i18next@npm:^23.5.1 || ^24.2.0, i18next@npm:^24.0.0": - version: 24.2.2 - resolution: "i18next@npm:24.2.2" + version: 24.2.3 + resolution: "i18next@npm:24.2.3" dependencies: - "@babel/runtime": "npm:^7.23.2" + "@babel/runtime": "npm:^7.26.10" peerDependencies: typescript: ^5 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/df2f08f7e7a813d0c38f67e9a9f67f6e86cd105a58b6419cab1118833e0a8ebf8d31e2df9033c12890fc1db18740fc227acc593c0a30887f8f7f94cd0293d051 + checksum: 10c0/7ac11a67d618ec714beef303aa497c1249bf5f1977dd3ebe9ca2673dfa6cadbba9e2d39ec1337688903ae3866ce9c1bc22cd6b265e66cce54c5db3a9bbedd390 languageName: node linkType: hard @@ -8509,13 +9031,20 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.1.8, ignore@npm:^5.2.0, ignore@npm:^5.3.1": +"ignore@npm:^5.2.0": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 languageName: node linkType: hard +"ignore@npm:^7.0.0": + version: 7.0.4 + resolution: "ignore@npm:7.0.4" + checksum: 10c0/90e1f69ce352b9555caecd9cbfd07abe7626d312a6f90efbbb52c7edca6ea8df065d66303863b30154ab1502afb2da8bc59d5b04e1719a52ef75bbf675c488eb + languageName: node + linkType: hard + "immutable@npm:^5.0.2": version: 5.0.3 resolution: "immutable@npm:5.0.3" @@ -9035,13 +9564,12 @@ __metadata: linkType: hard "jsdom@npm:^26.0.0": - version: 26.0.0 - resolution: "jsdom@npm:26.0.0" + version: 26.1.0 + resolution: "jsdom@npm:26.1.0" dependencies: cssstyle: "npm:^4.2.1" data-urls: "npm:^5.0.0" - decimal.js: "npm:^10.4.3" - form-data: "npm:^4.0.1" + decimal.js: "npm:^10.5.0" html-encoding-sniffer: "npm:^4.0.0" http-proxy-agent: "npm:^7.0.2" https-proxy-agent: "npm:^7.0.6" @@ -9051,12 +9579,12 @@ __metadata: rrweb-cssom: "npm:^0.8.0" saxes: "npm:^6.0.0" symbol-tree: "npm:^3.2.4" - tough-cookie: "npm:^5.0.0" + tough-cookie: "npm:^5.1.1" w3c-xmlserializer: "npm:^5.0.0" webidl-conversions: "npm:^7.0.0" whatwg-encoding: "npm:^3.1.1" whatwg-mimetype: "npm:^4.0.0" - whatwg-url: "npm:^14.1.0" + whatwg-url: "npm:^14.1.1" ws: "npm:^8.18.0" xml-name-validator: "npm:^5.0.0" peerDependencies: @@ -9064,7 +9592,7 @@ __metadata: peerDependenciesMeta: canvas: optional: true - checksum: 10c0/e48725ba4027edcfc9bca5799eaec72c6561ecffe3675a8ff87fe9c3541ca4ff9f82b4eff5b3d9c527302da0d859b2f60e9364347a5d42b77f5c76c436c569dc + checksum: 10c0/5b14a5bc32ce077a06fb42d1ab95b1191afa5cbbce8859e3b96831c5143becbbcbf0511d4d4934e922d2901443ced2cdc3b734c1cf30b5f73b3e067ce457d0f4 languageName: node linkType: hard @@ -9204,23 +9732,20 @@ __metadata: linkType: hard "knip@npm:^5.27.2": - version: 5.45.0 - resolution: "knip@npm:5.45.0" + version: 5.58.1 + resolution: "knip@npm:5.58.1" dependencies: - "@nodelib/fs.walk": "npm:3.0.1" - "@snyk/github-codeowners": "npm:1.1.0" - easy-table: "npm:1.2.0" - enhanced-resolve: "npm:^5.18.0" + "@nodelib/fs.walk": "npm:^1.2.3" fast-glob: "npm:^3.3.3" + formatly: "npm:^0.2.3" jiti: "npm:^2.4.2" js-yaml: "npm:^4.1.0" minimist: "npm:^1.2.8" + oxc-resolver: "npm:^9.0.2" picocolors: "npm:^1.1.0" picomatch: "npm:^4.0.1" - pretty-ms: "npm:^9.0.0" smol-toml: "npm:^1.3.1" strip-json-comments: "npm:5.0.1" - summary: "npm:2.1.0" zod: "npm:^3.22.4" zod-validation-error: "npm:^3.0.3" peerDependencies: @@ -9229,7 +9754,7 @@ __metadata: bin: knip: bin/knip.js knip-bun: bin/knip-bun.js - checksum: 10c0/21e9ef6286c9576e43289c3d44ba69033e9c8f1e47cb9b81fdb66ce7c13633d1f2a9277df0a1a69bbc3c39411c759aa46fdc2e924fffa171fb8eac557c54cb60 + checksum: 10c0/486af895f48a42cd9e04f621006a223855672c7c6113a956db2374bf391774c5c435878d399875c1d6fdc7e230153d88edf348cadb08358fb31e8c2c2c40ab69 languageName: node linkType: hard @@ -9280,12 +9805,12 @@ __metadata: languageName: node linkType: hard -"livekit-client@npm:2.11.2": - version: 2.11.2 - resolution: "livekit-client@npm:2.11.2" +"livekit-client@npm:^2.13.0": + version: 2.13.3 + resolution: "livekit-client@npm:2.13.3" dependencies: "@livekit/mutex": "npm:1.1.1" - "@livekit/protocol": "npm:1.36.1" + "@livekit/protocol": "npm:1.38.0" events: "npm:^3.3.0" loglevel: "npm:^1.9.2" sdp-transform: "npm:^2.15.0" @@ -9293,7 +9818,9 @@ __metadata: tslib: "npm:2.8.1" typed-emitter: "npm:^2.1.0" webrtc-adapter: "npm:^9.0.1" - checksum: 10c0/03a184f3a4f81beefb47a78adb37d3ba3b95a5d1f01e2ebbb83fb3769a120f6b8726ee8ccd96eb634164eeec508850cf05d40e2330fe7c1eda0e3d7f481561f7 + peerDependencies: + "@types/dom-mediacapture-record": ^1 + checksum: 10c0/9eadb9835514551c8e834cebb607999e632bc4b3b3e5d5e206db90b66e2e5467b8a1f76a03c648e00cc96c87256b4eece58dbb2b92dfcafa84f4798bbb305060 languageName: node linkType: hard @@ -9350,7 +9877,7 @@ __metadata: languageName: node linkType: hard -"loglevel@npm:^1.7.1, loglevel@npm:^1.9.1, loglevel@npm:^1.9.2": +"loglevel@npm:^1.9.1, loglevel@npm:^1.9.2": version: 1.9.2 resolution: "loglevel@npm:1.9.2" checksum: 10c0/1e317fa4648fe0b4a4cffef6de037340592cee8547b07d4ce97a487abe9153e704b98451100c799b032c72bb89c9366d71c9fb8192ada8703269263ae77acdc7 @@ -9504,18 +10031,18 @@ __metadata: languageName: node linkType: hard -"matrix-js-sdk@github:matrix-org/matrix-js-sdk#64e27f5d3cdab6aafeb7c22f1264416ffa72b83f": - version: 37.3.0 - resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=64e27f5d3cdab6aafeb7c22f1264416ffa72b83f" +"matrix-js-sdk@github:matrix-org/matrix-js-sdk#head=develop": + version: 37.6.0 + resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=bf6dc16ad32d47f2c6e167236f4c853ceef01d4f" dependencies: "@babel/runtime": "npm:^7.12.5" - "@matrix-org/matrix-sdk-crypto-wasm": "npm:^14.0.1" + "@matrix-org/matrix-sdk-crypto-wasm": "npm:^14.2.0" "@matrix-org/olm": "npm:3.2.15" another-json: "npm:^0.2.0" bs58: "npm:^6.0.0" content-type: "npm:^1.0.4" jwt-decode: "npm:^4.0.0" - loglevel: "npm:^1.7.1" + loglevel: "npm:^1.9.2" matrix-events-sdk: "npm:0.0.1" matrix-widget-api: "npm:^1.10.0" oidc-client-ts: "npm:^3.0.1" @@ -9523,17 +10050,17 @@ __metadata: sdp-transform: "npm:^2.14.1" unhomoglyph: "npm:^1.0.6" uuid: "npm:11" - checksum: 10c0/716f89b4fffc67ae42fad55f47b96792a0c49bd6d741410758dfbe1d0e4673097627b4c8f8a77063702cb41a5e0f7f0c5ff96c109ed332d3b3bc973f4d31f555 + checksum: 10c0/2877e7c5b2779200b48f3152bb7b510e58899b1e779e7e6d2bc1a236ed178fa8858f0547b644a2029f48f55dc7cc3954f48e2598c8963d45293c8280ccc23039 languageName: node linkType: hard -"matrix-widget-api@npm:1.11.0": - version: 1.11.0 - resolution: "matrix-widget-api@npm:1.11.0" +"matrix-widget-api@npm:^1.10.0, matrix-widget-api@npm:^1.13.0": + version: 1.13.1 + resolution: "matrix-widget-api@npm:1.13.1" dependencies: "@types/events": "npm:^3.0.0" events: "npm:^3.2.0" - checksum: 10c0/ac35ed8fb2b5df6d186beb64b5faf907ec113d708ad8353bdd8f9196fb3da255561b8807e2e845f39d4cf7ae6af36f90b54c230a0a100556ac7ebd8f18bee848 + checksum: 10c0/25ded744922755b3eb65f4e171cf6cff1a2e0fe43fc3fecbb13e565e41d8af066daa817dd2c3c7d921b996af399eec3b23df70ab7b682cf422d9cee7ca202512 languageName: node linkType: hard @@ -9561,7 +10088,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.35": +"mime-types@npm:^2.1.35": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -9931,14 +10458,15 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.8": - version: 1.1.8 - resolution: "object.entries@npm:1.1.8" +"object.entries@npm:^1.1.9": + version: 1.1.9 + resolution: "object.entries@npm:1.1.9" dependencies: - call-bind: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/db9ea979d2956a3bc26c262da4a4d212d36f374652cc4c13efdd069c1a519c16571c137e2893d1c46e1cb0e15c88fd6419eaf410c945f329f09835487d7e65d3 + es-object-atoms: "npm:^1.1.1" + checksum: 10c0/d4b8c1e586650407da03370845f029aa14076caca4e4d4afadbc69cfb5b78035fd3ee7be417141abdb0258fa142e59b11923b4c44d8b1255b28f5ffcc50da7db languageName: node linkType: hard @@ -10042,6 +10570,54 @@ __metadata: languageName: node linkType: hard +"oxc-resolver@npm:^9.0.2": + version: 9.0.2 + resolution: "oxc-resolver@npm:9.0.2" + dependencies: + "@oxc-resolver/binding-darwin-arm64": "npm:9.0.2" + "@oxc-resolver/binding-darwin-x64": "npm:9.0.2" + "@oxc-resolver/binding-freebsd-x64": "npm:9.0.2" + "@oxc-resolver/binding-linux-arm-gnueabihf": "npm:9.0.2" + "@oxc-resolver/binding-linux-arm64-gnu": "npm:9.0.2" + "@oxc-resolver/binding-linux-arm64-musl": "npm:9.0.2" + "@oxc-resolver/binding-linux-riscv64-gnu": "npm:9.0.2" + "@oxc-resolver/binding-linux-s390x-gnu": "npm:9.0.2" + "@oxc-resolver/binding-linux-x64-gnu": "npm:9.0.2" + "@oxc-resolver/binding-linux-x64-musl": "npm:9.0.2" + "@oxc-resolver/binding-wasm32-wasi": "npm:9.0.2" + "@oxc-resolver/binding-win32-arm64-msvc": "npm:9.0.2" + "@oxc-resolver/binding-win32-x64-msvc": "npm:9.0.2" + dependenciesMeta: + "@oxc-resolver/binding-darwin-arm64": + optional: true + "@oxc-resolver/binding-darwin-x64": + optional: true + "@oxc-resolver/binding-freebsd-x64": + optional: true + "@oxc-resolver/binding-linux-arm-gnueabihf": + optional: true + "@oxc-resolver/binding-linux-arm64-gnu": + optional: true + "@oxc-resolver/binding-linux-arm64-musl": + optional: true + "@oxc-resolver/binding-linux-riscv64-gnu": + optional: true + "@oxc-resolver/binding-linux-s390x-gnu": + optional: true + "@oxc-resolver/binding-linux-x64-gnu": + optional: true + "@oxc-resolver/binding-linux-x64-musl": + optional: true + "@oxc-resolver/binding-wasm32-wasi": + optional: true + "@oxc-resolver/binding-win32-arm64-msvc": + optional: true + "@oxc-resolver/binding-win32-x64-msvc": + optional: true + checksum: 10c0/54c9791d19a44930448d21ea79fca5b6649d69b41a8e8b0ca2d57345e871608a775b54ff92827f65177b5d856c6ce490e0ce99209d899d74de7db6be49c56a6d + languageName: node + linkType: hard + "p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" @@ -10078,15 +10654,6 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^4.0.0": - version: 4.0.0 - resolution: "p-map@npm:4.0.0" - dependencies: - aggregate-error: "npm:^3.0.0" - checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 - languageName: node - linkType: hard - "p-map@npm:^7.0.2": version: 7.0.3 resolution: "p-map@npm:7.0.3" @@ -10156,13 +10723,6 @@ __metadata: languageName: node linkType: hard -"parse-ms@npm:^4.0.0": - version: 4.0.0 - resolution: "parse-ms@npm:4.0.0" - checksum: 10c0/a7900f4f1ebac24cbf5e9708c16fb2fd482517fad353aecd7aefb8c2ba2f85ce017913ccb8925d231770404780df46244ea6fec598b3bde6490882358b4d2d16 - languageName: node - linkType: hard - "parse5-htmlparser2-tree-adapter@npm:^7.0.0": version: 7.1.0 resolution: "parse5-htmlparser2-tree-adapter@npm:7.1.0" @@ -10274,7 +10834,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 @@ -10295,27 +10855,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.51.0": - version: 1.51.0 - resolution: "playwright-core@npm:1.51.0" +"playwright-core@npm:1.52.0": + version: 1.52.0 + resolution: "playwright-core@npm:1.52.0" bin: playwright-core: cli.js - checksum: 10c0/8f5de23088c5e97c00327f356b17e0223181e921baf99f4e38d9a3b18d0693db288f8b5389e96d0cb4a1b55f03870f140dd7346128a0c02ce36d11eb92153841 + checksum: 10c0/640945507e6ca2144e9f596b2a6ecac042c2fd3683ff99e6271e9a7b38f3602d415f282609d569456f66680aab8b3c5bb1b257d8fb63a7fc0ed648261110421f languageName: node linkType: hard -"playwright@npm:1.51.0": - version: 1.51.0 - resolution: "playwright@npm:1.51.0" +"playwright@npm:1.52.0": + version: 1.52.0 + resolution: "playwright@npm:1.52.0" dependencies: fsevents: "npm:2.3.2" - playwright-core: "npm:1.51.0" + playwright-core: "npm:1.52.0" dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 10c0/e8509ea500e03e8051fd243f2347ac3196ff8dde4c20ae3aba4cf723e2b647a0158d209fba062995dab90590229a483d723562cf1ea8b2fc11698617027416fd + checksum: 10c0/2c6edf1e15e59bbaf77f3fa0fe0ac975793c17cff835d9c8b8bc6395a3b6f1c01898b3058ab37891b2e4d424bcc8f1b4844fe70d943e0143d239d7451408c579 languageName: node linkType: hard @@ -10362,18 +10922,18 @@ __metadata: languageName: node linkType: hard -"postcss-color-functional-notation@npm:^7.0.8": - version: 7.0.8 - resolution: "postcss-color-functional-notation@npm:7.0.8" +"postcss-color-functional-notation@npm:^7.0.10": + version: 7.0.10 + resolution: "postcss-color-functional-notation@npm:7.0.10" dependencies: - "@csstools/css-color-parser": "npm:^3.0.8" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/4180e2f6ee9c925d6c47e727cfc50de2186d4a5cfda6e1ccf28f60e5536b418ddd90f9cc5f9cbcd1900f74098101bca8f844867e16b591e66760300e34257e47 + checksum: 10c0/62ee77ef220488cfb4a1c5af4f5203a0c2951c8a0613088ffc946130d48b63ca28ab67b18ed380a288a7ce51c2360a75d8d08d2db389e48f4ebb78a3e52d15b6 languageName: node linkType: hard @@ -10401,46 +10961,46 @@ __metadata: languageName: node linkType: hard -"postcss-custom-media@npm:^11.0.5": - version: 11.0.5 - resolution: "postcss-custom-media@npm:11.0.5" +"postcss-custom-media@npm:^11.0.6": + version: 11.0.6 + resolution: "postcss-custom-media@npm:11.0.6" dependencies: - "@csstools/cascade-layer-name-parser": "npm:^2.0.4" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/media-query-list-parser": "npm:^4.0.2" + "@csstools/cascade-layer-name-parser": "npm:^2.0.5" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/media-query-list-parser": "npm:^4.0.3" peerDependencies: postcss: ^8.4 - checksum: 10c0/5ba1ca0383818e83d5f6f398a2b0c12cfda066b5d552adfc0e030a2c5f8690c2cc6224f9a1832a9c780dae3fd8d00d78c4a5c88eb36b731da1752f0c3917d488 + checksum: 10c0/62dcb2858fd490d90aab32062621d58892a7b2a54948ee63af81a2cd61807a11815d28d4ef6bc800c5e142ac73098f7e56822c7cc63192eb20d5b16071543a73 languageName: node linkType: hard -"postcss-custom-properties@npm:^14.0.4": - version: 14.0.4 - resolution: "postcss-custom-properties@npm:14.0.4" +"postcss-custom-properties@npm:^14.0.5": + version: 14.0.5 + resolution: "postcss-custom-properties@npm:14.0.5" dependencies: - "@csstools/cascade-layer-name-parser": "npm:^2.0.4" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" + "@csstools/cascade-layer-name-parser": "npm:^2.0.5" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" "@csstools/utilities": "npm:^2.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/5b101ee71289657cc2e5a16f4912009c10441052e2c54bd9e4f3d4d72b652bab56adb662ddaa96881413e375cf9852e2159b3c778d953442ce86efb781c3b2bf + checksum: 10c0/ddee0545075dc0888cd54a9bb5791a98719a5d4f31d1de33823841efb540fa79f65e48b7c4aaba753d3214102e419536c5bc46c72e6e1579e5352da4e042ef3b languageName: node linkType: hard -"postcss-custom-selectors@npm:^8.0.4": - version: 8.0.4 - resolution: "postcss-custom-selectors@npm:8.0.4" +"postcss-custom-selectors@npm:^8.0.5": + version: 8.0.5 + resolution: "postcss-custom-selectors@npm:8.0.5" dependencies: - "@csstools/cascade-layer-name-parser": "npm:^2.0.4" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" + "@csstools/cascade-layer-name-parser": "npm:^2.0.5" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" postcss-selector-parser: "npm:^7.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/09d494d2580d0a99f57684f79793d03358286c32460b61a84063c33bdde24865771cb1205efe9a8e26a508be24eba4fb93fc7f1e96ba21ca96a5d17fadb24863 + checksum: 10c0/bd8f2f85bbec4bd56ff408cb699d9fe649e2af0db82d5752eee05481ae522f06f5a47950ca22fcb4c8601071c03346df67cf20b0b0bcade32ce58d07ebaf9b32 languageName: node linkType: hard @@ -10455,16 +11015,16 @@ __metadata: languageName: node linkType: hard -"postcss-double-position-gradients@npm:^6.0.0": - version: 6.0.0 - resolution: "postcss-double-position-gradients@npm:6.0.0" +"postcss-double-position-gradients@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-double-position-gradients@npm:6.0.2" dependencies: - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/7a0e119df1b4af59d169b1a9dfc563275ce29b4ae5e6a6c90be29a7a59272ebc55bf3b2ed05a962f73b03194f7a88f6fe738e65c1659d43351fbdc705cc951ad + checksum: 10c0/7b4759813f99039c6a7c8e70b46ff4c34c27e723a9ff7f0e1044e293d568357e1d39233f94b1bf3b2768b1207348138faea0781086a66b7b8e39e780657da523 languageName: node linkType: hard @@ -10520,18 +11080,18 @@ __metadata: languageName: node linkType: hard -"postcss-lab-function@npm:^7.0.8": - version: 7.0.8 - resolution: "postcss-lab-function@npm:7.0.8" +"postcss-lab-function@npm:^7.0.10": + version: 7.0.10 + resolution: "postcss-lab-function@npm:7.0.10" dependencies: - "@csstools/css-color-parser": "npm:^3.0.8" - "@csstools/css-parser-algorithms": "npm:^3.0.4" - "@csstools/css-tokenizer": "npm:^3.0.3" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" + "@csstools/css-color-parser": "npm:^3.0.10" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" "@csstools/utilities": "npm:^2.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/5f7b6f95cb3d1aa099c16dcdd89c575f112387600f30949f74c205e0846c9303ca851be794fad9fd56825859d38ac811f972cc34bbc2dfcf71371c640165ddfb + checksum: 10c0/3e235b52f6c119937a0b41aa351f5f9ef6e17bf1b868e7068c9a04f3d31c247d0296c862388febb7fec5102d81413ccade8a4788904289afd34aa072de71390b languageName: node linkType: hard @@ -10600,63 +11160,64 @@ __metadata: linkType: hard "postcss-preset-env@npm:^10.0.0": - version: 10.1.5 - resolution: "postcss-preset-env@npm:10.1.5" + version: 10.2.0 + resolution: "postcss-preset-env@npm:10.2.0" dependencies: "@csstools/postcss-cascade-layers": "npm:^5.0.1" - "@csstools/postcss-color-function": "npm:^4.0.8" - "@csstools/postcss-color-mix-function": "npm:^3.0.8" - "@csstools/postcss-content-alt-text": "npm:^2.0.4" - "@csstools/postcss-exponential-functions": "npm:^2.0.7" + "@csstools/postcss-color-function": "npm:^4.0.10" + "@csstools/postcss-color-mix-function": "npm:^3.0.10" + "@csstools/postcss-color-mix-variadic-function-arguments": "npm:^1.0.0" + "@csstools/postcss-content-alt-text": "npm:^2.0.6" + "@csstools/postcss-exponential-functions": "npm:^2.0.9" "@csstools/postcss-font-format-keywords": "npm:^4.0.0" - "@csstools/postcss-gamut-mapping": "npm:^2.0.8" - "@csstools/postcss-gradients-interpolation-method": "npm:^5.0.8" - "@csstools/postcss-hwb-function": "npm:^4.0.8" - "@csstools/postcss-ic-unit": "npm:^4.0.0" + "@csstools/postcss-gamut-mapping": "npm:^2.0.10" + "@csstools/postcss-gradients-interpolation-method": "npm:^5.0.10" + "@csstools/postcss-hwb-function": "npm:^4.0.10" + "@csstools/postcss-ic-unit": "npm:^4.0.2" "@csstools/postcss-initial": "npm:^2.0.1" "@csstools/postcss-is-pseudo-class": "npm:^5.0.1" - "@csstools/postcss-light-dark-function": "npm:^2.0.7" + "@csstools/postcss-light-dark-function": "npm:^2.0.9" "@csstools/postcss-logical-float-and-clear": "npm:^3.0.0" "@csstools/postcss-logical-overflow": "npm:^2.0.0" "@csstools/postcss-logical-overscroll-behavior": "npm:^2.0.0" "@csstools/postcss-logical-resize": "npm:^3.0.0" - "@csstools/postcss-logical-viewport-units": "npm:^3.0.3" - "@csstools/postcss-media-minmax": "npm:^2.0.7" - "@csstools/postcss-media-queries-aspect-ratio-number-values": "npm:^3.0.4" + "@csstools/postcss-logical-viewport-units": "npm:^3.0.4" + "@csstools/postcss-media-minmax": "npm:^2.0.9" + "@csstools/postcss-media-queries-aspect-ratio-number-values": "npm:^3.0.5" "@csstools/postcss-nested-calc": "npm:^4.0.0" "@csstools/postcss-normalize-display-values": "npm:^4.0.0" - "@csstools/postcss-oklab-function": "npm:^4.0.8" - "@csstools/postcss-progressive-custom-properties": "npm:^4.0.0" - "@csstools/postcss-random-function": "npm:^1.0.3" - "@csstools/postcss-relative-color-syntax": "npm:^3.0.8" + "@csstools/postcss-oklab-function": "npm:^4.0.10" + "@csstools/postcss-progressive-custom-properties": "npm:^4.1.0" + "@csstools/postcss-random-function": "npm:^2.0.1" + "@csstools/postcss-relative-color-syntax": "npm:^3.0.10" "@csstools/postcss-scope-pseudo-class": "npm:^4.0.1" - "@csstools/postcss-sign-functions": "npm:^1.1.2" - "@csstools/postcss-stepped-value-functions": "npm:^4.0.7" + "@csstools/postcss-sign-functions": "npm:^1.1.4" + "@csstools/postcss-stepped-value-functions": "npm:^4.0.9" "@csstools/postcss-text-decoration-shorthand": "npm:^4.0.2" - "@csstools/postcss-trigonometric-functions": "npm:^4.0.7" + "@csstools/postcss-trigonometric-functions": "npm:^4.0.9" "@csstools/postcss-unset-value": "npm:^4.0.0" - autoprefixer: "npm:^10.4.19" - browserslist: "npm:^4.24.4" + autoprefixer: "npm:^10.4.21" + browserslist: "npm:^4.24.5" css-blank-pseudo: "npm:^7.0.1" css-has-pseudo: "npm:^7.0.2" css-prefers-color-scheme: "npm:^10.0.0" - cssdb: "npm:^8.2.3" + cssdb: "npm:^8.3.0" postcss-attribute-case-insensitive: "npm:^7.0.1" postcss-clamp: "npm:^4.1.0" - postcss-color-functional-notation: "npm:^7.0.8" + postcss-color-functional-notation: "npm:^7.0.10" postcss-color-hex-alpha: "npm:^10.0.0" postcss-color-rebeccapurple: "npm:^10.0.0" - postcss-custom-media: "npm:^11.0.5" - postcss-custom-properties: "npm:^14.0.4" - postcss-custom-selectors: "npm:^8.0.4" + postcss-custom-media: "npm:^11.0.6" + postcss-custom-properties: "npm:^14.0.5" + postcss-custom-selectors: "npm:^8.0.5" postcss-dir-pseudo-class: "npm:^9.0.1" - postcss-double-position-gradients: "npm:^6.0.0" + postcss-double-position-gradients: "npm:^6.0.2" postcss-focus-visible: "npm:^10.0.1" postcss-focus-within: "npm:^9.0.1" postcss-font-variant: "npm:^5.0.0" postcss-gap-properties: "npm:^6.0.0" postcss-image-set-function: "npm:^7.0.0" - postcss-lab-function: "npm:^7.0.8" + postcss-lab-function: "npm:^7.0.10" postcss-logical: "npm:^8.1.0" postcss-nesting: "npm:^13.0.1" postcss-opacity-percentage: "npm:^3.0.0" @@ -10668,7 +11229,7 @@ __metadata: postcss-selector-not: "npm:^8.0.1" peerDependencies: postcss: ^8.4 - checksum: 10c0/5ed5aeb7c9718230742a56d9b49e05a90135bc4bb77f97d9978bdb0b999d36a2d6175d99360c966cb7a307c9efe4b8792f4c0b79ec99a233f9e1c1ebae4244f0 + checksum: 10c0/33406dcdd1d63fd3810f12cd97bf0d6a09a51917943ee7d75e2ccaf1d8cbce363abcb90ee68f14509d287d00de4afd6664dbdecaa4f4b95509e3578e27f54a24 languageName: node linkType: hard @@ -10776,15 +11337,6 @@ __metadata: languageName: node linkType: hard -"pretty-ms@npm:^9.0.0": - version: 9.2.0 - resolution: "pretty-ms@npm:9.2.0" - dependencies: - parse-ms: "npm:^4.0.0" - checksum: 10c0/ab6d066f90e9f77020426986e1b018369f41575674544c539aabec2e63a20fec01166d8cf6571d0e165ad11cfe5a8134a2a48a36d42ab291c59c6deca5264cbb - languageName: node - linkType: hard - "proc-log@npm:^5.0.0": version: 5.0.0 resolution: "proc-log@npm:5.0.0" @@ -10922,20 +11474,23 @@ __metadata: linkType: hard "react-i18next@npm:^15.0.0": - version: 15.4.1 - resolution: "react-i18next@npm:15.4.1" + version: 15.5.2 + resolution: "react-i18next@npm:15.5.2" dependencies: "@babel/runtime": "npm:^7.25.0" html-parse-stringify: "npm:^3.0.1" peerDependencies: i18next: ">= 23.2.3" react: ">= 16.8.0" + typescript: ^5 peerDependenciesMeta: react-dom: optional: true react-native: optional: true - checksum: 10c0/4f421a4db8255766bdbc8cc262b03c75bed4d92e5f7cc79dee99236c3239eb86a4d100fcbc6c2c735fa0207de23c09516450c8d970d193b0f7c2a3daaa51e261 + typescript: + optional: true + checksum: 10c0/f31d3b10e1e3e1868831da872734cdb2042dd594ac01668478c4e39ca0bf8ee252da17fd0c435c9f5480501e612d8e28c90517df949651cfe4fe42667f3c06a9 languageName: node linkType: hard @@ -10953,10 +11508,10 @@ __metadata: languageName: node linkType: hard -"react-refresh@npm:^0.14.2": - version: 0.14.2 - resolution: "react-refresh@npm:0.14.2" - checksum: 10c0/875b72ef56b147a131e33f2abd6ec059d1989854b3ff438898e4f9310bfcc73acff709445b7ba843318a953cb9424bcc2c05af2b3d80011cee28f25aef3e2ebb +"react-refresh@npm:^0.17.0": + version: 0.17.0 + resolution: "react-refresh@npm:0.17.0" + checksum: 10c0/002cba940384c9930008c0bce26cac97a9d5682bc623112c2268ba0c155127d9c178a9a5cc2212d560088d60dfd503edd808669a25f9b377f316a32361d0b23c languageName: node linkType: hard @@ -11015,32 +11570,30 @@ __metadata: linkType: hard "react-router-dom@npm:^7.0.0": - version: 7.2.0 - resolution: "react-router-dom@npm:7.2.0" + version: 7.6.1 + resolution: "react-router-dom@npm:7.6.1" dependencies: - react-router: "npm:7.2.0" + react-router: "npm:7.6.1" peerDependencies: react: ">=18" react-dom: ">=18" - checksum: 10c0/b4199ea9767cd4db070faf33f9de35e35fcd55539145455b7eb4375c9072a42d2ac33930103d2a4d74c3466ab2792f99ff0dd612db9e353c61cd870916d232d6 + checksum: 10c0/9d448d82d73c18475c8e3e2f93cf9dd16ca0488379e295f5a949aa849aaf770eb6257d48f2aef2c62ac1635e8ccddd0fa53173c2479525305eb656936f330812 languageName: node linkType: hard -"react-router@npm:7.2.0": - version: 7.2.0 - resolution: "react-router@npm:7.2.0" +"react-router@npm:7.6.1": + version: 7.6.1 + resolution: "react-router@npm:7.6.1" dependencies: - "@types/cookie": "npm:^0.6.0" cookie: "npm:^1.0.1" set-cookie-parser: "npm:^2.6.0" - turbo-stream: "npm:2.4.0" peerDependencies: react: ">=18" react-dom: ">=18" peerDependenciesMeta: react-dom: optional: true - checksum: 10c0/eb3fe57405a90d22f0a5455a3f73ec60fe2808a579d37bf130c192dfde18ebab06353e2cda2ed0f67701a6c43445eab1c1b6caa1347e5635dc65ff3028b7c2e2 + checksum: 10c0/9968dcccc6695671cb216a74a756d717f47d5b8613869be72764966c2dc252ce12aa91a5f74838776b78d65a2297d7d5455c26a3ed78a380897905383b30c7d8 languageName: node linkType: hard @@ -11215,15 +11768,6 @@ __metadata: languageName: node linkType: hard -"regenerator-transform@npm:^0.15.2": - version: 0.15.2 - resolution: "regenerator-transform@npm:0.15.2" - dependencies: - "@babel/runtime": "npm:^7.8.4" - checksum: 10c0/7cfe6931ec793269701994a93bab89c0cc95379191fad866270a7fea2adfec67ea62bb5b374db77058b60ba4509319d9b608664d0d288bd9989ca8dbd08fae90 - languageName: node - linkType: hard - "regexp-tree@npm:^0.1.27": version: 0.1.27 resolution: "regexp-tree@npm:0.1.27" @@ -11480,31 +12024,31 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.30.1": - version: 4.37.0 - resolution: "rollup@npm:4.37.0" +"rollup@npm:^4.34.9": + version: 4.40.2 + resolution: "rollup@npm:4.40.2" dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.37.0" - "@rollup/rollup-android-arm64": "npm:4.37.0" - "@rollup/rollup-darwin-arm64": "npm:4.37.0" - "@rollup/rollup-darwin-x64": "npm:4.37.0" - "@rollup/rollup-freebsd-arm64": "npm:4.37.0" - "@rollup/rollup-freebsd-x64": "npm:4.37.0" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.37.0" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.37.0" - "@rollup/rollup-linux-arm64-gnu": "npm:4.37.0" - "@rollup/rollup-linux-arm64-musl": "npm:4.37.0" - "@rollup/rollup-linux-loongarch64-gnu": "npm:4.37.0" - "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.37.0" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.37.0" - "@rollup/rollup-linux-riscv64-musl": "npm:4.37.0" - "@rollup/rollup-linux-s390x-gnu": "npm:4.37.0" - "@rollup/rollup-linux-x64-gnu": "npm:4.37.0" - "@rollup/rollup-linux-x64-musl": "npm:4.37.0" - "@rollup/rollup-win32-arm64-msvc": "npm:4.37.0" - "@rollup/rollup-win32-ia32-msvc": "npm:4.37.0" - "@rollup/rollup-win32-x64-msvc": "npm:4.37.0" - "@types/estree": "npm:1.0.6" + "@rollup/rollup-android-arm-eabi": "npm:4.40.2" + "@rollup/rollup-android-arm64": "npm:4.40.2" + "@rollup/rollup-darwin-arm64": "npm:4.40.2" + "@rollup/rollup-darwin-x64": "npm:4.40.2" + "@rollup/rollup-freebsd-arm64": "npm:4.40.2" + "@rollup/rollup-freebsd-x64": "npm:4.40.2" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.40.2" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.40.2" + "@rollup/rollup-linux-arm64-gnu": "npm:4.40.2" + "@rollup/rollup-linux-arm64-musl": "npm:4.40.2" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.40.2" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.40.2" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.40.2" + "@rollup/rollup-linux-riscv64-musl": "npm:4.40.2" + "@rollup/rollup-linux-s390x-gnu": "npm:4.40.2" + "@rollup/rollup-linux-x64-gnu": "npm:4.40.2" + "@rollup/rollup-linux-x64-musl": "npm:4.40.2" + "@rollup/rollup-win32-arm64-msvc": "npm:4.40.2" + "@rollup/rollup-win32-ia32-msvc": "npm:4.40.2" + "@rollup/rollup-win32-x64-msvc": "npm:4.40.2" + "@types/estree": "npm:1.0.7" fsevents: "npm:~2.3.2" dependenciesMeta: "@rollup/rollup-android-arm-eabi": @@ -11551,7 +12095,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/2e00382e08938636edfe0a7547ea2eaa027205dc0b6ff85d8b82be0fbe55a4ef88a1995fee2a5059e33dbccf12d1376c236825353afb89c96298cc95c5160a46 + checksum: 10c0/cbe9b766891da74fbf7c3b50420bb75102e5c59afc0ea45751f7e43a581d2cd93367763f521f820b72e341cf1f6b9951fbdcd3be67a1b0aa774b754525a8b9c7 languageName: node linkType: hard @@ -11576,7 +12120,7 @@ __metadata: languageName: node linkType: hard -"run-parallel@npm:^1.1.9, run-parallel@npm:^1.2.0": +"run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" dependencies: @@ -11667,8 +12211,8 @@ __metadata: linkType: hard "sass@npm:^1.42.1": - version: 1.85.1 - resolution: "sass@npm:1.85.1" + version: 1.89.0 + resolution: "sass@npm:1.89.0" dependencies: "@parcel/watcher": "npm:^2.4.1" chokidar: "npm:^4.0.0" @@ -11679,7 +12223,7 @@ __metadata: optional: true bin: sass: sass.js - checksum: 10c0/f843aa1df1dca2f0e9cb2fb247e4939fd514ae4c182cdd1900a0622c0d71b40dfb1c4225f78b78e165a318287ca137ec597695db3e496408bd16a921a2bc2b3f + checksum: 10c0/8e31b48c5e0abd9d437edb201919a82863f605ace1c1536ccdc6b3133937a70fe29b92ad536af632ecae2f140733931e4ec971e1bfbf8b835c54d392b28331df languageName: node linkType: hard @@ -12031,10 +12575,10 @@ __metadata: languageName: node linkType: hard -"std-env@npm:^3.8.0": - version: 3.8.1 - resolution: "std-env@npm:3.8.1" - checksum: 10c0/e9b19cca6bc6f06f91607db5b636662914ca8ec9efc525a99da6ec7e493afec109d3b017d21d9782b4369fcfb2891c7c4b4e3c60d495fdadf6861ce434e07bf8 +"std-env@npm:^3.9.0": + version: 3.9.0 + resolution: "std-env@npm:3.9.0" + checksum: 10c0/4a6f9218aef3f41046c3c7ecf1f98df00b30a07f4f35c6d47b28329bc2531eef820828951c7d7b39a1c5eb19ad8a46e3ddfc7deb28f0a2f3ceebee11bab7ba50 languageName: node linkType: hard @@ -12229,13 +12773,6 @@ __metadata: languageName: node linkType: hard -"summary@npm:2.1.0": - version: 2.1.0 - resolution: "summary@npm:2.1.0" - checksum: 10c0/2743c1f940fb303c496ef1b085e654704a6c16872957b6b76648c34bd32c8f0b7a3c5ec4e0f8bfb71dcb8473e34d172fef31026b85562af589cf220aa901698d - languageName: node - linkType: hard - "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -12289,13 +12826,6 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.2.0": - version: 2.2.1 - resolution: "tapable@npm:2.2.1" - checksum: 10c0/bc40e6efe1e554d075469cedaba69a30eeb373552aaf41caeaaa45bf56ffacc2674261b106245bd566b35d8f3329b52d838e851ee0a852120acae26e622925c9 - languageName: node - linkType: hard - "tar@npm:^7.4.3": version: 7.4.3 resolution: "tar@npm:7.4.3" @@ -12384,6 +12914,16 @@ __metadata: languageName: node linkType: hard +"tinyglobby@npm:^0.2.13": + version: 0.2.13 + resolution: "tinyglobby@npm:0.2.13" + dependencies: + fdir: "npm:^6.4.4" + picomatch: "npm:^4.0.2" + checksum: 10c0/ef07dfaa7b26936601d3f6d999f7928a4d1c6234c5eb36896bb88681947c0d459b7ebe797022400e555fe4b894db06e922b95d0ce60cb05fd827a0a66326b18c + languageName: node + linkType: hard + "tinypool@npm:^1.0.2": version: 1.0.2 resolution: "tinypool@npm:1.0.2" @@ -12448,12 +12988,12 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^5.0.0": - version: 5.0.0 - resolution: "tough-cookie@npm:5.0.0" +"tough-cookie@npm:^5.1.1": + version: 5.1.2 + resolution: "tough-cookie@npm:5.1.2" dependencies: tldts: "npm:^6.1.32" - checksum: 10c0/4a69c885bf6f45c5a64e60262af99e8c0d58a33bd3d0ce5da62121eeb9c00996d0128a72df8fc4614cbde59cc8b70aa3e21e4c3c98c2bbde137d7aba7fa00124 + checksum: 10c0/5f95023a47de0f30a902bba951664b359725597d8adeabc66a0b93a931c3af801e1e697dae4b8c21a012056c0ea88bd2bf4dfe66b2adcf8e2f42cd9796fe0626 languageName: node linkType: hard @@ -12466,6 +13006,15 @@ __metadata: languageName: node linkType: hard +"tr46@npm:^5.1.0": + version: 5.1.1 + resolution: "tr46@npm:5.1.1" + dependencies: + punycode: "npm:^2.3.1" + checksum: 10c0/ae270e194d52ec67ebd695c1a42876e0f19b96e4aca2ab464ab1d9d17dc3acd3e18764f5034c93897db73421563be27c70c98359c4501136a497e46deda5d5ec + languageName: node + linkType: hard + "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -12482,6 +13031,15 @@ __metadata: languageName: node linkType: hard +"ts-api-utils@npm:^2.1.0": + version: 2.1.0 + resolution: "ts-api-utils@npm:2.1.0" + peerDependencies: + typescript: ">=4.8.4" + checksum: 10c0/9806a38adea2db0f6aa217ccc6bc9c391ddba338a9fe3080676d0d50ed806d305bb90e8cef0276e793d28c8a929f400abb184ddd7ff83a416959c0f4d2ce754f + languageName: node + linkType: hard + "ts-debounce@npm:^4.0.0": version: 4.0.0 resolution: "ts-debounce@npm:4.0.0" @@ -12501,7 +13059,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2, tslib@npm:2.8.1, tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.1.0": +"tslib@npm:2.8.1, tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.8.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 @@ -12549,13 +13107,6 @@ __metadata: languageName: node linkType: hard -"turbo-stream@npm:2.4.0": - version: 2.4.0 - resolution: "turbo-stream@npm:2.4.0" - checksum: 10c0/e68b2569f1f16e6e9633d090c6024b2ae9f0e97bfeacb572451ca3732e120ebbb546f3bc4afc717c46cb57b5aea6104e04ef497f9912eef6a7641e809518e98a - languageName: node - linkType: hard - "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -12672,13 +13223,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.1.6": - version: 5.7.3 - resolution: "typescript@npm:5.7.3" +"typescript@npm:^5.8.3": + version: 5.8.3 + resolution: "typescript@npm:5.8.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa + checksum: 10c0/5f8bb01196e542e64d44db3d16ee0e4063ce4f3e3966df6005f2588e86d91c03e1fb131c2581baf0fb65ee79669eea6e161cd448178986587e9f6844446dbb48 languageName: node linkType: hard @@ -12692,13 +13243,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.1.6#optional!builtin": - version: 5.7.3 - resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin::version=5.7.3&hash=5786d5" +"typescript@patch:typescript@npm%3A^5.8.3#optional!builtin": + version: 5.8.3 + resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4 + checksum: 10c0/39117e346ff8ebd87ae1510b3a77d5d92dae5a89bde588c747d25da5c146603a99c8ee588c7ef80faaf123d89ed46f6dbd918d534d641083177d5fac38b8a1cb languageName: node linkType: hard @@ -12724,17 +13275,10 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.19.8": - version: 6.19.8 - resolution: "undici-types@npm:6.19.8" - checksum: 10c0/078afa5990fba110f6824823ace86073b4638f1d5112ee26e790155f481f2a868cc3e0615505b6f4282bdf74a3d8caad715fd809e870c2bb0704e3ea6082f344 - languageName: node - linkType: hard - -"undici-types@npm:~6.20.0": - version: 6.20.0 - resolution: "undici-types@npm:6.20.0" - checksum: 10c0/68e659a98898d6a836a9a59e6adf14a5d799707f5ea629433e025ac90d239f75e408e2e5ff086afc3cace26f8b26ee52155293564593fbb4a2f666af57fc59bf +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04 languageName: node linkType: hard @@ -12860,7 +13404,7 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.1.1": +"update-browserslist-db@npm:^1.1.1, update-browserslist-db@npm:^1.1.3": version: 1.1.3 resolution: "update-browserslist-db@npm:1.1.3" dependencies: @@ -12914,14 +13458,14 @@ __metadata: languageName: node linkType: hard -"usehooks-ts@npm:3.1.0": - version: 3.1.0 - resolution: "usehooks-ts@npm:3.1.0" +"usehooks-ts@npm:3.1.1": + version: 3.1.1 + resolution: "usehooks-ts@npm:3.1.1" dependencies: lodash.debounce: "npm:^4.0.8" peerDependencies: - react: ^16.8.0 || ^17 || ^18 - checksum: 10c0/2204d8c95109302bdaaa51a66bf216f3dba750f1d2795c20ecba75ba1c44a070a253935d537ef536514ab6e363bcc02ccc78b5ad63576ff8d880d577cf3fc48f + react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + checksum: 10c0/8bbebf52b063f2e705eb27364f08ec2eff987b9e8d28d82a28248652dd89ef53cb514e1f2ee1cbc6ac6e083a8dce86310301c3e92a99902b98c32a26381202d7 languageName: node linkType: hard @@ -13029,30 +13573,30 @@ __metadata: languageName: node linkType: hard -"vite-node@npm:3.0.7": - version: 3.0.7 - resolution: "vite-node@npm:3.0.7" +"vite-node@npm:3.1.4": + version: 3.1.4 + resolution: "vite-node@npm:3.1.4" dependencies: cac: "npm:^6.7.14" debug: "npm:^4.4.0" - es-module-lexer: "npm:^1.6.0" + es-module-lexer: "npm:^1.7.0" pathe: "npm:^2.0.3" vite: "npm:^5.0.0 || ^6.0.0" bin: vite-node: vite-node.mjs - checksum: 10c0/caaebe014ad1b795c4c1c0adcb36bc78c9d34f1d43966526cd0cb41dc3aae717dc7a746c369006bfe8f30be54e7f3ce562aa86d38201ec79e4fad41f45b1edb2 + checksum: 10c0/2fc71ddadd308b19b0d0dc09f5b9a108ea9bb640ec5fbd6179267994da8fd6c9d6a4c92098af7de73a0fa817055b518b28972452a2f19a1be754e79947e289d2 languageName: node linkType: hard -"vite-plugin-generate-file@npm:^0.2.0": - version: 0.2.0 - resolution: "vite-plugin-generate-file@npm:0.2.0" +"vite-plugin-generate-file@npm:^0.3.0": + version: 0.3.1 + resolution: "vite-plugin-generate-file@npm:0.3.1" dependencies: ejs: "npm:^3.1.9" js-yaml: "npm:^4.1.0" mime-types: "npm:^2.1.35" picocolors: "npm:^1.0.0" - checksum: 10c0/21bd598c66da2d2fc9e739f36abbdcfcf0dfc76801314956b26fac133bac7d758a241e11849d8ff879e3f907d48264710489798457118fef45c59a2935037a07 + checksum: 10c0/c2ca100c64c0620766bfcf5fe281202e7110ba5cc0651f4ac19de7b6bcd9aa2bda1c6590190101859ba1b0a54d3c6a05d4780a5c545c0b81fdcc2975adcebfc9 languageName: node linkType: hard @@ -13092,13 +13636,16 @@ __metadata: linkType: hard "vite@npm:^5.0.0 || ^6.0.0, vite@npm:^6.0.0": - version: 6.2.6 - resolution: "vite@npm:6.2.6" + version: 6.3.5 + resolution: "vite@npm:6.3.5" dependencies: esbuild: "npm:^0.25.0" + fdir: "npm:^6.4.4" fsevents: "npm:~2.3.3" + picomatch: "npm:^4.0.2" postcss: "npm:^8.5.3" - rollup: "npm:^4.30.1" + rollup: "npm:^4.34.9" + tinyglobby: "npm:^0.2.13" peerDependencies: "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 jiti: ">=1.21.0" @@ -13139,7 +13686,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/68a2ed3e61bdd654c59b817b4f3203065241c66d1739faa707499130f3007bc3a666c7a8320a4198e275e62b5e4d34d9b78a6533f69e321d366e76f5093b2071 + checksum: 10c0/df70201659085133abffc6b88dcdb8a57ef35f742a01311fc56a4cfcda6a404202860729cc65a2c401a724f6e25f9ab40ce4339ed4946f550541531ced6fe41c languageName: node linkType: hard @@ -13158,35 +13705,36 @@ __metadata: linkType: hard "vitest@npm:^3.0.0": - version: 3.0.7 - resolution: "vitest@npm:3.0.7" + version: 3.1.4 + resolution: "vitest@npm:3.1.4" dependencies: - "@vitest/expect": "npm:3.0.7" - "@vitest/mocker": "npm:3.0.7" - "@vitest/pretty-format": "npm:^3.0.7" - "@vitest/runner": "npm:3.0.7" - "@vitest/snapshot": "npm:3.0.7" - "@vitest/spy": "npm:3.0.7" - "@vitest/utils": "npm:3.0.7" + "@vitest/expect": "npm:3.1.4" + "@vitest/mocker": "npm:3.1.4" + "@vitest/pretty-format": "npm:^3.1.4" + "@vitest/runner": "npm:3.1.4" + "@vitest/snapshot": "npm:3.1.4" + "@vitest/spy": "npm:3.1.4" + "@vitest/utils": "npm:3.1.4" chai: "npm:^5.2.0" debug: "npm:^4.4.0" - expect-type: "npm:^1.1.0" + expect-type: "npm:^1.2.1" magic-string: "npm:^0.30.17" pathe: "npm:^2.0.3" - std-env: "npm:^3.8.0" + std-env: "npm:^3.9.0" tinybench: "npm:^2.9.0" tinyexec: "npm:^0.3.2" + tinyglobby: "npm:^0.2.13" tinypool: "npm:^1.0.2" tinyrainbow: "npm:^2.0.0" vite: "npm:^5.0.0 || ^6.0.0" - vite-node: "npm:3.0.7" + vite-node: "npm:3.1.4" why-is-node-running: "npm:^2.3.0" peerDependencies: "@edge-runtime/vm": "*" "@types/debug": ^4.1.12 "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 - "@vitest/browser": 3.0.7 - "@vitest/ui": 3.0.7 + "@vitest/browser": 3.1.4 + "@vitest/ui": 3.1.4 happy-dom: "*" jsdom: "*" peerDependenciesMeta: @@ -13206,7 +13754,7 @@ __metadata: optional: true bin: vitest: vitest.mjs - checksum: 10c0/79075fdb493771bebe45df8cd88ab872cdaceca31420977dea43d8792fd308278a9274645220e12c24373f1e91a8848b41cedebef15fd5b538c0ea9660f42de3 + checksum: 10c0/aec575e3cc6cf9b3cee224ae63569479e3a41fa980e495a73d384e31e273f34b18317a0da23bbd577c60fe5e717fa41cdc390de4049ce224ffdaa266ea0cdc67 languageName: node linkType: hard @@ -13238,12 +13786,10 @@ __metadata: languageName: node linkType: hard -"wcwidth@npm:^1.0.1": - version: 1.0.1 - resolution: "wcwidth@npm:1.0.1" - dependencies: - defaults: "npm:^1.0.3" - checksum: 10c0/5b61ca583a95e2dd85d7078400190efd452e05751a64accb8c06ce4db65d7e0b0cde9917d705e826a2e05cc2548f61efde115ffa374c3e436d04be45c889e5b4 +"walk-up-path@npm:^3.0.1": + version: 3.0.1 + resolution: "walk-up-path@npm:3.0.1" + checksum: 10c0/3184738e0cf33698dd58b0ee4418285b9c811e58698f52c1f025435a85c25cbc5a63fee599f1a79cb29ca7ef09a44ec9417b16bfd906b1a37c305f7aa20ee5bc languageName: node linkType: hard @@ -13324,13 +13870,13 @@ __metadata: languageName: node linkType: hard -"whatwg-url@npm:^14.1.0": - version: 14.1.0 - resolution: "whatwg-url@npm:14.1.0" +"whatwg-url@npm:^14.1.1": + version: 14.2.0 + resolution: "whatwg-url@npm:14.2.0" dependencies: - tr46: "npm:^5.0.0" + tr46: "npm:^5.1.0" webidl-conversions: "npm:^7.0.0" - checksum: 10c0/f00104f1c67ce086ba8ffedab529cbbd9aefd8c0a6555320026de7aeff31f91c38680f95818b140a7c9cc657cde3781e567835dda552ddb1e2b8faaba0ac3cb6 + checksum: 10c0/f746fc2f4c906607d09537de1227b13f9494c171141e5427ed7d2c0dd0b6a48b43d8e71abaae57d368d0c06b673fd8ec63550b32ad5ed64990c7b0266c2b4272 languageName: node linkType: hard