diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 90edafe64..3b32b8db0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,10 +3,19 @@ updates: - package-ecosystem: "npm" directory: "/" schedule: - interval: "daily" - target-branch: "develop" + interval: "weekly" + target-branch: "develop" + # Ignore all patch updates (e.g. 1.0.1 -> 1.0.2) + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-patch"] + - package-ecosystem: "npm" directory: "/" schedule: - interval: "daily" - target-branch: "main" \ No newline at end of file + interval: "weekly" + target-branch: "main" + # Ignore all patch updates (e.g. 1.0.1 -> 1.0.2) + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-patch"] diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2594970f7..2564f79db 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -10,238 +10,77 @@ on: workflow_dispatch: inputs: rebuild-backend: - description: Build backend binaries + description: Force rebuild backend type: boolean - default: true - rebuild-control-station: - description: Build control station frontend + default: false + rebuild-testing-view: + description: Force rebuild testing-view type: boolean - default: true - rebuild-ethernet-view: - description: Build ethernet view frontend + default: false + rebuild-competition-view: + description: Force rebuild competition-view type: boolean - default: true - workflow_call: - inputs: - build-backend: - description: Build backend binaries - type: boolean - default: true - required: false - build-control-station: - description: Build control station frontend - type: boolean - default: true - required: false - build-ethernet-view: - description: Build ethernet view frontend - type: boolean - default: true - required: false + default: false + # workflow_call: + # inputs: + # build-backend: + # description: Build backend binaries + # type: boolean + # default: false + # required: false + # build-testing-view: + # description: Build testing-view + # type: boolean + # default: false + # required: false + # build-competition-view: + # description: Build competition-view + # type: boolean + # default: false + # required: false jobs: - # Detect what changed + # ------------------------------------------------------------------ + # 1. DETECT CHANGES + # Checks which parts of the codebase changed to avoid unnecessary builds + # ------------------------------------------------------------------ detect-changes: name: Detect Changes runs-on: ubuntu-latest - # We can't use this condition here because it would skip the whole job without setting the outputs - # if: github.event_name == 'push' || github.event_name == 'pull_request' - # Insted, we skip steps inside the job outputs: - backend_needs_rebuild: ${{ steps.changes.outputs.backend_any_changed == 'true' || github.event.inputs.rebuild-backend == 'true' }} - control-station_needs_rebuild: ${{ steps.changes.outputs.control-station_any_changed == 'true' || github.event.inputs.rebuild-control-station == 'true' }} - ethernet-view_needs_rebuild: ${{ steps.changes.outputs.ethernet-view_any_changed == 'true' || github.event.inputs.rebuild-ethernet-view == 'true' }} - common-front_needs_rebuild: ${{ steps.changes.outputs.common-front_any_changed == 'true' || github.event.inputs.rebuild-common-front == 'true' }} + backend: ${{ steps.filter.outputs.backend == 'true' || github.event.inputs.rebuild-backend == 'true' || inputs.build-backend == true }} + testing-view: ${{ steps.filter.outputs.testing-view == 'true' || github.event.inputs.rebuild-testing-view == 'true' || inputs.build-testing-view == true }} + competition-view: ${{ steps.filter.outputs.competition-view == 'true' || github.event.inputs.rebuild-competition-view == 'true' || inputs.build-competition-view == true }} steps: - # Only run on push or pull request events - # Skip on workflow_call or workflow_dispatch - - name: Checkout repository - if: github.event_name == 'push' || github.event_name == 'pull_request' - uses: actions/checkout@v4 - with: - fetch-depth: 0 + - uses: actions/checkout@v4 - # Only run on push or pull request events - # Skip on workflow_call or workflow_dispatch - - name: Detect changed files - if: github.event_name == 'push' || github.event_name == 'pull_request' - id: changes - uses: tj-actions/changed-files@v41 + - uses: dorny/paths-filter@v3 + id: filter with: - files_yaml: | + ref: "production" + filters: | backend: - 'backend/**/*' - control-station: - - 'control-station/**/*' - ethernet-view: - - 'ethernet-view/**/*' - common-front: - - 'common-front/**/*' - - # We want to set outputs even if the job should be skipped - - name: Set outputs - id: set-outputs - run: | - if [ "${{ github.event_name }}" = "push" ] || [ "${{ github.event_name }}" = "pull_request" ]; then - echo "backend_needs_rebuild=${{ steps.changes.outputs.backend_any_changed == 'true' && 'true' || 'false' }}" >> $GITHUB_OUTPUT - echo "control-station_needs_rebuild=${{ steps.changes.outputs.control-station_any_changed == 'true' || steps.changes.outputs.common-front_any_changed == 'true' && 'true' || 'false' }}" >> $GITHUB_OUTPUT - echo "ethernet-view_needs_rebuild=${{ steps.changes.outputs.ethernet-view_any_changed == 'true' || steps.changes.outputs.common-front_any_changed == 'true' && 'true' || 'false' }}" >> $GITHUB_OUTPUT - echo "common-front_needs_rebuild=${{ steps.changes.outputs.common-front_any_changed == 'true' && 'true' || 'false' }}" >> $GITHUB_OUTPUT - else - # On workflow_call/dispatch, default to false (no changes detected) - echo "backend_needs_rebuild=false" >> $GITHUB_OUTPUT - echo "control-station_needs_rebuild=false" >> $GITHUB_OUTPUT - echo "ethernet-view_needs_rebuild=false" >> $GITHUB_OUTPUT - echo "common-front_needs_rebuild=false" >> $GITHUB_OUTPUT - fi - - - name: Debug changed files - if: github.event_name == 'push' || github.event_name == 'pull_request' - run: | - echo "Changed backend: ${{ steps.changes.outputs.backend_any_changed }}" - echo "Changed control-station: ${{ steps.changes.outputs.control-station_any_changed }}" - echo "Changed ethernet-view: ${{ steps.changes.outputs.ethernet-view_any_changed }}" - echo "Changed common-front: ${{ steps.changes.outputs.common-front_any_changed }}" - - # Download backend from previous build if no changes - download-backend: - name: Download Backend - ${{ matrix.platform }} - needs: detect-changes - # It is important to use != 'true' and not == 'false' because if they are no inputs (executed on push or pull request events), - # values for inputs will be undefined which gives false for any condition - # The same thing applies for detect changes outputs, because we skip this job on dispatch and call events - # Thus, it's outputs are undefined - if: | - needs.detect-changes.outputs.backend_needs_rebuild != 'true' && - inputs.build-backend != 'true' - runs-on: ubuntu-latest - # Continue on error is necessary because download-backend job can fail if backend artifact is not found - # and in this case it is not necessarily has to fail the build - continue-on-error: true - outputs: - downloaded: ${{ steps.download.outcome == 'success' }} - strategy: - fail-fast: false - matrix: - platform: [linux, windows, macos-intel, macos-arm64] - - steps: - - name: Download backend from latest build - id: download - uses: dawidd6/action-download-artifact@v3 - with: - workflow: build.yaml - branch: production - workflow_conclusion: "completed" - name: backend-${{ matrix.platform }} - path: backend-artifacts - if_no_artifact_found: fail - - - name: Re-upload backend artifact - if: steps.download.outcome == 'success' - uses: actions/upload-artifact@v4 - with: - name: backend-${{ matrix.platform }} - path: backend-artifacts/* - retention-days: 30 - - - name: Write matrix output - if: always() - uses: cloudposse/github-action-matrix-outputs-write@v1 - with: - matrix-step-name: download-backend - matrix-key: ${{ matrix.platform }} - outputs: | - downloaded: ${{ steps.download.outcome == 'success' }} - - # Aggregate download results - aggregate-downloads: - name: Aggregate Download Results - # Always run to ensure outputs are always available - if: always() - needs: [detect-changes, download-backend] - runs-on: ubuntu-latest - steps: - - name: Set defaults if backend changed - id: set-defaults - run: | - # If backend changed or build-backend is explicitly requested, set defaults and skip aggregation - if [ "${{ needs.detect-changes.outputs.backend_needs_rebuild }}" = "true" ] || [ "${{ inputs.build-backend }}" = "true" ]; then - echo "any_needs_rebuild=false" >> $GITHUB_OUTPUT - echo 'result={"downloaded":{"linux":false,"windows":false,"macos-intel":false,"macos-arm64":false}}' >> $GITHUB_OUTPUT - echo "Backend changed or build requested, using defaults" - fi - shell: bash - - - uses: cloudposse/github-action-matrix-outputs-read@v1 - id: read - if: needs.detect-changes.outputs.backend_needs_rebuild != 'true' && inputs.build-backend != 'true' - with: - matrix-step-name: download-backend - - - name: Check if any platform needs rebuild - if: needs.detect-changes.outputs.backend_needs_rebuild != 'true' && inputs.build-backend != 'true' - id: check-rebuild - run: | - # Parse the result JSON to check if any download failed - RESULT='${{ steps.read.outputs.result }}' - echo "Parsing result: $RESULT" - - # Check if any platform has downloaded=false - # The result format is: {downloaded:{linux:true,windows:false,...}} - if echo "$RESULT" | grep -q '"downloaded".*"linux":false' || \ - echo "$RESULT" | grep -q '"downloaded".*"windows":false' || \ - echo "$RESULT" | grep -q '"downloaded".*"macos-intel":false' || \ - echo "$RESULT" | grep -q '"downloaded".*"macos-arm64":false'; then - echo "any_needs_rebuild=true" >> $GITHUB_OUTPUT - echo "At least one platform download failed, rebuild needed" - else - echo "any_needs_rebuild=false" >> $GITHUB_OUTPUT - echo "All platform downloads succeeded, no rebuild needed" - fi - shell: bash - - - name: Debug aggregate-downloads outputs - if: always() - run: | - echo "=== aggregate-downloads Debug ===" - echo "inputs.build-backend: ${{ inputs.build-backend }}" - echo "" - echo "=== detect-changes outputs ===" - echo "needs.detect-changes.outputs.backend_needs_rebuild: ${{ needs.detect-changes.outputs.backend_needs_rebuild }}" - echo "needs.detect-changes.outcome: ${{ needs.detect-changes.outcome }}" - echo "" - echo "=== aggregate-downloads Debug ===" - echo "steps.read.outputs.result: ${{ steps.read.outputs.result }}" - echo "steps.read.outcome: ${{ steps.read.outcome }}" - echo "" - echo "=== All read outputs ===" - echo "${{ toJSON(steps.read.outputs) }}" - echo "" - echo "=== download-backend outcomes ===" - echo "needs.download-backend.outcome: ${{ needs.download-backend.outcome }}" - outputs: - outcome: ${{ steps.read.outcome != '' && steps.read.outcome || 'skipped' }} - any_needs_rebuild: ${{ steps.check-rebuild.outputs.any_needs_rebuild != '' && steps.check-rebuild.outputs.any_needs_rebuild || steps.set-defaults.outputs.any_needs_rebuild || 'false' }} - result: ${{ steps.read.outputs.result != '' && steps.read.outputs.result || steps.set-defaults.outputs.result || '{"downloaded":{"linux":false,"windows":false,"macos-intel":false,"macos-arm64":false}}' }} - - # Build Go backends on native platforms - # only if backend changed or download-backend failed + - 'go.work' + - 'go.work.sum' + testing-view: + - 'frontend/testing-view/**/*' + - 'frontend/frontend-kit/**/*' # Shared lib dependency + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + competition-view: + - 'frontend/competition-view/**/*' + - 'frontend/frontend-kit/**/*' # Shared lib dependency + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + + # ------------------------------------------------------------------ + # 2. BUILD BACKEND (MATRIX) + # Builds Go binaries for Linux, Windows, and macOS (Intel & Arm) + # ------------------------------------------------------------------ build-backend: - name: Build Backend - ${{ matrix.platform }} - needs: [detect-changes, download-backend, aggregate-downloads] - # Always is needed to execute this job even if backend download failed - # By default it would be skipped because dependent job failed - # Build if explicitly requested for this platform - # Also build if backend changed or download-backend failed - if: | - always() && - ( - inputs.build-backend == true || - needs.detect-changes.outputs.backend_needs_rebuild == 'true' || - needs.aggregate-downloads.outputs.outcome == 'success' && - needs.aggregate-downloads.outputs.any_needs_rebuild == 'true' - ) + name: Backend - ${{ matrix.platform }} + needs: detect-changes runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -249,253 +88,124 @@ jobs: include: - os: ubuntu-latest platform: linux - binary_name: backend-linux-amd64 - + binary: backend-linux-amd64 + goarch: amd64 - os: windows-latest platform: windows - binary_name: backend-windows-amd64.exe - + binary: backend-windows-amd64.exe + goarch: amd64 - os: macos-latest platform: macos-intel - binary_name: backend-darwin-amd64 + binary: backend-darwin-amd64 goarch: amd64 - - os: macos-latest platform: macos-arm64 - binary_name: backend-darwin-arm64 + binary: backend-darwin-arm64 goarch: arm64 - steps: - - name: Debug - run: | - echo "=== aggregate-downloads Debug ===" - echo "needs.aggregate-downloads.outputs.result: ${{ needs.aggregate-downloads.outputs.result }}" - echo "needs.aggregate-downloads.outputs.result.downloaded: ${{ fromJSON(needs.aggregate-downloads.outputs.result).downloaded }}" - echo "needs.aggregate-downloads.outputs.result.downloaded.platform: ${{ fromJSON(needs.aggregate-downloads.outputs.result).downloaded[matrix.platform] }}" - - - name: Check if artifact exists for this platform - id: check-artifact - shell: bash - run: | - ARTIFACT_EXISTS="${{ fromJSON(needs.aggregate-downloads.outputs.result).downloaded[matrix.platform] }}" - BUILD_EXPLICITLY="${{ inputs.build-backend == true }}" - CHANGES_DETECTED="${{ needs.detect-changes.outputs.backend_needs_rebuild == 'true' }}" - - if [ "$ARTIFACT_EXISTS" != "true" ] || [ "$BUILD_EXPLICITLY" = "true" ] || [ "$CHANGES_DETECTED" = "true" ]; then - echo "needs_build=true" >> $GITHUB_OUTPUT - echo "Building for ${{ matrix.platform }}" - else - echo "needs_build=false" >> $GITHUB_OUTPUT - echo "Artifact exists for ${{ matrix.platform }}, skipping build" - fi - - - name: Exit if no build needed - if: steps.check-artifact.outputs.needs_build != 'true' - shell: bash - run: | - echo "Skipping build - artifact already exists" + # OPTIMIZATION: Try to download existing artifact first + # Only runs if NO changes were detected and NO rebuild was forced + - name: Try Download Cache + if: needs.detect-changes.outputs.backend != 'true' + id: download + uses: dawidd6/action-download-artifact@v3 + continue-on-error: true + with: + workflow: build.yaml + branch: production + workflow_conclusion: success + name: backend-${{ matrix.platform }} + path: backend/cmd - - name: Checkout repository - if: steps.check-artifact.outputs.needs_build == 'true' - uses: actions/checkout@v4 + # BUILD: Only runs if download failed OR changes detected + - uses: actions/checkout@v4 + if: steps.download.outcome != 'success' - - name: Setup Go - if: steps.check-artifact.outputs.needs_build == 'true' - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 + if: steps.download.outcome != 'success' with: - go-version: "1.21" + go-version: "1.23" - - name: Install Linux dependencies - if: runner.os == 'Linux' && steps.check-artifact.outputs.needs_build == 'true' + - name: Install Linux Deps + if: runner.os == 'Linux' && steps.download.outcome != 'success' run: sudo apt-get update && sudo apt-get install -y libpcap-dev gcc - - name: Install macOS dependencies - if: runner.os == 'macOS' && steps.check-artifact.outputs.needs_build == 'true' + - name: Install macOS Deps + if: runner.os == 'macOS' && steps.download.outcome != 'success' run: brew install libpcap - - name: Build backend (Linux) - if: runner.os == 'Linux' && steps.check-artifact.outputs.needs_build == 'true' - working-directory: backend/cmd - run: | - CGO_ENABLED=1 go build -o ${{ matrix.binary_name }} . - - - name: Build backend (Windows) - if: runner.os == 'Windows' && steps.check-artifact.outputs.needs_build == 'true' - working-directory: backend/cmd - run: | - $env:CGO_ENABLED="1" - go build -o ${{ matrix.binary_name }} . - shell: pwsh - - - name: Build backend (macOS) - if: runner.os == 'macOS' && steps.check-artifact.outputs.needs_build == 'true' + - name: Build Binary + if: steps.download.outcome != 'success' working-directory: backend/cmd + shell: bash run: | - CGO_ENABLED=1 GOARCH=${{ matrix.goarch }} go build -o ${{ matrix.binary_name }} . + go build -o ${{ matrix.binary }} . + env: + CGO_ENABLED: 1 + GOARCH: ${{ matrix.goarch }} - - name: Upload backend binary - if: steps.check-artifact.outputs.needs_build == 'true' - uses: actions/upload-artifact@v4 + # UPLOAD: Always runs to ensure artifact availability for release + - uses: actions/upload-artifact@v4 with: name: backend-${{ matrix.platform }} - path: backend/cmd/${{ matrix.binary_name }} + path: backend/cmd/${{ matrix.binary }} retention-days: 30 - # Download control-station from previous build if no changes - download-control-station: - name: Download Control Station + # ------------------------------------------------------------------ + # 3. BUILD FRONTEND (MATRIX) + # Builds Testing View and Competition View using pnpm & turbo + # ------------------------------------------------------------------ + build-frontend: + name: Build ${{ matrix.view }} needs: detect-changes - # The condition checks if control station changed or common front changed - # It is important to use != 'true' and not == 'false' because if they are no inputs (executed on push or pull request events), - # values for inputs will be undefined which gives false for any condition - # The same thing applies for detect changes outputs, because we skip this job on dispatch and call events - # Thus, it's outputs are undefined - if: | - needs.detect-changes.outputs.control-station_needs_rebuild != 'true' && - needs.detect-changes.outputs.common-front_needs_rebuild != 'true' && - inputs.build-control-station != 'true' runs-on: ubuntu-latest - # Continue on error is necessary because download-control-station job can fail if control station artifact is not found - # and it is not necessary to fail the build in this case - continue-on-error: true - outputs: - downloaded: ${{ steps.download.outcome == 'success' }} + strategy: + fail-fast: false + matrix: + view: [testing-view, + # competition-view] # TODO: Uncomment when competition view is ready + ] steps: - - name: Download control-station from latest build + # OPTIMIZATION: Try to download existing artifact first + # Only runs if NO changes were detected and NO rebuild was forced + - name: Try Download Cache + if: needs.detect-changes.outputs[matrix.view] != 'true' id: download uses: dawidd6/action-download-artifact@v3 + continue-on-error: true with: workflow: build.yaml branch: production - workflow_conclusion: "completed" - name: control-station - path: control-station-artifacts - if_no_artifact_found: fail + workflow_conclusion: success + name: ${{ matrix.view }} + path: frontend/${{ matrix.view }}/dist - - name: Re-upload control-station artifact - if: steps.download.outcome == 'success' - uses: actions/upload-artifact@v4 - with: - name: control-station - path: control-station-artifacts/** - retention-days: 30 + # BUILD: Only runs if download failed OR changes detected + - uses: actions/checkout@v4 + if: steps.download.outcome != 'success' - # Build control-station (if control-station or common-front changed) - build-control-station: - name: Build Control Station - needs: [detect-changes, download-control-station] - # Always is needed to execute this job even if control station download failed - # By default it would be skipped because dependent job failed - # The condition checks if control station changed or common front changed or download control station failed - if: always() && - (needs.detect-changes.outputs.control-station_needs_rebuild == 'true' || - needs.detect-changes.outputs.common-front_needs_rebuild == 'true' || - needs.download-control-station.outputs.downloaded != 'true' || - inputs.build-control-station == 'true') - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - - - name: Build common-front - working-directory: common-front - run: | - npm ci - npm run build - - - name: Build control-station - working-directory: control-station - run: | - npm ci - npm run build - - - name: Upload control-station artifact - uses: actions/upload-artifact@v4 - with: - name: control-station - path: control-station/static/** - retention-days: 30 - - # Download ethernet-view from previous build if no changes - download-ethernet-view: - name: Download Ethernet View - needs: detect-changes - # It is important to use != 'true' and not == 'false' because if they are no inputs (executed on push or pull request events), - # values for inputs will be undefined which gives false for any condition - # The same thing applies for detect changes outputs, because we skip this job on dispatch and call events - # Thus, it's outputs are undefined - if: | - needs.detect-changes.outputs.ethernet-view_needs_rebuild != 'true' && - needs.detect-changes.outputs.common-front_needs_rebuild != 'true' && - inputs.build-ethernet-view != 'true' - runs-on: ubuntu-latest - # Continue on error is necessary because download-ethernet-view job can fail if ethernet view artifact is not found - # and it is not necessary to fail the build in this case - continue-on-error: true - outputs: - downloaded: ${{ steps.download.outcome == 'success' }} - steps: - - name: Download ethernet-view from latest build - id: download - uses: dawidd6/action-download-artifact@v3 + - uses: pnpm/action-setup@v4 + if: steps.download.outcome != 'success' with: - workflow: build.yaml - branch: production - workflow_conclusion: "completed" - name: ethernet-view - path: ethernet-view-artifacts - if_no_artifact_found: fail + version: 10.26.0 - - name: Re-upload ethernet-view artifact - if: steps.download.outcome == 'success' - uses: actions/upload-artifact@v4 + - uses: actions/setup-node@v4 + if: steps.download.outcome != 'success' with: - name: ethernet-view - path: ethernet-view-artifacts/** - retention-days: 30 + node-version: 20 + cache: "pnpm" - # Build ethernet-view (if ethernet-view or common-front changed) - build-ethernet-view: - name: Build Ethernet View - needs: [detect-changes, download-ethernet-view] - # Always is needed to execute this job even if ethernet view download failed - # By default it would be skipped because dependent job failed - # The condition checks if ethernet view changed or common front changed or download ethernet view failed - if: always() && - (needs.detect-changes.outputs.ethernet-view_needs_rebuild == 'true' || - needs.detect-changes.outputs.common-front_needs_rebuild == 'true' || - needs.download-ethernet-view.outputs.downloaded != 'true' || - inputs.build-ethernet-view == 'true') - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" + - name: Install Dependencies + if: steps.download.outcome != 'success' + run: pnpm install --frozen-lockfile - - name: Build common-front - working-directory: common-front - run: | - npm ci - npm run build - - - name: Build ethernet-view - working-directory: ethernet-view - run: | - npm ci - npm run build + - name: Build with Turbo + if: steps.download.outcome != 'success' + run: pnpm turbo build --filter=${{ matrix.view }} - - name: Upload ethernet-view artifact - uses: actions/upload-artifact@v4 + # UPLOAD: Always runs to ensure artifact availability for release + - uses: actions/upload-artifact@v4 with: - name: ethernet-view - path: ethernet-view/static/** + name: ${{ matrix.view }} + path: frontend/${{ matrix.view }}/dist/** retention-days: 30 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 09ced9df5..abcc3c225 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -67,17 +67,22 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10.26.0 + - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" + cache: "pnpm" # Update package.json with release version - name: Update version in package.json working-directory: electron-app shell: bash run: | - npm version ${{ needs.determine-version.outputs.version }} --no-git-tag-version + pnpm version ${{ needs.determine-version.outputs.version }} --no-git-tag-version echo "Updated version to:" cat package.json | grep version @@ -123,23 +128,24 @@ jobs: path: electron-app/binaries # Download frontend builds from latest build - - name: Download control-station - uses: dawidd6/action-download-artifact@v3 - with: - workflow: build.yaml - branch: production - workflow_conclusion: success - name: control-station - path: electron-app/renderer/control-station - - - name: Download ethernet-view + # TODO: Uncomment when competition view is ready + # - name: Download competition-view + # uses: dawidd6/action-download-artifact@v3 + # with: + # workflow: build.yaml + # branch: production + # workflow_conclusion: success + # name: competition-view + # path: electron-app/renderer/competition-view + + - name: Download testing-view uses: dawidd6/action-download-artifact@v3 with: workflow: build.yaml branch: production workflow_conclusion: success - name: ethernet-view - path: electron-app/renderer/ethernet-view + name: testing-view + path: electron-app/renderer/testing-view - name: Set executable permissions (Unix) if: runner.os != 'Windows' @@ -147,11 +153,11 @@ jobs: - name: Install Electron dependencies working-directory: electron-app - run: npm ci + run: pnpm install - name: Build Electron distribution working-directory: electron-app - run: npm run dist + run: pnpm run dist env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} CSC_IDENTITY_AUTO_DISCOVERY: false @@ -178,6 +184,8 @@ jobs: electron-app/dist/*.deb electron-app/dist/*.dmg electron-app/dist/*.zip + electron-app/dist/*.yml + electron-app/dist/*.blockmap !electron-app/dist/*-unpacked !electron-app/dist/mac !electron-app/dist/win-unpacked diff --git a/backend/package.json b/backend/package.json index e433c7772..942b86567 100644 --- a/backend/package.json +++ b/backend/package.json @@ -8,6 +8,7 @@ "dev": "go run ./cmd --config ./cmd/dev-config.toml", "dev:main": "go run ./cmd --config ./cmd/config.toml", "build": "go build -o bin/backend ./cmd", + "build:ci": "go build", "test": "go test ./..." } } diff --git a/electron-app/BUILD.md b/electron-app/BUILD.md new file mode 100644 index 000000000..855ba3ff2 --- /dev/null +++ b/electron-app/BUILD.md @@ -0,0 +1,71 @@ +# Hyperloop Control Station Build System + +The project uses a unified, modular build script (`electron-app/build.mjs`) to handle building the backend (Go), packet sender (Rust), and frontends (React/Vite) for the Electron application. + +## Prerequisites + +- **Node.js** & **pnpm** +- **Go** (1.21+) +- **Rust/Cargo** (for Packet Sender) + +## Basic Usage + +Run the build script from the `electron-app` directory (or via npm scripts). + +```sh +# Build EVERYTHING (Backend, Packet Sender, Frontends) +pnpm build + +# OR +node build.mjs +``` + +## Configuration + +The build configuration is defined in `electron-app/build.mjs` within the `CONFIG` object. + +## Build Specific Components + +You can build individual components by passing their flag. + +```sh +# Build only the Backend +node build.mjs --backend + +# Build only the Testing View +node build.mjs --testing-view + +# Build only the Packet Sender +node build.mjs --packet-sender +``` + +## Platform Targeting + +By default, the script builds for all defined platforms (Windows, Linux, macOS). You can limit this using flags. + +```sh +# Build backend for Windows only +node build.mjs --backend --win + +# Build everything for Linux +node build.mjs --linux +``` + +## Advanced: Overwriting Commands + +The build script allows you to override configuration properties on the fly. This is useful for CI pipelines where you might want to use different build commands or flags. + +**Syntax**: `--[target].[property]="value"` + +### Examples + +```sh +# Use a custom build command for the backend: +node build.mjs --backend --backend.commands="pnpm run build:prod --" + +# Change the output directory +node build.mjs --backend --backend.output="./dist/bin" + +# Pass arguments to the underlying tools (passes -v) +node build.mjs --backend -- -v +``` diff --git a/electron-app/app-update.yml b/electron-app/app-update.yml new file mode 100644 index 000000000..27ef92e02 --- /dev/null +++ b/electron-app/app-update.yml @@ -0,0 +1,4 @@ +provider: github +owner: Hyperloop-UPV +repo: software +updaterCacheDirName: hyperloop-control-station/updater diff --git a/electron-app/build.mjs b/electron-app/build.mjs index 17fa0dfe2..f83964a19 100644 --- a/electron-app/build.mjs +++ b/electron-app/build.mjs @@ -1,285 +1,280 @@ #!/usr/bin/env node /** * @file build.mjs - * @description Build script for the Hyperloop Control Station Electron application. - * Handles building backend binaries, frontend applications, and managing build artifacts. + * @description Modular build script for Hyperloop Control Station */ import { execSync } from "child_process"; -import { mkdirSync, rmSync, cpSync } from "fs"; -import { join, dirname } from "path"; +import { copyFileSync, cpSync, existsSync, mkdirSync, rmSync } from "fs"; +import { dirname, join } from "path"; import { fileURLToPath } from "url"; import { logger } from "./src/utils/logger.js"; -import { colors } from "./src/utils/colors.js"; -// Get current directory path +// --- Configuration --- + const __dirname = dirname(fileURLToPath(import.meta.url)); -// Get project root directory (parent of electron-app) -const root = dirname(__dirname); +const ROOT = dirname(__dirname); -/** - * Executes a shell command synchronously with error handling. - * @param {string} cmd - The command to execute. - * @param {string} [cwd=root] - Working directory for the command. - * @param {Object} [env={}] - Additional environment variables to set. - * @returns {boolean} True if command succeeded, false otherwise. - * @example - * const success = run("npm install", "/path/to/project"); - * run("go build", backendDir, { GOOS: "windows", GOARCH: "amd64" }); - */ -const run = (cmd, cwd = root, env = {}) => { +const CONFIG = { + backend: { + type: "go", + path: join(ROOT, "backend"), // Root of backend (where package.json is) + output: join(__dirname, "binaries"), + commands: ["pnpm run build:ci"], + platforms: [ + { + id: "win64", + goos: "windows", + goarch: "amd64", + ext: ".exe", + tags: ["win", "windows"], + }, + { + id: "linux64", + goos: "linux", + goarch: "amd64", + ext: "", + tags: ["linux"], + }, + { + id: "mac64", + goos: "darwin", + goarch: "amd64", + ext: "", + tags: ["mac", "macos"], + }, + { + id: "macArm", + goos: "darwin", + goarch: "arm64", + ext: "", + tags: ["mac", "macos"], + }, + ], + }, + "packet-sender": { + type: "rust", + path: join(ROOT, "packet-sender"), + output: join(__dirname, "binaries"), + commands: ["pnpm run build"], + binaryPath: "target/release/packet-sender", + platforms: [ + { id: "win64", ext: ".exe", tags: ["win", "windows"] }, + { id: "linux64", ext: "", tags: ["linux"] }, + { id: "mac64", ext: "", tags: ["mac", "macos"] }, + ], + }, + "testing-view": { + type: "frontend", + path: join(ROOT, "frontend/testing-view"), + dest: join(__dirname, "renderer/testing-view"), + commands: [ + "pnpm --filter testing-view install --frozen-lockfile", + "pnpm run build", + ], + }, + "competition-view": { + type: "frontend", + path: join(ROOT, "frontend/competition-view"), + dest: join(__dirname, "renderer/competition-view"), + commands: [ + "pnpm --filter competition-view install --frozen-lockfile", + "pnpm run build", + ], + optional: true, + }, +}; + +// --- Helpers --- + +const run = (cmd, cwd, env = {}) => { try { - // Execute command with inherited stdio (shows output) - execSync(cmd, { - cwd, - stdio: "inherit", - shell: true, - // Merge process environment with provided env vars - env: { ...process.env, ...env }, - }); + const finalEnv = { ...process.env, ...env }; + execSync(cmd, { cwd, stdio: "inherit", shell: true, env: finalEnv }); return true; } catch (e) { - // Log warning if command fails (may need cross-compile tools) - logger.warning( - `${cmd.split(" ")[0]} failed (may need cross-compile tools)` - ); + logger.error(`Command failed: ${cmd}`); return false; } }; -// Parse command line arguments -const args = process.argv.slice(2); +const buildBackend = (config, requestedPlatforms, extraArgs = "") => { + logger.info("Building Backend (Go)..."); + mkdirSync(config.output, { recursive: true }); -// Show help message if requested -if (args.includes("--help") || args.includes("-h")) { - logger.info(` -${colors.bright}${colors.cyan}Hyperloop Control Station Build Script${colors.reset} - -${colors.bright}Usage:${colors.reset} - node build.mjs [options] - -${colors.bright}Options:${colors.reset} - ${colors.green}--platform${colors.reset} P Specify backend platform (windows, linux, mac, all) - ${colors.green}--backend${colors.reset} Build only backends - ${colors.green}--frontend${colors.reset} Build only frontends - ${colors.green}--common-front${colors.reset} Build common-front library - ${colors.green}--control-station${colors.reset} Build control-station frontend - ${colors.green}--ethernet-view${colors.reset} Build ethernet-view frontend - ${colors.green}--help, -h${colors.reset} Show this help message - -${colors.bright}Examples:${colors.reset} - node build.mjs ${colors.dim}# Build everything (all platforms)${colors.reset} - node build.mjs --platform windows ${colors.dim}# Build everything for Windows${colors.reset} - node build.mjs --backend ${colors.dim}# Build only backends (all platforms)${colors.reset} - node build.mjs --ethernet-view ${colors.dim}# Build only ethernet-view${colors.reset} - ${colors.brightYellow}For npm shortcuts, see package.json scripts section${colors.reset} -`); - process.exit(0); -} + const targets = config.platforms.filter((p) => { + if ( + !requestedPlatforms || + requestedPlatforms.length === 0 || + requestedPlatforms.includes("all") + ) + return true; + return p.tags.some((tag) => requestedPlatforms.includes(tag)); + }); -/** - * Gets the value of a command line argument flag. - * @param {string} flag - The flag to look for (e.g., "--platform"). - * @returns {string | null} The value after the flag, or null if not found. - * @example - * const platform = getArgValue("--platform"); - * // Returns "windows" if command was: node build.mjs --platform windows - */ -const getArgValue = (flag) => { - // Find index of the flag - const idx = args.findIndex((a) => a === flag); - // Return next argument if flag exists and has a value - return idx !== -1 && args[idx + 1] ? args[idx + 1] : null; -}; + if (targets.length === 0) { + logger.error( + `No matching platforms found for: ${requestedPlatforms.join(", ")}` + ); + return false; + } + + let success = true; + for (const p of targets) { + const filename = `backend-${p.goos}-${p.goarch}${p.ext}`; + logger.step(`Building ${p.goos}/${p.goarch}...`); + + for (const cmd of config.commands) { + // cmd is like "pnpm run build:ci --" + // We append the output flag and target directory + const buildCmd = `${cmd} -o "${join(config.output, filename)}" ${extraArgs} ./cmd`; -// Get platform argument value -const platformArg = getArgValue("--platform"); - -// Check if only --platform is specified (treat as build all for that platform) -const onlyPlatformSpecified = - platformArg && args.length === 2 && args[0] === "--platform"; - -// Determine what to build based on arguments -// Build everything if no args or only platform specified -const buildAll = args.length === 0 || onlyPlatformSpecified; -// Build only backend if --backend flag is present -const backendOnly = args.includes("--backend"); -// Build only frontend if --frontend flag is present -const frontendOnly = args.includes("--frontend"); -// Build common-front if explicitly requested, or if building frontend/all -const buildCommonFront = - args.includes("--common-front") || frontendOnly || (!backendOnly && buildAll); -// Build control-station if explicitly requested, or if building frontend/all -const buildControlStation = - args.includes("--control-station") || - frontendOnly || - (!backendOnly && buildAll); -// Build ethernet-view if explicitly requested, or if building frontend/all -const buildEthernetView = - args.includes("--ethernet-view") || - frontendOnly || - (!backendOnly && buildAll); -// Build backend if explicitly requested, or if building all, or if nothing else is being built -const buildBackend = - backendOnly || - (!frontendOnly && buildAll) || - (!buildCommonFront && !buildControlStation && !buildEthernetView); - -logger.header("🚀 Building Hyperloop Control Station"); - -// Setup: create necessary directories -mkdirSync(join(__dirname, "binaries"), { recursive: true }); -mkdirSync(join(__dirname, "renderer"), { recursive: true }); - -// Backend build section -if (buildBackend) { - logger.info("📦 Building backend..."); - // Path to backend source directory - const backendDir = join(root, "backend/cmd"); - // Path to binaries output directory - const binDir = join(__dirname, "binaries"); - - // Define all supported platforms for cross-compilation - const allPlatforms = [ - { - goos: "windows", - goarch: "amd64", - out: "backend-windows-amd64.exe", - name: "windows-amd64", - alias: "windows", - }, - { - goos: "linux", - goarch: "amd64", - out: "backend-linux-amd64", - name: "linux-amd64", - alias: "linux", - }, - { - goos: "darwin", - goarch: "amd64", - out: "backend-darwin-amd64", - name: "darwin-amd64", - alias: "mac", - }, - { - goos: "darwin", - goarch: "arm64", - out: "backend-darwin-arm64", - name: "darwin-arm64", - alias: "mac", - }, - ]; - - let platforms; - - // Filter platforms based on --platform argument - if (platformArg) { - if (platformArg === "all") { - // Build all platforms - platforms = allPlatforms; - } else { - // Filter to specific platform alias - platforms = allPlatforms.filter((p) => p.alias === platformArg); - // Error if platform not found - if (platforms.length === 0) { - logger.error(`Unknown platform: ${platformArg}`); - logger.error(`Available: windows, linux, mac, all`); - process.exit(1); + const result = run(buildCmd, config.path, { + GOOS: p.goos, + GOARCH: p.goarch, + CGO_ENABLED: "1", + }); + + if (!result) { + logger.warning(`Failed to build ${filename}`); + success = false; + break; } } + } + return success; +}; + +const buildRust = (name, config, requestedPlatforms, extraArgs = "") => { + logger.info(`Building ${name} (Rust)...`); + mkdirSync(config.output, { recursive: true }); + + for (const cmd of config.commands) { + // Only append extra args to build commands + const finalCmd = cmd.includes("build") ? `${cmd} ${extraArgs}` : cmd; + if (!run(finalCmd, config.path)) return false; + } + + const isWin = + process.platform === "win32" || + (requestedPlatforms && requestedPlatforms.includes("win")); + const ext = isWin ? ".exe" : ""; + + // Check for source binary + const sourceBin = join(config.path, config.binaryPath + ext); + const destName = `packet-sender${ext}`; + const destPath = join(config.output, destName); + + logger.step(`Copying binary to ${destPath}...`); + + if (existsSync(sourceBin)) { + copyFileSync(sourceBin, destPath); + return true; } else { - // Build all platforms if no platform specified - platforms = allPlatforms; + logger.error(`Rust binary not found at ${sourceBin}`); + return false; } +}; - // Build backend for each selected platform - for (const p of platforms) { - logger.step(`Building ${colors.magenta}${p.name}${colors.reset}...`); - // Run go build with platform-specific environment variables - run(`go build -o "${join(binDir, p.out)}" .`, backendDir, { - GOOS: p.goos, - GOARCH: p.goarch, - CGO_ENABLED: "1", - }); +const buildFrontend = (name, config, extraArgs = "") => { + if (config.optional && !existsSync(join(config.path, "package.json"))) { + logger.warning(`Skipping ${name} (not initialized)`); + return true; } -} - -// Frontend - Common library build -if (buildCommonFront) { - console.log(); - logger.info("📦 Building common-front..."); - logger.step(`Building ${colors.magenta}common-front${colors.reset}...`); - // Install dependencies - run("npm ci", join(root, "common-front")); - // Build the library - run("npm run build", join(root, "common-front")); -} - -// Frontend - Control Station build -if (buildControlStation) { - console.log(); - logger.info("📦 Building control-station..."); - logger.step(`Building ${colors.magenta}control-station${colors.reset}...`); - // Install dependencies - run("npm ci", join(root, "control-station")); - // Build the application - run("npm run build", join(root, "control-station")); - - logger.step("Copying static files..."); - // Remove existing renderer directory - rmSync(join(__dirname, "renderer/control-station"), { - recursive: true, - force: true, - }); - // Copy built static files to renderer directory - cpSync( - join(root, "control-station/static"), - join(__dirname, "renderer/control-station"), - { recursive: true } - ); -} - -// Frontend - Ethernet View build -if (buildEthernetView) { - console.log(); - logger.info("📦 Building ethernet-view..."); - logger.step(`Building ${colors.magenta}ethernet-view${colors.reset}...`); - // Install dependencies - run("npm ci", join(root, "ethernet-view")); - // Build the application - run("npm run build", join(root, "ethernet-view")); - - logger.step("Copying static files..."); - // Remove existing renderer directory - rmSync(join(__dirname, "renderer/ethernet-view"), { - recursive: true, - force: true, - }); - // Copy built static files to renderer directory - cpSync( - join(root, "ethernet-view/static"), - join(__dirname, "renderer/ethernet-view"), - { recursive: true } - ); -} - -// Install Electron dependencies if any frontend was built -if (buildControlStation || buildEthernetView) { - console.log(); - logger.info("📦 Installing Electron dependencies..."); - // Install Electron app dependencies - run("npm ci", __dirname); -} - -console.log(); -logger.success("✅ Build complete!"); -console.log(); -// Show helpful next steps -console.log( - `${colors.dim}To run in development: ${colors.reset}${colors.cyan}npm start${colors.reset}` -); -console.log( - `${colors.dim}To build installers: ${colors.reset}${colors.cyan}npm run dist${colors.reset}` + + logger.info(`Building ${name}...`); + + for (const cmd of config.commands) { + const finalCmd = cmd.includes("build") ? `${cmd} ${extraArgs}` : cmd; + if (!run(finalCmd, config.path)) return false; + } + + logger.step(`Copying to renderer/${name}...`); + if (existsSync(config.dest)) + rmSync(config.dest, { recursive: true, force: true }); + + const distPath = join(config.path, "dist"); + if (existsSync(distPath)) { + cpSync(distPath, config.dest, { recursive: true }); + return true; + } else { + logger.error(`Build output not found at ${distPath}`); + return false; + } +}; + +// --- Argument Parsing --- + +const args = process.argv.slice(2); +const doubleDashIndex = args.indexOf("--"); +const scriptArgs = + doubleDashIndex !== -1 ? args.slice(0, doubleDashIndex) : args; +const extraArgs = + doubleDashIndex !== -1 ? args.slice(doubleDashIndex + 1).join(" ") : ""; + +const requestedPlatforms = []; +if (scriptArgs.includes("--win") || scriptArgs.includes("--windows")) + requestedPlatforms.push("win"); +if (scriptArgs.includes("--linux")) requestedPlatforms.push("linux"); +if (scriptArgs.includes("--mac") || scriptArgs.includes("--macos")) + requestedPlatforms.push("mac"); +if (scriptArgs.includes("--all")) requestedPlatforms.push("all"); + +// Handle Overrides: --target.prop=value +scriptArgs.forEach((arg) => { + if (arg.startsWith("--") && arg.includes(".") && arg.includes("=")) { + const [key, value] = arg.slice(2).split("="); + const [target, prop] = key.split("."); + if (CONFIG[target] && prop) { + const finalValue = prop === "commands" ? value.split(",") : value; + CONFIG[target][prop] = finalValue; + logger.info(`Override: ${target}.${prop} = ${finalValue}`); + } + } +}); + +const specificTargets = Object.keys(CONFIG).filter((key) => + scriptArgs.includes(`--${key}`) ); -console.log(); +const targetsToBuild = + specificTargets.length > 0 ? specificTargets : Object.keys(CONFIG); + +// --- Main Execution --- + +logger.header("Hyperloop Control Station Build"); + +(async () => { + let frontendBuilt = false; + let allSuccess = true; + + for (const key of targetsToBuild) { + const config = CONFIG[key]; + let success = true; + + if (config.type === "go") { + success = buildBackend(config, requestedPlatforms, extraArgs); + } else if (config.type === "rust") { + success = buildRust(key, config, requestedPlatforms, extraArgs); + } else if (config.type === "frontend") { + success = buildFrontend(key, config, extraArgs); + if (success && !config.optional) frontendBuilt = true; + } + + if (!success) { + allSuccess = false; + if (process.env.CI) process.exit(1); + } + } + + if (frontendBuilt && !process.env.CI) { + logger.info("Finalizing Electron..."); + run("pnpm --filter electron-app install --frozen-lockfile", __dirname); + } + + if (allSuccess) { + logger.success("Build complete!"); + } else { + logger.error("Build failed."); + process.exit(1); + } +})(); diff --git a/electron-app/dev-app-update.yml b/electron-app/dev-app-update.yml new file mode 100644 index 000000000..27ef92e02 --- /dev/null +++ b/electron-app/dev-app-update.yml @@ -0,0 +1,4 @@ +provider: github +owner: Hyperloop-UPV +repo: software +updaterCacheDirName: hyperloop-control-station/updater diff --git a/electron-app/icon.png b/electron-app/icon.png new file mode 100644 index 000000000..3555d0ad7 Binary files /dev/null and b/electron-app/icon.png differ diff --git a/electron-app/icons/1024x1024.png b/electron-app/icons/1024x1024.png new file mode 100644 index 000000000..1b2a9c44f Binary files /dev/null and b/electron-app/icons/1024x1024.png differ diff --git a/electron-app/icons/128x128.png b/electron-app/icons/128x128.png new file mode 100644 index 000000000..a498ea646 Binary files /dev/null and b/electron-app/icons/128x128.png differ diff --git a/electron-app/icons/16x16.png b/electron-app/icons/16x16.png new file mode 100644 index 000000000..ccd0fdfb2 Binary files /dev/null and b/electron-app/icons/16x16.png differ diff --git a/electron-app/icons/24x24.png b/electron-app/icons/24x24.png new file mode 100644 index 000000000..b4c0a5c1f Binary files /dev/null and b/electron-app/icons/24x24.png differ diff --git a/electron-app/icons/256x256.png b/electron-app/icons/256x256.png new file mode 100644 index 000000000..3d83ffa18 Binary files /dev/null and b/electron-app/icons/256x256.png differ diff --git a/electron-app/icons/32x32.png b/electron-app/icons/32x32.png new file mode 100644 index 000000000..58c8034d9 Binary files /dev/null and b/electron-app/icons/32x32.png differ diff --git a/electron-app/icons/48x48.png b/electron-app/icons/48x48.png new file mode 100644 index 000000000..0aecdf06e Binary files /dev/null and b/electron-app/icons/48x48.png differ diff --git a/electron-app/icons/512x512.png b/electron-app/icons/512x512.png new file mode 100644 index 000000000..4c1778dec Binary files /dev/null and b/electron-app/icons/512x512.png differ diff --git a/electron-app/icons/64x64.png b/electron-app/icons/64x64.png new file mode 100644 index 000000000..37afc188c Binary files /dev/null and b/electron-app/icons/64x64.png differ diff --git a/electron-app/icons/icon.icns b/electron-app/icons/icon.icns new file mode 100644 index 000000000..85fc7cac1 Binary files /dev/null and b/electron-app/icons/icon.icns differ diff --git a/electron-app/icons/icon.ico b/electron-app/icons/icon.ico new file mode 100644 index 000000000..a0d5ea739 Binary files /dev/null and b/electron-app/icons/icon.ico differ diff --git a/electron-app/main.js b/electron-app/main.js index 7c5138023..2ccc19c9f 100644 --- a/electron-app/main.js +++ b/electron-app/main.js @@ -4,13 +4,16 @@ * Handles application lifecycle, initialization, and cleanup of processes and windows. */ -import { app, dialog, BrowserWindow } from "electron"; -import { createWindow } from "./src/windows/mainWindow.js"; -import { startBackend, stopBackend } from "./src/processes/backend.js"; -import { setupIpcHandlers } from "./src/ipc/handlers.js"; +import { app, BrowserWindow, dialog } from "electron"; +import pkg from "electron-updater"; import { getConfigManager } from "./src/config/configInstance.js"; +import { setupIpcHandlers } from "./src/ipc/handlers.js"; +import { startBackend, stopBackend } from "./src/processes/backend.js"; import { stopPacketSender } from "./src/processes/packetSender.js"; import { logger } from "./src/utils/logger.js"; +import { createWindow } from "./src/windows/mainWindow.js"; + +const { autoUpdater } = pkg; // Setup IPC handlers for renderer process communication setupIpcHandlers(); @@ -18,16 +21,54 @@ setupIpcHandlers(); // App lifecycle: wait for Electron to be ready app.whenReady().then(async () => { // Initialize ConfigManager and ensure config exists BEFORE starting backend - logger.electron.info("Initializing configuration..."); + logger.electron.header("Initializing configuration..."); // Get ConfigManager instance (creates config from template if needed) await getConfigManager(); - logger.electron.info("Configuration ready"); + logger.electron.header("Configuration ready"); // Start backend process - startBackend(); + try { + await startBackend(); + logger.electron.header("Backend process spawned"); + } catch (error) { + // Start backend already shows these errors + return; + } // Create main application window createWindow(); + logger.electron.header("Main application window created"); + + // Updater setup + if (!app.isPackaged) { + autoUpdater.forceDevUpdateConfig = true; + } + + autoUpdater.logger = { + info: (message) => logger.electron.info(message), + error: (message) => logger.electron.error(message), + warn: (message) => logger.electron.warning(message), + debug: (message) => logger.electron.debug(message), + }; + + // Check for updates + autoUpdater.checkForUpdates(); + + // Handle update downloaded event + autoUpdater.on("update-downloaded", (info) => { + dialog + .showMessageBox({ + type: "info", + title: "Update Ready", + message: `Version ${info.version} has been downloaded. Restart now to install?`, + buttons: ["Restart", "Later"], + }) + .then((result) => { + if (result.response === 0) { + autoUpdater.quitAndInstall(); + } + }); + }); // Handle macOS app activation (reopen window when dock icon clicked) app.on("activate", () => { diff --git a/electron-app/package.json b/electron-app/package.json index b34bb56ad..a37d20f36 100644 --- a/electron-app/package.json +++ b/electron-app/package.json @@ -11,7 +11,7 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/HyperloopUPV-H8/software.git" + "url": "https://github.com/Hyperloop-UPV/software.git" }, "scripts": { "start": "electron .", @@ -21,37 +21,41 @@ "dist:mac": "electron-builder --mac", "dist:linux": "electron-builder --linux", "test": "vitest run", + "build-icons": "electron-icon-builder --input=./icon.png --output=./ --flatten", "build": "node build.mjs", - "build:win": "node build.mjs --platform windows", - "build:linux": "node build.mjs --platform linux", - "build:mac": "node build.mjs --platform mac", - "build:all": "node build.mjs --platform all", + "build:win": "node build.mjs --win", + "build:linux": "node build.mjs --linux", + "build:mac": "node build.mjs --mac", "build:backend": "node build.mjs --backend", - "build:backend:win": "node build.mjs --backend --platform windows", - "build:backend:linux": "node build.mjs --backend --platform linux", - "build:backend:mac": "node build.mjs --backend --platform mac", - "build:frontend": "node build.mjs --frontend", - "build:common": "node build.mjs --common-front", - "build:control-station": "node build.mjs --control-station", - "build:ethernet-view": "node build.mjs --ethernet-view", + "build:backend:win": "node build.mjs --backend --win", + "build:backend:linux": "node build.mjs --backend --linux", + "build:backend:mac": "node build.mjs --backend --mac", + "build:testing": "node build.mjs --testing-view", + "build:competition": "node build.mjs --competition-view", "asar:win": "asar list dist/win-unpacked/resources/app.asar | findstr /V node_modules", "asar:mac": "asar list dist/mac-unpacked/resources/app.asar | findstr /V node_modules", "asar:linux": "asar list dist/linux-unpacked/resources/app.asar | findstr /V node_modules" }, "dependencies": { "@iarna/toml": "^2.2.5", - "electron-store": "^8.1.0" + "electron-store": "^11.0.2", + "electron-updater": "^6.7.3", + "picocolors": "^1.1.1" }, "devDependencies": { - "@vitest/coverage-v8": "^4.0.14", + "@vitest/coverage-v8": "^4.0.18", "asar": "^3.2.0", - "electron": "^28.0.0", - "electron-builder": "^24.9.1", - "vitest": "^4.0.14" + "electron": "^40.1.0", + "electron-builder": "^26.7.0", + "vitest": "^4.0.18" }, "build": { "appId": "com.hyperloop.controlstation", - "publish": null, + "publish": { + "provider": "github", + "owner": "Hyperloop-UPV", + "repo": "software" + }, "productName": "Hyperloop-Control-Station", "directories": { "output": "dist" @@ -82,14 +86,20 @@ "nsis", "portable" ], - "icon": "icon.ico" + "icon": "icons/icon.ico" + }, + "nsis": { + "artifactName": "${productName}-Setup-${version}.${ext}" + }, + "portable": { + "artifactName": "${productName}-Portable-${version}.${ext}" }, "mac": { "target": [ "dmg", "zip" ], - "icon": "icon.icns", + "icon": "icons/icon.icns", "category": "public.app-category.utilities", "artifactName": "${productName}-${version}-macos-${arch}.${ext}" }, @@ -98,7 +108,7 @@ "AppImage", "deb" ], - "icon": "icon.png", + "icon": "icons/512x512.png", "category": "Utility", "artifactName": "${productName}-${version}-linux-${arch}.${ext}" } diff --git a/electron-app/src/config/configInstance.js b/electron-app/src/config/configInstance.js index 842327343..ae8068252 100644 --- a/electron-app/src/config/configInstance.js +++ b/electron-app/src/config/configInstance.js @@ -4,8 +4,8 @@ * Provides async wrappers for ConfigManager operations with lazy initialization. */ -import { getUserConfigPath, getTemplatePath } from "../utils/paths.js"; import { logger } from "../utils/logger.js"; +import { getTemplatePath, getUserConfigPath } from "../utils/paths.js"; // Store the singleton ConfigManager instance let configManager = null; @@ -30,8 +30,8 @@ async function getConfigManager() { // Create new ConfigManager instance configManager = new ConfigManager(userConfigPath, templatePath); logger.config.info("ConfigManager initialized"); - logger.config.info("User config:", userConfigPath); - logger.config.info("Template:", templatePath); + logger.config.path("User config", userConfigPath); + logger.config.path("Template path", templatePath); } // Return the singleton instance @@ -132,4 +132,4 @@ async function importConfig() { } } -export { getConfigManager, readConfig, writeConfig, importConfig }; +export { getConfigManager, importConfig, readConfig, writeConfig }; diff --git a/electron-app/src/ipc/handlers.js b/electron-app/src/ipc/handlers.js index 414f1e410..2aefe2bf4 100644 --- a/electron-app/src/ipc/handlers.js +++ b/electron-app/src/ipc/handlers.js @@ -7,19 +7,19 @@ * - Folder selection dialogs */ -import { ipcMain, dialog } from "electron"; +import { dialog, ipcMain } from "electron"; import { + importConfig, readConfig, writeConfig, - importConfig, } from "../config/configInstance.js"; +import { restartBackend } from "../processes/backend.js"; +import { logger } from "../utils/logger.js"; import { - loadView, getCurrentView, getMainWindow, + loadView, } from "../windows/mainWindow.js"; -import { restartBackend } from "../processes/backend.js"; -import { logger } from "../utils/logger.js"; /** * Initializes all IPC handlers for communication between main and renderer processes. diff --git a/electron-app/src/menu/menu.js b/electron-app/src/menu/menu.js index 6cd06f19d..c0436ab79 100644 --- a/electron-app/src/menu/menu.js +++ b/electron-app/src/menu/menu.js @@ -4,13 +4,14 @@ * Defines menu structure with File, View, Tools, and Help sections with keyboard shortcuts and actions. */ -import { Menu, dialog, app } from "electron"; -import { getBinaryPath } from "../utils/paths.js"; +import { Menu, app, dialog } from "electron"; +import fs from "fs"; import { - startPacketSender, getPacketSenderProcess, + startPacketSender, + stopPacketSender, } from "../processes/packetSender.js"; -import fs from "fs"; +import { getBinaryPath } from "../utils/paths.js"; import { loadView } from "../windows/mainWindow.js"; /** @@ -43,19 +44,17 @@ function createMenu(mainWindow) { label: "View", submenu: [ { - label: "Control Station", + label: "Competition View", accelerator: "CmdOrCtrl+1", click: () => { - loadView("control-station"); - loadView("control-station"); + loadView("competition-view"); }, }, { - label: "Ethernet View", + label: "Testing View", accelerator: "CmdOrCtrl+2", click: () => { - loadView("ethernet-view"); - loadView("ethernet-view"); + loadView("testing-view"); }, }, { type: "separator" }, @@ -84,7 +83,7 @@ function createMenu(mainWindow) { } const packetSenderProcess = getPacketSenderProcess(); if (!packetSenderProcess || packetSenderProcess.killed) { - startPacketSender(["--help"]); + startPacketSender(["random"]); } }, }, @@ -110,8 +109,7 @@ function createMenu(mainWindow) { type: "info", title: "About", message: "Hyperloop UPV Control Station", - detail: - "Version 1.0.0\n\nControl and monitoring software for Hyperloop pod.", + detail: `Version ${app.getVersion()}\n\nControl and monitoring software for Hyperloop pod.`, }); }, }, diff --git a/electron-app/src/processes/backend.js b/electron-app/src/processes/backend.js index ccdc7b1ba..1e215619d 100644 --- a/electron-app/src/processes/backend.js +++ b/electron-app/src/processes/backend.js @@ -5,16 +5,15 @@ */ import { spawn } from "child_process"; -import { dialog } from "electron"; +import { app, dialog } from "electron"; +import fs from "fs"; +import path from "path"; +import { logger } from "../utils/logger.js"; import { getAppPath, getBinaryPath, getUserConfigPath, } from "../utils/paths.js"; -import fs from "fs"; -import { app } from "electron"; -import path from "path"; -import { logger } from "../utils/logger.js"; // Get the application root path const appPath = getAppPath(); @@ -32,69 +31,82 @@ let lastBackendError = null; * startBackend(); */ function startBackend() { - // Get paths for binary and config - const backendBin = getBinaryPath("backend"); - const configPath = getUserConfigPath(); - - // Check if binary exists before attempting to start - if (!fs.existsSync(backendBin)) { - logger.backend.error(`Backend binary not found: ${backendBin}`); - dialog.showErrorBox("Error", `Backend binary not found at: ${backendBin}`); - return; - } - - logger.backend.info(`Starting backend: ${backendBin}, config: ${configPath}`); - - // Set working directory to backend/cmd in development, or resources in production - const workingDir = !app.isPackaged - ? path.join(appPath, "..", "backend", "cmd") - : path.dirname(configPath); - - // Spawn the backend process with config argument - backendProcess = spawn(backendBin, ["--config", configPath], { - cwd: workingDir, - }); - - // Log stdout output from backend - backendProcess.stdout.on("data", (data) => { - logger.backend.info(`${data.toString().trim()}`); - }); - - // Capture stderr output (where Go errors/panics are written) - backendProcess.stderr.on("data", (data) => { - const errorMsg = data.toString().trim(); - logger.backend.error(errorMsg); - // Store the last error message - lastBackendError = errorMsg; - }); + return new Promise((resolve, reject) => { + // Get paths for binary and config + const backendBin = getBinaryPath("backend"); + const configPath = getUserConfigPath(); + + // Check if binary exists before attempting to start + if (!fs.existsSync(backendBin)) { + logger.backend.error(`Backend binary not found: ${backendBin}`); + dialog.showErrorBox( + "Error", + `Backend binary not found at: ${backendBin}` + ); + return reject(new Error(`Backend binary not found: ${backendBin}`)); + } - // Handle spawn errors - backendProcess.on("error", (error) => { - logger.backend.error(`Failed to start backend: ${error.message}`); - dialog.showErrorBox( - "Backend Error", - `Failed to start backend: ${error.message}` + logger.backend.info( + `Starting backend: ${backendBin}, config: ${configPath}` ); - }); - // Handle process exit - backendProcess.on("close", (code) => { - logger.backend.info(`Backend process exited with code ${code}`); - // Show error dialog if process crashed (non-zero exit code) - if (code !== 0 && code !== null) { - // Build error message with actual error details - let errorMessage = `Backend exited with code ${code}`; - - if (lastBackendError) { - errorMessage += `\n\n${lastBackendError}`; - } else { - errorMessage += "\n\n(No error output captured)"; + // Set working directory to backend/cmd in development, or resources in production + const workingDir = !app.isPackaged + ? path.join(appPath, "..", "backend", "cmd") + : path.dirname(configPath); + + // Spawn the backend process with config argument + backendProcess = spawn(backendBin, ["--config", configPath], { + cwd: workingDir, + }); + + // Log stdout output from backend + backendProcess.stdout.on("data", (data) => { + logger.backend.info(`${data.toString().trim()}`); + }); + + // Capture stderr output (where Go errors/panics are written) + backendProcess.stderr.on("data", (data) => { + const errorMsg = data.toString().trim(); + logger.backend.error(errorMsg); + // Store the last error message + lastBackendError = errorMsg; + }); + + // Handle spawn errors + backendProcess.on("error", (error) => { + logger.backend.error(`Failed to start backend: ${error.message}`); + dialog.showErrorBox( + "Backend Error", + `Failed to start backend: ${error.message}` + ); + return reject(new Error(`Failed to start backend: ${error.message}`)); + }); + + // If the backend didn't fail in this period of time, resolve the promise + setTimeout(() => { + resolve(backendProcess); + }, 1000); + + // Handle process exit + backendProcess.on("close", (code) => { + logger.backend.info(`Backend process exited with code ${code}`); + // Show error dialog if process crashed (non-zero exit code) + if (code !== 0 && code !== null) { + // Build error message with actual error details + let errorMessage = `Backend exited with code ${code}`; + + if (lastBackendError) { + errorMessage += `\n\n${lastBackendError}`; + } else { + errorMessage += "\n\n(No error output captured)"; + } + + dialog.showErrorBox("Backend Crashed", errorMessage); + // Clear error message after showing + lastBackendError = null; } - - dialog.showErrorBox("Backend Crashed", errorMessage); - // Clear error message after showing - lastBackendError = null; - } + }); }); } @@ -128,4 +140,4 @@ function restartBackend() { startBackend(); } -export { startBackend, stopBackend, restartBackend }; +export { restartBackend, startBackend, stopBackend }; diff --git a/electron-app/src/processes/packetSender.js b/electron-app/src/processes/packetSender.js index 67a506cfd..e6efc5cf9 100644 --- a/electron-app/src/processes/packetSender.js +++ b/electron-app/src/processes/packetSender.js @@ -5,9 +5,9 @@ */ import { spawn } from "child_process"; -import { getBinaryPath } from "../utils/paths.js"; import fs from "fs"; import { logger } from "../utils/logger.js"; +import { getBinaryPath } from "../utils/paths.js"; // Store the packet sender process instance let packetSenderProcess = null; @@ -90,7 +90,7 @@ function restartPacketSender() { // Wait before starting new process to ensure cleanup setTimeout(() => { // Start with help arguments - startPacketSender(["--help"]); + startPacketSender(["random"]); }, 500); } } @@ -110,8 +110,8 @@ function getPacketSenderProcess() { } export { + getPacketSenderProcess, + restartPacketSender, startPacketSender, stopPacketSender, - restartPacketSender, - getPacketSenderProcess, }; diff --git a/electron-app/src/utils/colors.js b/electron-app/src/utils/colors.js deleted file mode 100644 index fd982d517..000000000 --- a/electron-app/src/utils/colors.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @module utils - * @description ANSI color codes for terminal output formatting. - * Provides color constants for styling console messages with reset, brightness, and color options. - */ - -/** - * Object containing ANSI escape codes for terminal text coloring and formatting. - * @type {Object} - * @property {string} reset - ANSI reset code to clear all formatting. - * @property {string} bright - ANSI code for bright/bold text. - * @property {string} dim - ANSI code for dim text. - * @property {string} red - ANSI code for red text. - * @property {string} green - ANSI code for green text. - * @property {string} yellow - ANSI code for yellow text. - * @property {string} blue - ANSI code for blue text. - * @property {string} magenta - ANSI code for magenta text. - * @property {string} cyan - ANSI code for cyan text. - * @property {string} white - ANSI code for white text. - * @property {string} gray - ANSI code for gray text. - * @property {string} brightRed - ANSI code for bright red text. - * @property {string} brightGreen - ANSI code for bright green text. - * @property {string} brightYellow - ANSI code for bright yellow text. - * @property {string} brightBlue - ANSI code for bright blue text. - * @property {string} brightMagenta - ANSI code for bright magenta text. - * @property {string} brightCyan - ANSI code for bright cyan text. - * @example - * import { colors } from './colors.js'; - * console.log(`${colors.green}Success!${colors.reset}`); - * console.log(`${colors.brightRed}Error!${colors.reset}`); - */ -export const colors = { - reset: "\x1b[0m", - bright: "\x1b[1m", - dim: "\x1b[2m", - - red: "\x1b[31m", - green: "\x1b[32m", - yellow: "\x1b[33m", - blue: "\x1b[34m", - magenta: "\x1b[35m", - cyan: "\x1b[36m", - white: "\x1b[37m", - gray: "\x1b[90m", - - brightRed: "\x1b[91m", - brightGreen: "\x1b[92m", - brightYellow: "\x1b[93m", - brightBlue: "\x1b[94m", - brightMagenta: "\x1b[95m", - brightCyan: "\x1b[96m", -}; diff --git a/electron-app/src/utils/logger.js b/electron-app/src/utils/logger.js index e837402b8..4fab38227 100644 --- a/electron-app/src/utils/logger.js +++ b/electron-app/src/utils/logger.js @@ -5,7 +5,7 @@ * All logging methods write directly to the console with ANSI color formatting. */ -import { colors } from "./colors.js"; +import pc from "picocolors"; /** * @typedef {Object} LoggerMethods @@ -21,118 +21,51 @@ import { colors } from "./colors.js"; /** * Creates a set of logger methods with an optional prefix and color. - * @param {string} [prefix=""] - Optional prefix text to display before log messages. - * @param {keyof typeof colors} [prefixColor=""] - Optional color name from the colors object for the prefix. - * @returns {LoggerMethods} Logger methods object. - * @example - * const myLogger = createLoggerMethods("MyApp", "cyan"); - * myLogger.info("Application started"); - * myLogger.error("Something went wrong"); + * @param {string} [prefix=""] - Optional prefix text. + * @param {string} [prefixColor=""] - Color name from picocolors (e.g., "cyan", "magenta"). */ function createLoggerMethods(prefix = "", prefixColor = "") { - const prefixText = prefix - ? `${colors[prefixColor] || ""}[${prefix}]${colors.reset} ` - : ""; + // Get the color function from picocolors, or fallback to a plain string + const colorFn = pc[prefixColor] || ((s) => s); + const prefixText = prefix ? `${colorFn(`[${prefix}]`)} ` : ""; return { - /** - * Logs an info-level message to the console. - * @param {string} msg - The message to log. - * @param {...any} args - Additional arguments for console.log. - */ info: (msg, ...args) => { - console.log( - `${prefixText}${colors.blue}[INFO]${colors.reset} ${msg}`, - ...args - ); + console.log(`${prefixText}${pc.blue("[INFO]")} ${msg}`, ...args); }, - /** - * Logs a success-level message to the console. - * @param {string} msg - The message to log. - * @param {...any} args - Additional arguments for console.log. - */ success: (msg, ...args) => { - console.log( - `${prefixText}${colors.brightGreen}[OK]${colors.reset} ${msg}`, - ...args - ); + console.log(`${prefixText}${pc.green("[OK]")} ${msg}`, ...args); }, - /** - * Logs a warning-level message to the console. - * @param {string} msg - The message to log. - * @param {...any} args - Additional arguments for console.log. - */ warning: (msg, ...args) => { - console.log( - `${prefixText}${colors.yellow}[WARN]${colors.reset} ${msg}`, - ...args - ); + console.log(`${prefixText}${pc.yellow("[WARN]")} ${msg}`, ...args); }, - /** - * Logs an error-level message to the console. - * @param {string} msg - The message to log. - * @param {...any} args - Additional arguments for console.error. - */ error: (msg, ...args) => { - console.error( - `${prefixText}${colors.brightRed}[ERROR]${colors.reset} ${msg}`, - ...args - ); + console.error(`${prefixText}${pc.red("[ERROR]")} ${msg}`, ...args); }, - /** - * Logs a debug-level message to the console. - * @param {string} msg - The message to log. - * @param {...any} args - Additional arguments for console.log. - */ debug: (msg, ...args) => { - console.log( - `${prefixText}${colors.gray}[DEBUG]${colors.reset} ${msg}`, - ...args - ); + console.log(`${prefixText}${pc.gray("[DEBUG]")} ${msg}`, ...args); }, - /** - * Prints a header message with bright cyan formatting. - * @param {string} msg - The header message. - */ header: (msg) => { - console.log( - `\n${prefixText}${colors.bright}${colors.cyan}${msg}${colors.reset}\n` - ); + console.log(`\n${prefixText}${pc.bold(pc.cyan(msg))}\n`); }, - /** - * Prints a step message with dim formatting. - * @param {string} msg - The step message. - * @param {...any} args - Additional arguments for console.log. - */ step: (msg, ...args) => { - console.log( - `${prefixText}${colors.dim} > ${msg}${colors.reset}`, - ...args - ); + console.log(`${prefixText}${pc.dim(` > ${msg}`)}`, ...args); }, - /** - * Prints a labeled path with dim label and cyan path. - * @param {string} label - Label for the path (e.g., "Config"). - * @param {string} path - The path value. - */ path: (label, path) => { - console.log( - `${prefixText} ${colors.dim}${label}:${colors.reset} ${colors.cyan}${path}${colors.reset}` - ); + console.log(`${prefixText} ${pc.dim(`${label}:`)} ${pc.cyan(path)}`); }, }; } /** * @typedef {LoggerMethods & { - * colors: typeof colors, * electron: LoggerMethods, * backend: LoggerMethods, * config: LoggerMethods, @@ -154,8 +87,6 @@ function createLoggerMethods(prefix = "", prefixColor = "") { * logger.log("green", "Success message"); */ export const logger = { - colors, - // Default logger methods (no prefix) ...createLoggerMethods(), @@ -171,16 +102,16 @@ export const logger = { * @param {string} msg - Message to log. */ process: (name, msg) => { - console.log(`${colors.magenta}[${name}]${colors.reset} ${msg}`); + console.log(`${pc.magenta}[${name}]${pc.reset} ${msg}`); }, /** * Logs a message in a specified color. - * @param {keyof typeof colors} color - Color key from the colors object. + * @param {keyof typeof pc} color - Color key from the pc object. * @param {string} msg - Message to log. * @param {...any} args - Additional arguments for console.log. */ log: (color, msg, ...args) => { - console.log(`${colors[color] || ""}${msg}${colors.reset}`, ...args); + console.log(`${pc[color] || ""}${msg}${pc.reset}`, ...args); }, }; diff --git a/electron-app/src/utils/paths.js b/electron-app/src/utils/paths.js index d3178d7e2..f7bf70033 100644 --- a/electron-app/src/utils/paths.js +++ b/electron-app/src/utils/paths.js @@ -41,6 +41,13 @@ function getBinaryPath(name) { const arch = process.arch; const ext = platform === "win32" ? ".exe" : ""; + if (name === "packet-sender") { + if (!app.isPackaged) { + return path.join(getAppPath(), "binaries", `${name}${ext}`); + } + return path.join(process.resourcesPath, "binaries", `${name}${ext}`); + } + const goosMap = { win32: "windows", darwin: "darwin", @@ -108,4 +115,4 @@ function getTemplatePath() { return path.join(process.resourcesPath, "config.toml"); } -export { getAppPath, getBinaryPath, getUserConfigPath, getTemplatePath }; +export { getAppPath, getBinaryPath, getTemplatePath, getUserConfigPath }; diff --git a/electron-app/src/windows/mainWindow.js b/electron-app/src/windows/mainWindow.js index 885d142b4..259f8dc79 100644 --- a/electron-app/src/windows/mainWindow.js +++ b/electron-app/src/windows/mainWindow.js @@ -5,8 +5,8 @@ */ import { BrowserWindow, app, dialog } from "electron"; -import path from "path"; import fs from "fs"; +import path from "path"; import { createMenu } from "../menu/menu.js"; import { getAppPath } from "../utils/paths.js"; @@ -16,7 +16,7 @@ const appPath = getAppPath(); // Store the main window instance let mainWindow = null; // Track the currently loaded view -let currentView = "ethernet-view"; +let currentView = "testing-view"; /** * Creates and initializes the main application window. @@ -38,13 +38,15 @@ function createWindow() { contextIsolation: true, // Disable node integration for security nodeIntegration: false, + // Disable background throttling to prevent data loss when window is minimized + backgroundThrottling: false, }, title: "Hyperloop Control Station", backgroundColor: "#1a1a1a", }); // Load ethernet view by default - loadView("ethernet-view"); + loadView(currentView); // Create application menu createMenu(mainWindow); @@ -117,4 +119,4 @@ function getMainWindow() { return mainWindow; } -export { createWindow, loadView, getCurrentView, getMainWindow }; +export { createWindow, getCurrentView, getMainWindow, loadView }; diff --git a/frontend/frontend-kit/core/package.json b/frontend/frontend-kit/core/package.json index 38738ae85..bb358f5a3 100644 --- a/frontend/frontend-kit/core/package.json +++ b/frontend/frontend-kit/core/package.json @@ -14,7 +14,7 @@ "packageManager": "pnpm@10.24.0", "devDependencies": { "@workspace/eslint-config": "workspace:*", - "eslint": "^9.39.1" + "eslint": "^9.39.2" }, "exports": { ".": "./src/index.ts" diff --git a/frontend/frontend-kit/core/src/websocket.ts b/frontend/frontend-kit/core/src/websocket.ts index 2d4005654..649818f1f 100644 --- a/frontend/frontend-kit/core/src/websocket.ts +++ b/frontend/frontend-kit/core/src/websocket.ts @@ -2,13 +2,16 @@ import { asyncScheduler, BehaviorSubject, bufferTime, + catchError, concatMap, + EMPTY, filter, from, map, Observable, ReplaySubject, shareReplay, + Subject, switchMap, throttleTime, } from "rxjs"; @@ -33,11 +36,26 @@ class SocketService { "connected" | "disconnected" | "connecting" >("disconnected"); + /** + * Subject that holds the error of the WebSocket connection. + * + * The idea is to emit only one error event for each error.\ + * Without this subject error gets duplicated because of shareReplay operator. + */ + public error$ = new Subject(); + /** * Observable that emits the messages from the WebSocket server. */ public messages$: Observable = this.socketSource$.pipe( - switchMap((socket) => socket), + switchMap((socket) => + socket.pipe( + catchError((err) => { + this.error$.next(err); + return EMPTY; + }), + ), + ), shareReplay(1), ); @@ -70,6 +88,8 @@ class SocketService { this.ws.subscribe({ error: (err) => { logger.core.error("WebSocket Error:", err); + this.error$.next(err); + this.status$.next("disconnected"); this.cleanup(); }, @@ -144,6 +164,15 @@ class SocketService { } this.ws.next({ topic, payload }); } + + /** + * Subscribes to the error subject. + * @param callback - the callback to call when an error occurs. + * @returns a subscription to the error subject. + */ + onError(callback: (err: Error) => void) { + return this.error$.subscribe(callback); + } } export const socketService = new SocketService(); diff --git a/frontend/frontend-kit/esling-config/package.json b/frontend/frontend-kit/esling-config/package.json index 8216a4d86..dfb4d11d7 100644 --- a/frontend/frontend-kit/esling-config/package.json +++ b/frontend/frontend-kit/esling-config/package.json @@ -12,18 +12,18 @@ "./vite": "./vite.js" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^8.24.1", - "@typescript-eslint/parser": "^8.24.1", - "eslint": "^9.20.1", - "@eslint/js": "^9.20.1", - "eslint-config-prettier": "^9.1.0", + "@eslint/js": "^9.39.2", + "@typescript-eslint/eslint-plugin": "^8.54.0", + "@typescript-eslint/parser": "^8.54.0", + "eslint": "^9.39.2", + "eslint-config-prettier": "^10.1.8", "eslint-plugin-only-warn": "^1.1.0", - "eslint-plugin-react": "^7.37.4", - "eslint-plugin-react-hooks": "^5.1.0", - "eslint-plugin-react-refresh": "^0.4.19", - "eslint-plugin-turbo": "^2.4.2", - "globals": "^15.15.0", - "typescript": "^5.7.3", - "typescript-eslint": "^8.24.1" + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.5.0", + "eslint-plugin-turbo": "^2.8.3", + "globals": "^17.3.0", + "typescript": "^5.9.3", + "typescript-eslint": "^8.54.0" } } diff --git a/frontend/frontend-kit/ui/package.json b/frontend/frontend-kit/ui/package.json index 4fccb11f9..9c26d70ce 100644 --- a/frontend/frontend-kit/ui/package.json +++ b/frontend/frontend-kit/ui/package.json @@ -22,28 +22,28 @@ "@workspace/core": "workspace:*", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "lucide-react": "^0.475.0", - "next-themes": "^0.4.4", - "react": "^19.2.3", - "react-dom": "^19.2.3", - "react-resizable-panels": "^3.0.6", + "lucide-react": "^0.563.0", + "next-themes": "^0.4.6", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-resizable-panels": "^4.6.0", "rxjs": "^7.8.2", - "tailwind-merge": "^3.0.1", - "tw-animate-css": "^1.2.4", - "zod": "^3.24.2", + "tailwind-merge": "^3.4.0", + "tw-animate-css": "^1.4.0", + "zod": "^4.3.6", "zustand": "^5.0.11" }, "devDependencies": { - "@tailwindcss/postcss": "^4.0.8", - "@turbo/gen": "^2.4.2", - "@types/node": "^20", - "@types/react": "^19.2.7", + "@tailwindcss/postcss": "^4.1.18", + "@turbo/gen": "^2.8.3", + "@types/node": "^25.2.0", + "@types/react": "^19.2.11", "@types/react-dom": "^19.2.3", "@workspace/eslint-config": "workspace:*", "@workspace/typescript-config": "workspace:*", - "eslint": "^9.39.1", - "tailwindcss": "^4.0.8", - "typescript": "^5.7.3" + "eslint": "^9.39.2", + "tailwindcss": "^4.1.18", + "typescript": "^5.9.3" }, "exports": { ".": "./src/index.ts", diff --git a/frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx b/frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx index bcdac0037..bbaca1e2b 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/resizable.tsx @@ -1,56 +1,53 @@ -"use client"; +"use client" -import * as React from "react"; -import { GripVerticalIcon } from "lucide-react"; -import * as ResizablePrimitive from "react-resizable-panels"; +import { GripVerticalIcon } from "lucide-react" +import * as ResizablePrimitive from "react-resizable-panels" -import { cn } from "@workspace/ui/lib/utils"; +import { cn } from "@workspace/ui/lib/utils" function ResizablePanelGroup({ className, ...props -}: React.ComponentProps) { +}: ResizablePrimitive.GroupProps) { return ( - - ); + ) } -function ResizablePanel({ - ...props -}: React.ComponentProps) { - return ; +function ResizablePanel({ ...props }: ResizablePrimitive.PanelProps) { + return } function ResizableHandle({ withHandle, className, ...props -}: React.ComponentProps & { - withHandle?: boolean; +}: ResizablePrimitive.SeparatorProps & { + withHandle?: boolean }) { return ( - div]:rotate-90", - className, + "bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90", + className )} {...props} > {withHandle && ( -
+
)} - - ); + + ) } -export { ResizablePanelGroup, ResizablePanel, ResizableHandle }; +export { ResizableHandle, ResizablePanel, ResizablePanelGroup } diff --git a/frontend/frontend-kit/ui/src/hooks/webSocket/index.ts b/frontend/frontend-kit/ui/src/hooks/webSocket/index.ts index 94526929c..8b8f71bcf 100644 --- a/frontend/frontend-kit/ui/src/hooks/webSocket/index.ts +++ b/frontend/frontend-kit/ui/src/hooks/webSocket/index.ts @@ -1,3 +1,4 @@ export * from "./fetchConfig"; +export * from "./useErrorSubscription"; export * from "./useTopic"; export * from "./useWebSocket"; diff --git a/frontend/frontend-kit/ui/src/hooks/webSocket/useErrorSubscription.ts b/frontend/frontend-kit/ui/src/hooks/webSocket/useErrorSubscription.ts new file mode 100644 index 000000000..6b1eb734f --- /dev/null +++ b/frontend/frontend-kit/ui/src/hooks/webSocket/useErrorSubscription.ts @@ -0,0 +1,12 @@ +import { socketService } from "@workspace/core"; +import { useEffect } from "react"; + +const useErrorSubscription = (callback: (err: Error) => void) => { + useEffect(() => { + const sub = socketService.onError((err) => callback(err)); + + return () => sub.unsubscribe(); + }, [callback]); +}; + +export default useErrorSubscription; diff --git a/frontend/testing-view/.env.production b/frontend/testing-view/.env.production new file mode 100644 index 000000000..ae71e9e8b --- /dev/null +++ b/frontend/testing-view/.env.production @@ -0,0 +1 @@ +VITE_BACKEND_URL=http://127.0.0.1:4000/backend \ No newline at end of file diff --git a/frontend/testing-view/config.ts b/frontend/testing-view/config.ts new file mode 100644 index 000000000..6fca0d4f9 --- /dev/null +++ b/frontend/testing-view/config.ts @@ -0,0 +1,25 @@ +export const config = { + /** Default buffer size for a new chart. */ + DEFAULT_CHART_HISTORY_LIMIT: 100, + + /** Fallback history limit for a chart. Used when the history limit is not set. */ + FALLBACK_CHART_HISTORY_LIMIT: 100, + + /** Default height of chart. */ + DEFAULT_CHART_HEIGHT: 250, + + /** Width of lines in chart between points. */ + CHART_LINE_WIDTH: 2, + + /** Size of points in chart (not hovered state). */ + CHART_POINT_SIZE: 2, + + /** Maximum number of messages section to store. */ + MAX_MESSAGES_COUNT: 200, + + /** Timeout for logger response or time to invalidate logger status after start button click. */ + LOGGER_RESPONSE_TIMEOUT: 2000, + + /** Timeout applied after settings save to give enough time for backend to restart. */ + SETTINGS_RESPONSE_TIMEOUT: 1000, +} as const; diff --git a/frontend/testing-view/package.json b/frontend/testing-view/package.json index 587d09f09..6da712c4d 100644 --- a/frontend/testing-view/package.json +++ b/frontend/testing-view/package.json @@ -18,29 +18,29 @@ "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@radix-ui/react-slot": "^1.2.4", - "@tailwindcss/vite": "^4.1.17", - "@tanstack/react-virtual": "^3.13.14", + "@tailwindcss/vite": "^4.1.18", + "@tanstack/react-virtual": "^3.13.18", "@types/lodash": "^4.17.23", - "@vitejs/plugin-react-swc": "^4.2.2", + "@vitejs/plugin-react-swc": "^4.2.3", "@workspace/core": "workspace:*", "@workspace/ui": "workspace:*", - "lodash": "^4.17.21", - "react": "^19.2.3", - "react-dom": "^19.2.3", + "lodash": "^4.17.23", + "react": "^19.2.4", + "react-dom": "^19.2.4", "react-router": "^7.13.0", - "tailwindcss": "^4.1.17", + "tailwindcss": "^4.1.18", "uplot": "^1.6.32", - "vitest": "^4.0.16", + "vitest": "^4.0.18", "zustand": "^5.0.11" }, "devDependencies": { - "@types/react": "^19.2.7", + "@types/react": "^19.2.11", "@types/react-dom": "^19.2.3", "@workspace/eslint-config": "workspace:^", "@workspace/typescript-config": "workspace:*", - "eslint": "^9.25.0", - "globals": "^15.15.0", + "eslint": "^9.39.2", + "globals": "^17.3.0", "typescript": "^5.9.3", - "vite": "^7.2.4" + "vite": "^7.3.1" } } diff --git a/frontend/testing-view/src/App.tsx b/frontend/testing-view/src/App.tsx index d5db347a5..506f86ed4 100644 --- a/frontend/testing-view/src/App.tsx +++ b/frontend/testing-view/src/App.tsx @@ -24,7 +24,7 @@ function App() { const { packets, commands, isLoading } = useAppConfigs(isConnected); // Determine app mode - useAppMode(packets, commands, isLoading, isConnected); + useAppMode(packets, commands, isLoading); // Transform boards and store in the global store useTransformedBoards(packets, commands); diff --git a/frontend/testing-view/src/components/Footer.tsx b/frontend/testing-view/src/components/Footer.tsx deleted file mode 100644 index 6846cdb93..000000000 --- a/frontend/testing-view/src/components/Footer.tsx +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Renders a footer with the app name, current year and the copyright notice - */ -export const Footer = () => { - const currentYear = new Date().getFullYear(); - const dateRange = - currentYear <= 2025 ? `${currentYear}` : `2025-${currentYear}`; - - return ( -
- - Control Station - Testing View © {dateRange} Hyperloop UPV - -
- ); -}; - -export default Footer; diff --git a/frontend/testing-view/src/components/leftSidebar/Logo.tsx b/frontend/testing-view/src/components/leftSidebar/Logo.tsx index 48f42f3f2..91228bd2c 100644 --- a/frontend/testing-view/src/components/leftSidebar/Logo.tsx +++ b/frontend/testing-view/src/components/leftSidebar/Logo.tsx @@ -10,7 +10,7 @@ const Logo = () => { tooltip="Hyperloop UPV H11" className="text-base font-bold" > - Logo + Logo Hyperloop UPV H11 diff --git a/frontend/testing-view/src/components/settings/SettingsDialog.tsx b/frontend/testing-view/src/components/settings/SettingsDialog.tsx index f9fe6d647..f62b29d31 100644 --- a/frontend/testing-view/src/components/settings/SettingsDialog.tsx +++ b/frontend/testing-view/src/components/settings/SettingsDialog.tsx @@ -1,3 +1,4 @@ +import { socketService } from "@workspace/core"; import { Badge, Button } from "@workspace/ui"; import { Dialog, @@ -11,14 +12,17 @@ import { AlertTriangle, CheckCircle2, } from "../../../../frontend-kit/ui/src/icons/notifications"; +import { config } from "../../../config"; import { DEFAULT_CONFIG } from "../../constants/defaultConfig"; import { useStore } from "../../store/store"; +import type { ConfigData } from "../../types/common/config"; import { SettingsForm } from "./SettingsForm"; export const SettingsDialog = () => { const isSettingsOpen = useStore((s) => s.isSettingsOpen); const setSettingsOpen = useStore((s) => s.setSettingsOpen); - const [localConfig, setLocalConfig] = useState(null); + const setRestarting = useStore((s) => s.setRestarting); + const [localConfig, setLocalConfig] = useState(null); const [isSynced, setIsSynced] = useState(false); const loadConfig = async () => { @@ -55,12 +59,19 @@ export const SettingsDialog = () => { } else { console.log("Electron API not available. Using default config."); } - setSettingsOpen(false); + + setRestarting(true); + + setTimeout(() => { + socketService.connect(); + setSettingsOpen(false); + setRestarting(false); + }, config.SETTINGS_RESPONSE_TIMEOUT); }; return ( - +
System Configuration diff --git a/frontend/testing-view/src/components/settings/SettingsForm.tsx b/frontend/testing-view/src/components/settings/SettingsForm.tsx index bca848233..96357b57e 100644 --- a/frontend/testing-view/src/components/settings/SettingsForm.tsx +++ b/frontend/testing-view/src/components/settings/SettingsForm.tsx @@ -1,5 +1,6 @@ import { get, set } from "lodash"; import { SETTINGS_SCHEMA } from "../../constants/settingsSchema"; +import type { ConfigData } from "../../types/common/config"; import type { SettingField } from "../../types/common/settings"; import { BooleanField } from "./BooleanField"; import { MultiCheckboxField } from "./MultiCheckboxField"; @@ -7,13 +8,9 @@ import { PathField } from "./PathField"; import { SelectField } from "./SelectField"; import { TextField } from "./TextField"; -interface SettingsConfig { - [key: string]: SettingField; -} - interface SettingsFormProps { - config: SettingsConfig; - onChange: (newConfig: SettingsConfig) => void; + config: ConfigData; + onChange: (newConfig: ConfigData) => void; } export const SettingsForm = ({ config, onChange }: SettingsFormProps) => { diff --git a/frontend/testing-view/src/constants/acronyms.ts b/frontend/testing-view/src/constants/acronyms.ts index c69c72bbb..52552c31a 100644 --- a/frontend/testing-view/src/constants/acronyms.ts +++ b/frontend/testing-view/src/constants/acronyms.ts @@ -1,5 +1,7 @@ -// Special cases for acronyms that should stay uppercase for format name function -export const acronyms = [ +/** + * Special cases for acronyms that should stay uppercase for format name function + */ +export const ACRONYMS = [ "SOC", "SOH", "CAN", @@ -20,4 +22,4 @@ export const acronyms = [ "BMS", "LDU", "SVPWM", -]; +] as const; diff --git a/frontend/testing-view/src/constants/boards.ts b/frontend/testing-view/src/constants/boards.ts index 0f49db77b..68a8a4127 100644 --- a/frontend/testing-view/src/constants/boards.ts +++ b/frontend/testing-view/src/constants/boards.ts @@ -1,11 +1,10 @@ -import type { BoardName } from "../types/data/board"; - -export const BOARD_NAMES: BoardName[] = [ - "BCU", - "PCU", - "LCU", - "HVSCU", - "BMSL", - "VCU", - "HVSCU-Cabinet", +/** List of names of available boards. */ +export const BOARD_NAMES: readonly string[] = [ + "BCU", // Battery Control Unit + "PCU", // Propulsion Control Unit + "LCU", // Levitation Control Unit + "HVSCU", // High Voltage System Control Unit + "BMSL", // Battery Management System Level + "VCU", // Vehicle Control Unit + "HVSCU-Cabinet", // High Voltage System Control Unit Cabinet ]; diff --git a/frontend/testing-view/src/constants/defaultConfig.ts b/frontend/testing-view/src/constants/defaultConfig.ts index 50813bb64..a7e0bb6b0 100644 --- a/frontend/testing-view/src/constants/defaultConfig.ts +++ b/frontend/testing-view/src/constants/defaultConfig.ts @@ -1,5 +1,7 @@ import type { ConfigData } from "../types/common/config"; +/** Default configuration for the backend in settings form. + * Used when the configuration is not found or when opened without electron API. */ export const DEFAULT_CONFIG: ConfigData = { vehicle: { boards: [ diff --git a/frontend/testing-view/src/constants/emptyArray.ts b/frontend/testing-view/src/constants/emptyArray.ts index d562f71b3..ae5a4164b 100644 --- a/frontend/testing-view/src/constants/emptyArray.ts +++ b/frontend/testing-view/src/constants/emptyArray.ts @@ -1,2 +1,2 @@ -// Empty array reference +/** Empty array reference. */ export const EMPTY_ARRAY: unknown[] = []; diff --git a/frontend/testing-view/src/constants/loggerControlConfig.tsx b/frontend/testing-view/src/constants/loggerControlConfig.tsx index baeafcea6..03127b9e4 100644 --- a/frontend/testing-view/src/constants/loggerControlConfig.tsx +++ b/frontend/testing-view/src/constants/loggerControlConfig.tsx @@ -8,6 +8,7 @@ interface LoggerControlOption { className: string; } +/** Appearance configuration for the logger control state. */ export const LOGGER_CONTROL_CONFIG: Record = { standby: { diff --git a/frontend/testing-view/src/constants/messageKindColors.ts b/frontend/testing-view/src/constants/messageKindColors.ts index 74909decd..d7d6e6123 100644 --- a/frontend/testing-view/src/constants/messageKindColors.ts +++ b/frontend/testing-view/src/constants/messageKindColors.ts @@ -1,8 +1,9 @@ import type { Message } from "../types/data/message"; +/** Colors for the message kind badges in the messages section. */ export const MESSAGE_KIND_COLORS: Record = { - info: "border-blue-500 hover:bg-blue-500/5", - warning: "border-yellow-500 hover:bg-yellow-500/5", - fault: "border-red-500 hover:bg-red-500/5", - ok: "border-green-500 hover:bg-green-500/5", - }; \ No newline at end of file + info: "border-blue-500 hover:bg-blue-500/5", + warning: "border-yellow-500 hover:bg-yellow-500/5", + fault: "border-red-500 hover:bg-red-500/5", + ok: "border-green-500 hover:bg-green-500/5", +}; diff --git a/frontend/testing-view/src/constants/pages.ts b/frontend/testing-view/src/constants/pages.ts index 0d3aaf96b..82867a064 100644 --- a/frontend/testing-view/src/constants/pages.ts +++ b/frontend/testing-view/src/constants/pages.ts @@ -1,10 +1,12 @@ import { FlaskConical, ScrollText } from "@workspace/ui/icons"; +/** Pages of the application showed in the left sidebar. */ export const PAGES = { "/": { title: "Testing", icon: FlaskConical }, "/logs": { title: "Logs", icon: ScrollText }, }; +/** Pages of the application showed in the left sidebar. The same thing as `PAGES` but in the array format. */ export const PAGES_ARRAY = Object.entries(PAGES).map( ([url, { title, icon }]) => ({ title, icon, url }), ); diff --git a/frontend/testing-view/src/constants/settingsSchema.ts b/frontend/testing-view/src/constants/settingsSchema.ts index ef4a366d6..eecc75f85 100644 --- a/frontend/testing-view/src/constants/settingsSchema.ts +++ b/frontend/testing-view/src/constants/settingsSchema.ts @@ -1,5 +1,7 @@ import type { SettingsSection } from "../types/common/settings"; +import { BOARD_NAMES } from "./boards"; +/** Settings form is generated from this schema. */ export const SETTINGS_SCHEMA: SettingsSection[] = [ { title: "Vehicle Configuration", @@ -8,16 +10,7 @@ export const SETTINGS_SCHEMA: SettingsSection[] = [ label: "Boards", path: "vehicle.boards", type: "multi-checkbox", - options: [ - "BCU", - "BMSL", - "HVSCU", - "HVSCU-Cabinet", - "LCU", - "PCU", - "VCU", - "BLCU", - ], + options: BOARD_NAMES as string[], }, ], }, diff --git a/frontend/testing-view/src/constants/variablesBadgeClasses.ts b/frontend/testing-view/src/constants/variablesBadgeClasses.ts index 6c4706a8c..4c1e7484f 100644 --- a/frontend/testing-view/src/constants/variablesBadgeClasses.ts +++ b/frontend/testing-view/src/constants/variablesBadgeClasses.ts @@ -1,4 +1,7 @@ -const variablesBadgeClasses = { +/** + * Classes for the badge showed at the left side of the variable item in the telemetry tab. + */ +export const variablesBadgeClasses = { float: "bg-sky-500/20 text-sky-400 border-sky-500/40 dark:bg-sky-500/15 dark:text-sky-300", integer: @@ -11,5 +14,3 @@ const variablesBadgeClasses = { unknown: "bg-slate-500/20 text-slate-400 border-slate-500/40 dark:bg-slate-500/15 dark:text-slate-300", }; - -export { variablesBadgeClasses }; diff --git a/frontend/testing-view/src/features/charts/components/ChartSettings.tsx b/frontend/testing-view/src/features/charts/components/ChartSettings.tsx index acec665b3..20913c495 100644 --- a/frontend/testing-view/src/features/charts/components/ChartSettings.tsx +++ b/frontend/testing-view/src/features/charts/components/ChartSettings.tsx @@ -6,6 +6,7 @@ import { PopoverTrigger, } from "@workspace/ui"; import { Settings2 } from "@workspace/ui/icons"; +import { config } from "../../../../config"; import { useStore } from "../../../store/store"; interface ChartSettingsProps { @@ -17,7 +18,7 @@ export const ChartSettings = ({ chartId }: ChartSettingsProps) => { const historyLimit = useStore( (s) => s.charts[activeWorkspace?.id ?? ""]?.find((c) => c.id === chartId) - ?.historyLimit ?? 200, + ?.historyLimit ?? config.FALLBACK_CHART_HISTORY_LIMIT, ); const setHistoryLimit = useStore((s) => s.setChartHistoryLimit); diff --git a/frontend/testing-view/src/features/charts/components/ChartSurface.tsx b/frontend/testing-view/src/features/charts/components/ChartSurface.tsx index f251bbd73..048d08f15 100644 --- a/frontend/testing-view/src/features/charts/components/ChartSurface.tsx +++ b/frontend/testing-view/src/features/charts/components/ChartSurface.tsx @@ -1,9 +1,11 @@ +import type { TelemetryPacket } from "@workspace/core"; import { Button } from "@workspace/ui"; import { ChevronLeft, ChevronRight, X } from "@workspace/ui/icons"; import { cn } from "@workspace/ui/lib"; import { memo, useEffect, useRef, useState } from "react"; import uPlot from "uplot"; import { useShallow } from "zustand/shallow"; +import { config } from "../../../../config"; import { useStore } from "../../../store/store"; import { COLORS } from "../constants/chartsColors"; import type { WorkspaceChartSeries } from "../types/charts"; @@ -31,7 +33,7 @@ export const ChartSurface = memo( const historyLimit = useStore( (s) => s.charts[activeWorkspace?.id ?? ""]?.find((c) => c.id === chartId) - ?.historyLimit ?? 200, + ?.historyLimit ?? config.FALLBACK_CHART_HISTORY_LIMIT, ); const packets = useStore( @@ -96,7 +98,7 @@ export const ChartSurface = memo( const opts: uPlot.Options = { width: containerRef.current.clientWidth - 32, - height: 250, + height: config.DEFAULT_CHART_HEIGHT, legend: { show: false, }, @@ -118,10 +120,10 @@ export const ChartSurface = memo( ...series.map((p, i) => ({ label: p.variable, stroke: COLORS[i % COLORS.length], - width: 2, + width: config.CHART_LINE_WIDTH, points: { show: true, - size: 2, + size: config.CHART_POINT_SIZE, fill: COLORS[i % COLORS.length], width: 0, }, @@ -167,11 +169,16 @@ export const ChartSurface = memo( // Update Chart Data (Runs only when 'data' actually changes) useEffect(() => { - const primaryPacket = packets[0]; - if (!primaryPacket || !uplotRef.current) return; + const activePackets = packets.filter( + (p): p is TelemetryPacket => p !== undefined, + ); + + if (activePackets.length === 0 || !uplotRef.current) return; + + const latestCount = Math.max(...activePackets.map((p) => p.count)); const snapshot = { - count: primaryPacket.count, + count: latestCount, values: series.map((p, i) => { const pkt = packets[i]; const m = pkt?.measurementUpdates?.[p.variable]; @@ -205,7 +212,6 @@ export const ChartSurface = memo( const range = currentXMax - currentXMin; const shift = range * 0.2; - // If the view was already at the "Present" before this update... if (currentXMax >= prevLatestCount) { const currentXMin = u.scales.x.min!; const range = currentXMax - currentXMin; @@ -228,7 +234,7 @@ export const ChartSurface = memo( uplotRef.current.setSize({ width: width, - height: 250, + height: config.DEFAULT_CHART_HEIGHT, }); } } @@ -241,14 +247,6 @@ export const ChartSurface = memo( }; }, []); - if (series.length === 0) { - return ( -
- Add a variable here to start visualizing data -
- ); - } - const latestCount = historyRef.current[historyRef.current.length - 1]?.count ?? 0; const currentMax = uplotRef.current?.scales.x.max ?? 0; @@ -256,7 +254,10 @@ export const ChartSurface = memo( return (
-
+
{/* Integrated Status Bar - Pinned Top Right */}
{/* Mode Indicator & Label */} diff --git a/frontend/testing-view/src/features/charts/components/SortableChart.tsx b/frontend/testing-view/src/features/charts/components/SortableChart.tsx index f19a20629..76efbfc37 100644 --- a/frontend/testing-view/src/features/charts/components/SortableChart.tsx +++ b/frontend/testing-view/src/features/charts/components/SortableChart.tsx @@ -1,7 +1,14 @@ import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; +import type { WorkspaceChartSeries } from "../types/charts"; import { TelemetryChart } from "./TelemetryChart"; -export function SortableChart({ id, series }: { id: string; series: any[] }) { + +interface SortableChartProps { + id: string; + series: WorkspaceChartSeries[]; +} + +export function SortableChart({ id, series }: SortableChartProps) { const { setNodeRef, attributes, diff --git a/frontend/testing-view/src/features/charts/components/TelemetryChart.tsx b/frontend/testing-view/src/features/charts/components/TelemetryChart.tsx index 3e84b721c..2dd8fa14d 100644 --- a/frontend/testing-view/src/features/charts/components/TelemetryChart.tsx +++ b/frontend/testing-view/src/features/charts/components/TelemetryChart.tsx @@ -1,3 +1,5 @@ +import type { DraggableAttributes } from "@dnd-kit/core"; +import type { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities"; import { GripVertical, Trash2 } from "@workspace/ui/icons"; import { cn } from "@workspace/ui/lib/utils"; import { useState } from "react"; @@ -12,8 +14,8 @@ interface TelemetryChartProps { series: WorkspaceChartSeries[]; isDragging: boolean; isOver?: boolean; - dragAttributes?: any; - dragListeners?: any; + dragAttributes?: DraggableAttributes; + dragListeners?: SyntheticListenerMap; } /** diff --git a/frontend/testing-view/src/features/charts/store/chartsSlice.ts b/frontend/testing-view/src/features/charts/store/chartsSlice.ts index aa1314c61..b74827008 100644 --- a/frontend/testing-view/src/features/charts/store/chartsSlice.ts +++ b/frontend/testing-view/src/features/charts/store/chartsSlice.ts @@ -1,4 +1,5 @@ import type { StateCreator } from "zustand"; +import { config } from "../../../../config"; import { EMPTY_ARRAY } from "../../../constants/emptyArray"; import type { Store } from "../../../store/store"; import type { @@ -67,7 +68,11 @@ export const createChartsSlice: StateCreator = ( ...state.charts, [workspaceId]: [ ...(state.charts[workspaceId] || []), - { id: newChartId, series: [], historyLimit: 200 }, + { + id: newChartId, + series: [], + historyLimit: config.DEFAULT_CHART_HISTORY_LIMIT, + }, ], }, })); diff --git a/frontend/testing-view/src/features/filtering/components/FilterCategoryItem.tsx b/frontend/testing-view/src/features/filtering/components/FilterCategoryItem.tsx index 51478c254..747f80aff 100644 --- a/frontend/testing-view/src/features/filtering/components/FilterCategoryItem.tsx +++ b/frontend/testing-view/src/features/filtering/components/FilterCategoryItem.tsx @@ -11,7 +11,11 @@ import { useStore } from "../../../store/store"; import type { BoardName } from "../../../types/data/board"; import { FilterItem } from "./FilterItem"; -export const FilterCategoryItem = ({ category }: { category: BoardName }) => { +interface FilterCategoryItemProps { + category: BoardName; +} + +export const FilterCategoryItem = ({ category }: FilterCategoryItemProps) => { const [isExpanded, setIsExpanded] = useState(false); const { scope } = useStore((s) => s.filterDialog); if (!scope) return null; diff --git a/frontend/testing-view/src/features/workspace/components/LoggerControl.tsx b/frontend/testing-view/src/features/workspace/components/LoggerControl.tsx index c4ac6d891..4b8e99820 100644 --- a/frontend/testing-view/src/features/workspace/components/LoggerControl.tsx +++ b/frontend/testing-view/src/features/workspace/components/LoggerControl.tsx @@ -2,7 +2,6 @@ import { Button, Separator } from "@workspace/ui"; import { Settings2 } from "@workspace/ui/icons"; import { cn } from "@workspace/ui/lib"; import { LOGGER_CONTROL_CONFIG } from "../../../constants/loggerControlConfig"; -import useConfirmClose from "../../../hooks/useConfirmClose"; import { useLogger } from "../../../hooks/useLogger"; import { useStore } from "../../../store/store"; import type { BoardName } from "../../../types/data/board"; @@ -15,8 +14,7 @@ interface LoggerControlProps { export const LoggerControl = ({ disabled }: LoggerControlProps) => { const { status, startLogging, stopLogging } = useLogger(); const openFilterDialog = useStore((s) => s.openFilterDialog); - - useConfirmClose(status === "recording"); + const filteredCount = useStore((state) => state.getFilteredCount("logs")); const handleToggle = () => { if (status === "loading") return; @@ -64,10 +62,10 @@ export const LoggerControl = ({ disabled }: LoggerControlProps) => { >
- + Logger - + {config.text}
@@ -91,12 +89,15 @@ export const LoggerControl = ({ disabled }: LoggerControlProps) => {
diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarContent.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarContent.tsx index 647240281..ff41e515e 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarContent.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarContent.tsx @@ -3,58 +3,83 @@ import { ResizablePanel, ResizablePanelGroup, } from "@workspace/ui"; -import { Activity } from "react"; import { useStore } from "../../../../store/store"; +import { CommandsSection } from "./sections/CommandsSection"; import MessagesSection from "./sections/MessagesSection"; import { NoneSelectedSection } from "./sections/NoneSelectedSection"; -import TabsSection from "./sections/TabsSection"; +import { TelemetrySection } from "./sections/TelemetrySection"; interface RightSidebarContentProps {} export const RightSidebarContent = ({}: RightSidebarContentProps) => { - const isTabsVisible = useStore((s) => s.isTabsVisible); + const isTelemetryVisible = useStore((s) => s.isTelemetryVisible); + const isCommandsVisible = useStore((s) => s.isCommandsVisible); const isMessagesVisible = useStore((s) => s.isMessagesVisible); const isHorizontal = useStore((s) => s.isHorizontal); - const isSplit = useStore((s) => s.isSplit); - const bothVisible = useStore((s) => s.getBothVisible()); const noneVisible = useStore((s) => s.getNoneVisible()); + const showCommandsMessages = isCommandsVisible || isMessagesVisible; + if (noneVisible) { return ; } - if (bothVisible) { - return ( - - - - + return ( + + {/* 1. Permanent Telemetry Column (Full Height) */} + {isTelemetryVisible && ( + <> + +
+ +
- {isMessagesVisible && } -
+ {showCommandsMessages && } + + )} - - - - - -
- ); - } + {/* 2. Right Column (Commands & Messages) */} + {showCommandsMessages && ( + + { + + {isCommandsVisible && ( + +
+ +
+
+ )} - return ( - <> - -
- -
-
- - -
- -
-
- + {isCommandsVisible && isMessagesVisible && ( + + )} + + {isMessagesVisible && ( + + + + )} +
+ } +
+ )} + ); }; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarHeader.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarHeader.tsx index a4bf54257..737f6ec91 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarHeader.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/RightSidebarHeader.tsx @@ -1,135 +1,73 @@ +import { Button } from "@workspace/ui"; import { - Button, - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "@workspace/ui"; -import { - Columns, - List, + Activity, MessageSquare, PanelBottom, PanelRight, + Terminal, X, } from "@workspace/ui/icons"; import { useStore } from "../../../../store/store"; +import { RightSidebarToggle } from "./RightSidebarToggle"; interface RightSidebarHeaderProps { onClose: () => void; } export const RightSidebarHeader = ({ onClose }: RightSidebarHeaderProps) => { - const isTabsVisible = useStore((s) => s.isTabsVisible); + const isTelemetryVisible = useStore((s) => s.isTelemetryVisible); + const isCommandsVisible = useStore((s) => s.isCommandsVisible); const isMessagesVisible = useStore((s) => s.isMessagesVisible); const isHorizontal = useStore((s) => s.isHorizontal); - const isSplit = useStore((s) => s.isSplit); - const bothVisible = useStore((s) => s.getBothVisible()); - const toggleTabs = useStore((s) => s.toggleTabs); + const toggleTelemetry = useStore((s) => s.toggleTelemetry); + const toggleCommands = useStore((s) => s.toggleCommands); const toggleMessages = useStore((s) => s.toggleMessages); const toggleLayout = useStore((s) => s.toggleLayout); - const toggleSplit = useStore((s) => s.toggleSplit); return (
- - - - - - -

- {isTabsVisible - ? "Hide Commands / Packets" - : "Show Commands / Packets"} -

-
-
+ {/* Telemetry Toggle */} + } + label={isTelemetryVisible ? "Hide Telemetry" : "Show Telemetry"} + /> + + {/* Commands Toggle */} + } + label={isCommandsVisible ? "Hide Commands" : "Show Commands"} + /> - - - - - -

{isMessagesVisible ? "Hide Messages" : "Show Messages"}

-
-
-
+ {/* Messages Toggle */} + } + label={isMessagesVisible ? "Hide Messages" : "Show Messages"} + />
- - - - - - -

{isSplit ? "Merge tabs" : "Split tabs into columns"}

-
-
- - - - - - -

- {isHorizontal - ? "Move messages to the bottom" - : "Move messages to the right"} -

-
-
-
+ + ) : ( + + ) + } + label={ + isHorizontal ? "Move messages to bottom" : "Move messages to right" + } + disabled={!isCommandsVisible || !isMessagesVisible} + /> + + +

{label}

+
+ + +); diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/CommandsSection.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/CommandsSection.tsx new file mode 100644 index 000000000..60b1a0876 --- /dev/null +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/CommandsSection.tsx @@ -0,0 +1,15 @@ +import { BOARD_NAMES } from "../../../../../constants/boards"; +import type { CommandCatalogItem } from "../../../../../types/data/commandCatalogItem"; +import { CommandItem } from "../tabs/commands/CommandItem"; +import { Tab } from "../tabs/Tab"; + +export const CommandsSection = () => ( + ( + + )} + /> +); diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/TabsSection.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/TabsSection.tsx deleted file mode 100644 index 63e86e18e..000000000 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/TabsSection.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import { - ResizableHandle, - ResizablePanel, - ResizablePanelGroup, - Tabs, - TabsContent, - TabsList, - TabsTrigger, -} from "@workspace/ui"; -import { BOARD_NAMES } from "../../../../../constants/boards"; -import { useStore } from "../../../../../store/store"; -import type { CommandCatalogItem } from "../../../../../types/data/commandCatalogItem"; -import type { TelemetryCatalogItem } from "../../../../../types/data/telemetryCatalogItem"; -import type { SidebarTab } from "../../../types/sidebar"; -import { CommandItem } from "../tabs/commands/CommandItem"; -import { Tab } from "../tabs/Tab"; -import { TelemetryItem } from "../tabs/telemetry/TelemetryItem"; - -interface TabsSectionProps { - isSplit: boolean; -} - -const TabsSection = ({ isSplit }: TabsSectionProps) => { - const activeTab = useStore((s) => s.getActiveTab()); - const setActiveTab = useStore((s) => s.setActiveTab); - - if (isSplit) { - return ( -
- {/* Header */} -
-
- - Packets & Commands - -
-
- - {/* Split view - both tabs side by side */} - - -
- ( - - )} - virtualized - /> -
-
- - - - -
- ( - - )} - /> -
-
-
-
- ); - } - - return ( - setActiveTab(value as SidebarTab)} - className="flex h-full flex-1 flex-col overflow-y-auto" - > - - Telemetry - Commands - - - - ( - - )} - virtualized - /> - - - - ( - - )} - /> - - - ); -}; - -export default TabsSection; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/TelemetrySection.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/TelemetrySection.tsx new file mode 100644 index 000000000..4798da54d --- /dev/null +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/sections/TelemetrySection.tsx @@ -0,0 +1,16 @@ +import { BOARD_NAMES } from "../../../../../constants/boards"; +import type { TelemetryCatalogItem } from "../../../../../types/data/telemetryCatalogItem"; +import { Tab } from "../tabs/Tab"; +import { TelemetryItem } from "../tabs/telemetry/TelemetryItem"; + +export const TelemetrySection = () => ( + ( + + )} + virtualized + /> +); diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/Tab.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/Tab.tsx index 7e5dfa44e..0bf90687f 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/Tab.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/Tab.tsx @@ -2,11 +2,11 @@ import { type ComponentType } from "react"; import { useStore } from "../../../../../store/store"; import type { CatalogItem } from "../../../../../types/common/item"; import type { BoardName } from "../../../../../types/data/board"; +import type { SidebarTab } from "../../../types/sidebar"; import { EmptyTab } from "./EmptyTab"; import { StandardList } from "./StandardList"; import { TabHeader } from "./TabHeader"; import { VirtualizedList } from "./VirtualizedList"; -import type { SidebarTab } from "../../../types/sidebar"; interface TabProps { title: string; diff --git a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/TabHeader.tsx b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/TabHeader.tsx index 13ff18450..08730d14c 100644 --- a/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/TabHeader.tsx +++ b/frontend/testing-view/src/features/workspace/components/rightSidebar/tabs/TabHeader.tsx @@ -14,7 +14,7 @@ export const TabHeader = ({ title, scope }: TabHeaderProps) => { const filteredCount = useStore((state) => state.getFilteredCount(scope)); return ( -
+

{title} diff --git a/frontend/testing-view/src/features/workspace/store/rightSidebarSlice.ts b/frontend/testing-view/src/features/workspace/store/rightSidebarSlice.ts index 29be2806e..4a8a13144 100644 --- a/frontend/testing-view/src/features/workspace/store/rightSidebarSlice.ts +++ b/frontend/testing-view/src/features/workspace/store/rightSidebarSlice.ts @@ -3,19 +3,18 @@ import type { Store } from "../../../store/store"; export interface RightSidebarSlice { // Section visibility - isTabsVisible: boolean; isMessagesVisible: boolean; - toggleTabs: () => void; + isTelemetryVisible: boolean; + isCommandsVisible: boolean; + toggleTelemetry: () => void; + toggleCommands: () => void; toggleMessages: () => void; // Layout settings isHorizontal: boolean; - isSplit: boolean; toggleLayout: () => void; - toggleSplit: () => void; // Computed values - getBothVisible: () => boolean; getNoneVisible: () => boolean; } @@ -26,18 +25,17 @@ export const createRightSidebarSlice: StateCreator< RightSidebarSlice > = (set, get) => ({ // Section visibility - isTabsVisible: true, + isTelemetryVisible: true, + isCommandsVisible: true, isMessagesVisible: true, - toggleTabs: () => set({ isTabsVisible: !get().isTabsVisible }), + toggleTelemetry: () => set({ isTelemetryVisible: !get().isTelemetryVisible }), + toggleCommands: () => set({ isCommandsVisible: !get().isCommandsVisible }), toggleMessages: () => set({ isMessagesVisible: !get().isMessagesVisible }), // Layout settings - isHorizontal: true, - isSplit: false, + isHorizontal: false, toggleLayout: () => set({ isHorizontal: !get().isHorizontal }), - toggleSplit: () => set({ isSplit: !get().isSplit }), // Computed values - getBothVisible: () => get().isTabsVisible && get().isMessagesVisible, - getNoneVisible: () => !get().isTabsVisible && !get().isMessagesVisible, + getNoneVisible: () => !get().isTelemetryVisible && !get().isMessagesVisible, }); diff --git a/frontend/testing-view/src/hooks/useAppConfigs.ts b/frontend/testing-view/src/hooks/useAppConfigs.ts index 24ceb704b..4a8d29d98 100644 --- a/frontend/testing-view/src/hooks/useAppConfigs.ts +++ b/frontend/testing-view/src/hooks/useAppConfigs.ts @@ -17,7 +17,7 @@ const useAppConfigs = (isConnected: boolean) => { } = useFetchConfig(backendUrl, "orderStructures"); useEffect(() => { - if (isConnected && packets !== null && commands !== null) { + if (isConnected) { refetchPackets(); refetchCommands(); } diff --git a/frontend/testing-view/src/hooks/useAppMode.ts b/frontend/testing-view/src/hooks/useAppMode.ts index 13eb13307..e390a0cc4 100644 --- a/frontend/testing-view/src/hooks/useAppMode.ts +++ b/frontend/testing-view/src/hooks/useAppMode.ts @@ -7,11 +7,12 @@ export function useAppMode( packets: PacketsData | null, commands: OrdersData | null, isLoading: boolean, - backendConnected: boolean, ) { const setAppMode = useStore((s) => s.setAppMode); const appMode = useStore((s) => s.appMode); const modeOverride = useStore((s) => s.modeOverride); + const isRestarting = useStore((s) => s.isRestarting); + const error = useStore((s) => s.error); const determineAppMode = useCallback(() => { // If there's an override, use it @@ -22,8 +23,9 @@ export function useAppMode( const isForceDev = import.meta.env.VITE_FORCE_DEV === "true"; const isDev = import.meta.env.DEV || isForceDev; + const hasData = !!(packets?.boards && commands?.boards); - const hasError = !hasData || !backendConnected; + const hasError = !hasData || error; // Debug logs // logger.testingView.log("[DEBUG] isDev", isDev); @@ -32,11 +34,20 @@ export function useAppMode( // logger.testingView.log("[DEBUG] backendConnected", backendConnected); // logger.testingView.log("[DEBUG] hasError", hasError); - if (isLoading) return "loading"; + if (isLoading || isRestarting) return "loading"; + + if (!packets || !commands) { + // If we have an explicit error, show it. + if (hasError) return "error"; + + // Otherwise, we are just waiting for data. + return "loading"; + } + if (!hasError) return "active"; if (isDev) return "mock"; return "error"; - }, [isLoading, packets, commands, backendConnected, modeOverride]); + }, [isLoading, packets, commands, isRestarting, modeOverride]); // Determine and set app mode useEffect(() => { diff --git a/frontend/testing-view/src/hooks/useConfirmClose.ts b/frontend/testing-view/src/hooks/useConfirmClose.ts deleted file mode 100644 index 01bf190d4..000000000 --- a/frontend/testing-view/src/hooks/useConfirmClose.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useEffect } from "react"; - -const useConfirmClose = (shouldLock: boolean) => { - useEffect(() => { - const handleBeforeUnload = (event: BeforeUnloadEvent) => { - if (shouldLock) { - event.preventDefault(); - event.returnValue = "true"; - return "true"; - } - }; - - window.addEventListener("beforeunload", handleBeforeUnload); - - return () => { - window.removeEventListener("beforeunload", handleBeforeUnload); - }; - }, [shouldLock]); -}; - -export default useConfirmClose; diff --git a/frontend/testing-view/src/hooks/useErrorHandler.ts b/frontend/testing-view/src/hooks/useErrorHandler.ts index 60f14b26c..fcba6be94 100644 --- a/frontend/testing-view/src/hooks/useErrorHandler.ts +++ b/frontend/testing-view/src/hooks/useErrorHandler.ts @@ -1,4 +1,5 @@ import { logger } from "@workspace/core"; +import useErrorSubscription from "@workspace/ui/hooks/webSocket/useErrorSubscription"; import { useEffect } from "react"; import { useStore } from "../store/store"; @@ -10,14 +11,23 @@ import { useStore } from "../store/store"; */ export function useErrorHandler() { const setError = useStore((s) => s.setError); - const setAppMode = useStore((s) => s.setAppMode); + + useErrorSubscription((err) => { + const isRestarting = useStore.getState().isRestarting; + + if (err instanceof CloseEvent && err.code == 1006 && isRestarting) { + logger.testingView.warn("Restarting app..."); + return; + } + + setError(err); + }); useEffect(() => { // Global error handler const handleError = (event: ErrorEvent) => { logger.testingView.error("Uncaught error:", event.error); setError(event.error); - setAppMode("error"); }; // Unhandled promise rejection handler @@ -42,7 +52,7 @@ export function useErrorHandler() { handleUnhandledRejection, ); }; - }, [setError, setAppMode]); + }, [setError]); /** * This functions prints the error and the error info in console using logger diff --git a/frontend/testing-view/src/hooks/useLogger.ts b/frontend/testing-view/src/hooks/useLogger.ts index 24bd69c4a..afa900c2d 100644 --- a/frontend/testing-view/src/hooks/useLogger.ts +++ b/frontend/testing-view/src/hooks/useLogger.ts @@ -1,6 +1,7 @@ import { socketService } from "@workspace/core"; import { useTopic } from "@workspace/ui/hooks"; import { useRef, useState } from "react"; +import { config } from "../../config"; import type { LoggerStatus } from "../types/common/logger"; export function useLogger() { @@ -17,7 +18,7 @@ export function useLogger() { timeoutRef.current = setTimeout(() => { setStatus("error"); timeoutRef.current = null; - }, 2000); + }, config.LOGGER_RESPONSE_TIMEOUT); }; useTopic("logger/response", (isLogging) => { diff --git a/frontend/testing-view/src/layout/AppLayout.tsx b/frontend/testing-view/src/layout/AppLayout.tsx index faf746950..d6a772cb1 100644 --- a/frontend/testing-view/src/layout/AppLayout.tsx +++ b/frontend/testing-view/src/layout/AppLayout.tsx @@ -1,6 +1,5 @@ import { SidebarInset, SidebarProvider } from "@workspace/ui/components"; import React, { useEffect } from "react"; -import Footer from "../components/Footer"; import Header from "../components/header/Header"; import AppSidebar from "../components/leftSidebar/AppSidebar"; import { SettingsDialog } from "../components/settings/SettingsDialog"; @@ -40,7 +39,6 @@ export const AppLayout = ({ children, backendConnected }: AppLayoutProps) => {
{children}
-

diff --git a/frontend/testing-view/src/lib/utils.ts b/frontend/testing-view/src/lib/utils.ts index 629263f43..fe0306338 100644 --- a/frontend/testing-view/src/lib/utils.ts +++ b/frontend/testing-view/src/lib/utils.ts @@ -1,4 +1,4 @@ -import { acronyms } from "../constants/acronyms"; +import { ACRONYMS } from "../constants/acronyms"; import { BOARD_NAMES } from "../constants/boards"; import { variablesBadgeClasses } from "../constants/variablesBadgeClasses"; import type { @@ -95,7 +95,7 @@ export const formatName = (name: string): string => { .map((word) => { const upperWord = word.toUpperCase(); // Check if word is an acronym - if (acronyms.includes(upperWord)) { + if (ACRONYMS.includes(upperWord as (typeof ACRONYMS)[number])) { return upperWord; } diff --git a/frontend/testing-view/src/main.tsx b/frontend/testing-view/src/main.tsx index 1aa646249..6ffe1cf7c 100644 --- a/frontend/testing-view/src/main.tsx +++ b/frontend/testing-view/src/main.tsx @@ -1,13 +1,13 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; -import { BrowserRouter } from "react-router"; +import { HashRouter } from "react-router"; import App from "./App.tsx"; import "./index.css"; createRoot(document.getElementById("root")!).render( - + - + , ); diff --git a/frontend/testing-view/src/pages/Testing.tsx b/frontend/testing-view/src/pages/Testing.tsx index b02ccbb9b..a39a6f72e 100644 --- a/frontend/testing-view/src/pages/Testing.tsx +++ b/frontend/testing-view/src/pages/Testing.tsx @@ -21,6 +21,13 @@ export const Testing = () => { const setIsSidebarVisible = useStore((s) => s.setTestingSidebarVisible); const charts = useStore((s) => s.getActiveWorkspaceCharts()); + const isCommandsVisible = useStore((s) => s.isCommandsVisible); + const isMessagesVisible = useStore((s) => s.isMessagesVisible); + const isHorizontal = useStore((s) => s.isHorizontal); + const isTelemetryVisible = useStore((s) => s.isTelemetryVisible); + + const showCommandsMessages = isCommandsVisible || isMessagesVisible; + useGlobalKeyBindings(); const { @@ -58,10 +65,22 @@ export const Testing = () => { onDragEnd={handleDragEnd} >
- + { {isSidebarVisible && ( <> - + setIsSidebarVisible(false)} /> diff --git a/frontend/testing-view/src/store/slices/appSlice.ts b/frontend/testing-view/src/store/slices/appSlice.ts index 662de7340..7afc5a42f 100644 --- a/frontend/testing-view/src/store/slices/appSlice.ts +++ b/frontend/testing-view/src/store/slices/appSlice.ts @@ -13,6 +13,9 @@ export interface AppSlice { error: Error | null; setError: (error: Error | null) => void; + isRestarting: boolean; + setRestarting: (isRestarting: boolean) => void; + // Mode override (only used in dev mode) modeOverride: AppMode | null; setModeOverride: (mode: AppMode | null) => void; @@ -53,6 +56,10 @@ export const createAppSlice: StateCreator = (set) => ({ error: null, setError: (error) => set({ error }), + // Happens when we restart the backend on config change + isRestarting: false, + setRestarting: (isRestarting) => set({ isRestarting }), + // Mode override (only used in dev mode) modeOverride: null, setModeOverride: (mode) => set({ modeOverride: mode }), diff --git a/frontend/testing-view/src/store/slices/messagesSlice.ts b/frontend/testing-view/src/store/slices/messagesSlice.ts index e2ff88792..0a9b2d898 100644 --- a/frontend/testing-view/src/store/slices/messagesSlice.ts +++ b/frontend/testing-view/src/store/slices/messagesSlice.ts @@ -1,4 +1,5 @@ import type { StateCreator } from "zustand"; +import { config } from "../../../config"; import type { Message } from "../../types/data/message"; import type { Store } from "../store"; @@ -8,15 +9,16 @@ export interface MessagesSlice { clearMessages: () => void; } -const MAX_MESSAGES = 200; - export const createMessagesSlice: StateCreator = ( set, ) => ({ messages: [], addMessage: (message) => set((state) => ({ - messages: [message, ...state.messages].slice(0, MAX_MESSAGES), + messages: [message, ...state.messages].slice( + 0, + config.MAX_MESSAGES_COUNT, + ), })), clearMessages: () => set({ messages: [] }), }); diff --git a/frontend/testing-view/src/store/store.ts b/frontend/testing-view/src/store/store.ts index 9ed8695ee..26c3602f8 100644 --- a/frontend/testing-view/src/store/store.ts +++ b/frontend/testing-view/src/store/store.ts @@ -73,7 +73,7 @@ export const useStore = create()( // Workspace UI state activeTab: state.activeTab, - tabFilters: state.workspaceFilters, + workspaceFilters: state.workspaceFilters, }), }, ), diff --git a/frontend/testing-view/src/types/common/config.ts b/frontend/testing-view/src/types/common/config.ts index 0f2a862fa..762205aab 100644 --- a/frontend/testing-view/src/types/common/config.ts +++ b/frontend/testing-view/src/types/common/config.ts @@ -6,8 +6,8 @@ export type ConfigField = string | string[] | number | boolean; /** * Configuration type used in app slice to store values from the form. */ -export interface ConfigData { +export type ConfigData = { [section: string]: { [field: string]: ConfigField; }; -} +}; diff --git a/frontend/testing-view/src/types/common/connection.ts b/frontend/testing-view/src/types/common/connection.ts index 56a4c4445..9795d945a 100644 --- a/frontend/testing-view/src/types/common/connection.ts +++ b/frontend/testing-view/src/types/common/connection.ts @@ -1,10 +1,10 @@ /** * One connection to the vehicle. */ -export interface Connection { +export type Connection = { /** Name of the connection */ name: string; /** Whether the connection is established */ isConnected: boolean; -} +}; diff --git a/frontend/testing-view/src/types/common/item.ts b/frontend/testing-view/src/types/common/item.ts index fd320b5ef..3acf4445d 100644 --- a/frontend/testing-view/src/types/common/item.ts +++ b/frontend/testing-view/src/types/common/item.ts @@ -1,18 +1,18 @@ /** * Raw item from the catalog (commands or telemetry) as it arrives from the backend. */ -export interface Item { +export type Item = { /** Unique (If firmware fixes it) ID of the item from ADJ */ id: number; /** Name of the item from ADJ */ name: string; -} +}; /** * Item from the catalog (commands or telemetry) with my label. */ -export interface CatalogItem extends Item { +export type CatalogItem = Item & { /** Label of the item generated from the name on frontend startup */ label: string; -} +}; diff --git a/frontend/testing-view/src/types/common/settings.ts b/frontend/testing-view/src/types/common/settings.ts index bbe3e20df..10a744b44 100644 --- a/frontend/testing-view/src/types/common/settings.ts +++ b/frontend/testing-view/src/types/common/settings.ts @@ -27,32 +27,33 @@ export interface FieldProps { /** * One item of the settings schema from config.toml. */ -export interface SettingField { - /** Label of the field */ +export type SettingField = { + /** Label of the field. The text showed above the field itself. */ label: string; - /** Type of the field */ + /** Type of the field. It affects what kind of component is showed in the interface.\ + * **E.g.** checkboxes or multiple choice section. */ type: FieldType; /** Options of the field */ options?: string[]; - /** Placeholder of the field */ + /** Placeholder of the field. The text showed inside the field when it is empty. */ placeholder?: string; /** Path to the field in the config.toml configuration.\ * **Note:** it should match config.toml section and variable name.\ * **E.g.** `vehicle.boards` or `adj.branch`. */ path: string; -} +}; /** * One section of the settings from config.toml. */ -export interface SettingsSection { +export type SettingsSection = { /** Title of the section */ title: string; /** Fields of the section */ fields: SettingField[]; -} +}; diff --git a/frontend/testing-view/src/types/data/board.ts b/frontend/testing-view/src/types/data/board.ts index 4c92463ad..421eabc3a 100644 --- a/frontend/testing-view/src/types/data/board.ts +++ b/frontend/testing-view/src/types/data/board.ts @@ -10,36 +10,36 @@ export type BoardName = string; /** * Common properties of boards. */ -export interface BoardData { +export type BoardData = { name: BoardName; -} +}; /** * Basically ADJ telemetry packets definition from the backend. */ -export interface BoardPacketsData extends BoardData { +export type BoardPacketsData = BoardData & { /** List of telemetry packets (also referred as packets in some places) */ packets: TelemetryCatalogItem[]; -} +}; /** * Basically ADJ commands definition from the backend. */ -export interface BoardOrdersData extends BoardData { +export type BoardOrdersData = BoardData & { /** List of commands (also referred as orders in some places) */ orders: CommandCatalogItem[]; -} +}; /** * Final type of the result of the packets fetching. */ -export interface PacketsData { +export type PacketsData = { boards: BoardPacketsData[]; -} +}; /** * Final type of the result of the commands fetching. */ -export interface OrdersData { +export type OrdersData = { boards: BoardOrdersData[]; -} +}; diff --git a/frontend/testing-view/src/types/data/commandCatalogItem.ts b/frontend/testing-view/src/types/data/commandCatalogItem.ts index 923b2fae4..71d9aa193 100644 --- a/frontend/testing-view/src/types/data/commandCatalogItem.ts +++ b/frontend/testing-view/src/types/data/commandCatalogItem.ts @@ -3,42 +3,42 @@ import type { CatalogItem, Item } from "../common/item"; /** * Params of a command. */ -export interface CommandParameter { +export type CommandParameter = { kind: string; id: string; name: string; type: string; -} +}; /** * Numeric parameter has safe and warning ranges. */ -export interface NumericCommandParameter extends CommandParameter { +export type NumericCommandParameter = CommandParameter & { safeRange: (number | null)[]; warningRange: (number | null)[]; -} +}; /** * Enum parameter has options. */ -export interface EnumCommandParameter extends CommandParameter { +export type EnumCommandParameter = CommandParameter & { options: string[]; -} +}; /** * Map of parameter id to parameter type of a command.\ * Each parameter can be either numeric or enum. */ -export interface CommandParameters { +export type CommandParameters = { [key: string]: NumericCommandParameter | EnumCommandParameter; -} +}; /** * Definition of a command packet as it arrives from the backend. */ -export interface RawOrder extends Item { +export type RawOrder = Item & { fields: CommandParameters; -} +}; /** * Definition of a command catalog item as it arrives from the backend and my label. diff --git a/frontend/testing-view/src/types/data/message.ts b/frontend/testing-view/src/types/data/message.ts index 7d8c2998a..45cbe70e7 100644 --- a/frontend/testing-view/src/types/data/message.ts +++ b/frontend/testing-view/src/types/data/message.ts @@ -6,7 +6,7 @@ import type { BoardName } from "./board"; * Because seconds basically don't tell us anything in the context of high-frequency systems * and counter only means uniqueness considering the same packet type */ -export interface MessageTimestamp { +export type MessageTimestamp = { /** Counter which is incremented by 1 every time packet of one type is generated,\ * but it can be the same between different packet types */ @@ -17,7 +17,7 @@ export interface MessageTimestamp { day: number; month: number; year: number; -} +}; /** * Possible payloads for a `ok`, `warning` and `fault` messages. @@ -39,7 +39,7 @@ export type DetailedPayload = /** * Definition of a MessagePacket as it arrives from the backend. */ -export interface MessagePacket { +export type MessagePacket = { /** Message type */ kind: "info" | "warning" | "fault" | "ok"; /** For `info` messages, the payload is a string. @@ -49,12 +49,12 @@ export interface MessagePacket { board: BoardName; name: string; timestamp: MessageTimestamp; -} +}; /** * Message definition on frontend. */ -export interface Message extends MessagePacket { +export type Message = MessagePacket & { /** Unique message id generated on frontend for React keys */ id: string; -} +}; diff --git a/frontend/testing-view/src/types/data/telemetryCatalogItem.ts b/frontend/testing-view/src/types/data/telemetryCatalogItem.ts index a51593d90..25e98ec11 100644 --- a/frontend/testing-view/src/types/data/telemetryCatalogItem.ts +++ b/frontend/testing-view/src/types/data/telemetryCatalogItem.ts @@ -3,12 +3,12 @@ import type { CatalogItem, Item } from "../common/item"; /** * Variable definition. Sometimes also called Measurement. This is the same thing. */ -export interface Variable { +export type Variable = { id: string; name: string; type: string; units?: string; -} +}; export interface NumericVariable extends Variable { safeRange: (number | null)[]; @@ -29,14 +29,14 @@ export type TelemetryVariable = /** * Definition of a telemetry packet as it arrives from the backend. */ -export interface RawPacket extends Item { +export type RawPacket = Item & { count: number; cycleTime: number; type: string; measurements: TelemetryVariable[]; /** Currently unused (always equals to "000000" placeholder on the backend) */ hexValue: string; -} +}; /** * Definition of a telemetry catalog item as it arrives from the backend and my label. diff --git a/frontend/testing-view/src/types/data/transformedBoards.ts b/frontend/testing-view/src/types/data/transformedBoards.ts index 38e9658ea..bfd76b025 100644 --- a/frontend/testing-view/src/types/data/transformedBoards.ts +++ b/frontend/testing-view/src/types/data/transformedBoards.ts @@ -6,7 +6,7 @@ import type { TelemetryCatalogItem } from "./telemetryCatalogItem"; * Final result of the useBoardData hook and boards transformation.\ * This is the format I actually use */ -export interface TransformedBoards { +export type TransformedBoards = { /** Map of board name to list of telemetry catalog items */ telemetryCatalog: Record; @@ -15,4 +15,4 @@ export interface TransformedBoards { /** Set of all available boards (not used for now) */ boards: Set; -} +}; diff --git a/frontend/testing-view/vite.config.ts b/frontend/testing-view/vite.config.ts index 4093b0cc7..41187a938 100644 --- a/frontend/testing-view/vite.config.ts +++ b/frontend/testing-view/vite.config.ts @@ -5,6 +5,7 @@ import { defineConfig } from "vite"; // https://vite.dev/config/ export default defineConfig({ plugins: [react(), tailwindcss()], + base: "./", server: { port: 9000, host: true, diff --git a/package.json b/package.json index dab8718ac..942aad474 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,9 @@ "dev": "turbo dev", "dev:main": "turbo dev:main", "build": "turbo build", + "build:win": "pnpm --filter electron-app build:win", + "build:linux": "pnpm --filter electron-app build:linux", + "build:mac": "pnpm --filter electron-app build:mac", "lint": "turbo lint", "preview": "turbo preview", "test": "turbo test", @@ -13,10 +16,10 @@ "devDependencies": { "@workspace/eslint-config": "workspace:*", "@workspace/typescript-config": "workspace:*", - "prettier": "^3.7.4", - "prettier-plugin-tailwindcss": "^0.6.14", - "turbo": "^2.7.1", - "typescript": "5.7.3" + "prettier": "^3.8.1", + "prettier-plugin-tailwindcss": "^0.7.2", + "turbo": "^2.8.3", + "typescript": "5.9.3" }, "packageManager": "pnpm@10.26.0", "engines": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a08e9d060..9698bd788 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,17 +15,17 @@ importers: specifier: workspace:* version: link:frontend/frontend-kit/typescript-config prettier: - specifier: ^3.7.4 - version: 3.7.4 + specifier: ^3.8.1 + version: 3.8.1 prettier-plugin-tailwindcss: - specifier: ^0.6.14 - version: 0.6.14(prettier@3.7.4) + specifier: ^0.7.2 + version: 0.7.2(prettier@3.8.1) turbo: - specifier: ^2.7.1 - version: 2.7.1 + specifier: ^2.8.3 + version: 2.8.3 typescript: - specifier: 5.7.3 - version: 5.7.3 + specifier: 5.9.3 + version: 5.9.3 backend: {} @@ -35,24 +35,30 @@ importers: specifier: ^2.2.5 version: 2.2.5 electron-store: - specifier: ^8.1.0 - version: 8.2.0 + specifier: ^11.0.2 + version: 11.0.2 + electron-updater: + specifier: ^6.7.3 + version: 6.7.3 + picocolors: + specifier: ^1.1.1 + version: 1.1.1 devDependencies: '@vitest/coverage-v8': - specifier: ^4.0.14 - version: 4.0.16(vitest@4.0.16(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2)) + specifier: ^4.0.18 + version: 4.0.18(vitest@4.0.18(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)) asar: specifier: ^3.2.0 version: 3.2.0 electron: - specifier: ^28.0.0 - version: 28.3.3 + specifier: ^40.1.0 + version: 40.1.0 electron-builder: - specifier: ^24.9.1 - version: 24.13.3(electron-builder-squirrel-windows@24.13.3) + specifier: ^26.7.0 + version: 26.7.0(electron-builder-squirrel-windows@24.13.3) vitest: - specifier: ^4.0.14 - version: 4.0.16(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2) + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2) frontend/frontend-kit/core: dependencies: @@ -64,50 +70,50 @@ importers: specifier: workspace:* version: link:../esling-config eslint: - specifier: ^9.39.1 + specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) frontend/frontend-kit/esling-config: devDependencies: '@eslint/js': - specifier: ^9.20.1 + specifier: ^9.39.2 version: 9.39.2 '@typescript-eslint/eslint-plugin': - specifier: ^8.24.1 - version: 8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.54.0 + version: 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': - specifier: ^8.24.1 - version: 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.54.0 + version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: - specifier: ^9.20.1 + specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.2(eslint@9.39.2(jiti@2.6.1)) + specifier: ^10.1.8 + version: 10.1.8(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-only-warn: specifier: ^1.1.0 version: 1.1.0 eslint-plugin-react: - specifier: ^7.37.4 + specifier: ^7.37.5 version: 7.37.5(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react-hooks: - specifier: ^5.1.0 - version: 5.2.0(eslint@9.39.2(jiti@2.6.1)) + specifier: ^7.0.1 + version: 7.0.1(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react-refresh: - specifier: ^0.4.19 - version: 0.4.26(eslint@9.39.2(jiti@2.6.1)) + specifier: ^0.5.0 + version: 0.5.0(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-turbo: - specifier: ^2.4.2 - version: 2.7.1(eslint@9.39.2(jiti@2.6.1))(turbo@2.8.2) + specifier: ^2.8.3 + version: 2.8.3(eslint@9.39.2(jiti@2.6.1))(turbo@2.8.3) globals: - specifier: ^15.15.0 - version: 15.15.0 + specifier: ^17.3.0 + version: 17.3.0 typescript: - specifier: ^5.7.3 + specifier: ^5.9.3 version: 5.9.3 typescript-eslint: - specifier: ^8.24.1 - version: 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.54.0 + version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) frontend/frontend-kit/typescript-config: {} @@ -115,37 +121,37 @@ importers: dependencies: '@radix-ui/react-checkbox': specifier: ^1.3.3 - version: 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-collapsible': specifier: ^1.1.12 - version: 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-dialog': specifier: ^1.1.15 - version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-dropdown-menu': specifier: ^2.1.16 - version: 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-label': specifier: ^2.1.8 - version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-popover': specifier: ^1.1.15 - version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-select': specifier: ^2.2.6 - version: 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-separator': specifier: ^1.1.8 - version: 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-slot': specifier: ^1.2.4 - version: 1.2.4(@types/react@19.2.7)(react@19.2.3) + version: 1.2.4(@types/react@19.2.11)(react@19.2.4) '@radix-ui/react-tabs': specifier: ^1.1.13 - version: 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-tooltip': specifier: ^1.2.8 - version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@workspace/core': specifier: workspace:* version: link:../core @@ -156,51 +162,51 @@ importers: specifier: ^2.1.1 version: 2.1.1 lucide-react: - specifier: ^0.475.0 - version: 0.475.0(react@19.2.3) + specifier: ^0.563.0 + version: 0.563.0(react@19.2.4) next-themes: - specifier: ^0.4.4 - version: 0.4.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: - specifier: ^19.2.3 - version: 19.2.3 + specifier: ^19.2.4 + version: 19.2.4 react-dom: - specifier: ^19.2.3 - version: 19.2.3(react@19.2.3) + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) react-resizable-panels: - specifier: ^3.0.6 - version: 3.0.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^4.6.0 + version: 4.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) rxjs: specifier: ^7.8.2 version: 7.8.2 tailwind-merge: - specifier: ^3.0.1 + specifier: ^3.4.0 version: 3.4.0 tw-animate-css: - specifier: ^1.2.4 + specifier: ^1.4.0 version: 1.4.0 zod: - specifier: ^3.24.2 - version: 3.25.76 + specifier: ^4.3.6 + version: 4.3.6 zustand: specifier: ^5.0.11 - version: 5.0.11(@types/react@19.2.7)(immer@11.1.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)) + version: 5.0.11(@types/react@19.2.11)(immer@11.1.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: '@tailwindcss/postcss': - specifier: ^4.0.8 + specifier: ^4.1.18 version: 4.1.18 '@turbo/gen': - specifier: ^2.4.2 - version: 2.7.1(@swc/core@1.15.7)(@types/node@20.19.27)(typescript@5.9.3) + specifier: ^2.8.3 + version: 2.8.3(@swc/core@1.15.11)(@types/node@25.2.0)(typescript@5.9.3) '@types/node': - specifier: ^20 - version: 20.19.27 + specifier: ^25.2.0 + version: 25.2.0 '@types/react': - specifier: ^19.2.7 - version: 19.2.7 + specifier: ^19.2.11 + version: 19.2.11 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.7) + version: 19.2.3(@types/react@19.2.11) '@workspace/eslint-config': specifier: workspace:* version: link:../esling-config @@ -208,41 +214,41 @@ importers: specifier: workspace:* version: link:../typescript-config eslint: - specifier: ^9.39.1 + specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) tailwindcss: - specifier: ^4.0.8 + specifier: ^4.1.18 version: 4.1.18 typescript: - specifier: ^5.7.3 + specifier: ^5.9.3 version: 5.9.3 frontend/testing-view: dependencies: '@dnd-kit/core': specifier: ^6.3.1 - version: 6.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@dnd-kit/sortable': specifier: ^10.0.0 - version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3) + version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4) '@dnd-kit/utilities': specifier: ^3.2.2 - version: 3.2.2(react@19.2.3) + version: 3.2.2(react@19.2.4) '@radix-ui/react-slot': specifier: ^1.2.4 - version: 1.2.4(@types/react@19.2.7)(react@19.2.3) + version: 1.2.4(@types/react@19.2.11)(react@19.2.4) '@tailwindcss/vite': - specifier: ^4.1.17 - version: 4.1.18(vite@7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2)) + specifier: ^4.1.18 + version: 4.1.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)) '@tanstack/react-virtual': - specifier: ^3.13.14 - version: 3.13.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^3.13.18 + version: 3.13.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@types/lodash': specifier: ^4.17.23 version: 4.17.23 '@vitejs/plugin-react-swc': - specifier: ^4.2.2 - version: 4.2.2(vite@7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2)) + specifier: ^4.2.3 + version: 4.2.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)) '@workspace/core': specifier: workspace:* version: link:../frontend-kit/core @@ -250,36 +256,36 @@ importers: specifier: workspace:* version: link:../frontend-kit/ui lodash: - specifier: ^4.17.21 - version: 4.17.21 + specifier: ^4.17.23 + version: 4.17.23 react: - specifier: ^19.2.3 - version: 19.2.3 + specifier: ^19.2.4 + version: 19.2.4 react-dom: - specifier: ^19.2.3 - version: 19.2.3(react@19.2.3) + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) react-router: specifier: ^7.13.0 - version: 7.13.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tailwindcss: - specifier: ^4.1.17 + specifier: ^4.1.18 version: 4.1.18 uplot: specifier: ^1.6.32 version: 1.6.32 vitest: - specifier: ^4.0.16 - version: 4.0.16(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2) + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2) zustand: specifier: ^5.0.11 - version: 5.0.11(@types/react@19.2.7)(immer@11.1.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)) + version: 5.0.11(@types/react@19.2.11)(immer@11.1.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: '@types/react': - specifier: ^19.2.7 - version: 19.2.7 + specifier: ^19.2.11 + version: 19.2.11 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.7) + version: 19.2.3(@types/react@19.2.11) '@workspace/eslint-config': specifier: workspace:^ version: link:../frontend-kit/esling-config @@ -287,17 +293,17 @@ importers: specifier: workspace:* version: link:../frontend-kit/typescript-config eslint: - specifier: ^9.25.0 + specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) globals: - specifier: ^15.15.0 - version: 15.15.0 + specifier: ^17.3.0 + version: 17.3.0 typescript: specifier: ^5.9.3 version: 5.9.3 vite: - specifier: ^7.2.4 - version: 7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2) + specifier: ^7.3.1 + version: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2) packet-sender: {} @@ -310,6 +316,40 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -318,17 +358,33 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/runtime-corejs3@7.28.4': - resolution: {integrity: sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==} + '@babel/runtime-corejs3@7.29.0': + resolution: {integrity: sha512-TgUkdp71C9pIbBcHudc+gXZnihEDOjUAmXO1VO4HHGES7QLZcShR0stfKIxLSNIYx2fqhmJChOjm/wkF8wv4gA==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@1.0.2': @@ -370,23 +426,49 @@ packages: engines: {node: '>=10.12.0'} hasBin: true + '@electron/fuses@1.8.0': + resolution: {integrity: sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==} + hasBin: true + '@electron/get@2.0.3': resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} engines: {node: '>=12'} + '@electron/get@3.1.0': + resolution: {integrity: sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==} + engines: {node: '>=14'} + '@electron/notarize@2.2.1': resolution: {integrity: sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg==} engines: {node: '>= 10.0.0'} + '@electron/notarize@2.5.0': + resolution: {integrity: sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==} + engines: {node: '>= 10.0.0'} + '@electron/osx-sign@1.0.5': resolution: {integrity: sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==} engines: {node: '>=12.0.0'} hasBin: true + '@electron/osx-sign@1.3.3': + resolution: {integrity: sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==} + engines: {node: '>=12.0.0'} + hasBin: true + + '@electron/rebuild@4.0.3': + resolution: {integrity: sha512-u9vpTHRMkOYCs/1FLiSVAFZ7FbjsXK+bQuzviJZa+lG7BHZl1nz52/IcGvwa3sk80/fc3llutBkbCq10Vh8WQA==} + engines: {node: '>=22.12.0'} + hasBin: true + '@electron/universal@1.5.1': resolution: {integrity: sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw==} engines: {node: '>=8.6'} + '@electron/universal@2.0.3': + resolution: {integrity: sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==} + engines: {node: '>=16.4'} + '@esbuild/aix-ppc64@0.27.2': resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} engines: {node: '>=18'} @@ -543,8 +625,8 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.9.0': - resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -581,14 +663,14 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@floating-ui/core@1.7.3': - resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + '@floating-ui/core@1.7.4': + resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} - '@floating-ui/dom@1.7.4': - resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + '@floating-ui/dom@1.7.5': + resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} - '@floating-ui/react-dom@2.1.6': - resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + '@floating-ui/react-dom@2.1.7': + resolution: {integrity: sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' @@ -615,10 +697,31 @@ packages: '@iarna/toml@2.2.5': resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.1': + resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -642,6 +745,10 @@ packages: resolution: {integrity: sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==} engines: {node: '>= 10'} + '@malept/cross-spawn-promise@2.0.0': + resolution: {integrity: sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==} + engines: {node: '>= 12.13.0'} + '@malept/flatpak-bundler@0.4.0': resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} engines: {node: '>= 10.0.0'} @@ -658,6 +765,14 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@npmcli/agent@3.0.0': + resolution: {integrity: sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==} + engines: {node: ^18.17.0 || >=20.5.0} + + '@npmcli/fs@4.0.0': + resolution: {integrity: sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==} + engines: {node: ^18.17.0 || >=20.5.0} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -1092,116 +1207,131 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - '@rolldown/pluginutils@1.0.0-beta.47': - resolution: {integrity: sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==} + '@rolldown/pluginutils@1.0.0-rc.2': + resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} - '@rollup/rollup-android-arm-eabi@4.54.0': - resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==} + '@rollup/rollup-android-arm-eabi@4.57.1': + resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.54.0': - resolution: {integrity: sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==} + '@rollup/rollup-android-arm64@4.57.1': + resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.54.0': - resolution: {integrity: sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==} + '@rollup/rollup-darwin-arm64@4.57.1': + resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.54.0': - resolution: {integrity: sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==} + '@rollup/rollup-darwin-x64@4.57.1': + resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.54.0': - resolution: {integrity: sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==} + '@rollup/rollup-freebsd-arm64@4.57.1': + resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.54.0': - resolution: {integrity: sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==} + '@rollup/rollup-freebsd-x64@4.57.1': + resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.54.0': - resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': + resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.54.0': - resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==} + '@rollup/rollup-linux-arm-musleabihf@4.57.1': + resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.54.0': - resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==} + '@rollup/rollup-linux-arm64-gnu@4.57.1': + resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.54.0': - resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==} + '@rollup/rollup-linux-arm64-musl@4.57.1': + resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.54.0': - resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==} + '@rollup/rollup-linux-loong64-gnu@4.57.1': + resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.57.1': + resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.54.0': - resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==} + '@rollup/rollup-linux-ppc64-gnu@4.57.1': + resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.57.1': + resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.54.0': - resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==} + '@rollup/rollup-linux-riscv64-gnu@4.57.1': + resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.54.0': - resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==} + '@rollup/rollup-linux-riscv64-musl@4.57.1': + resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.54.0': - resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==} + '@rollup/rollup-linux-s390x-gnu@4.57.1': + resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.54.0': - resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==} + '@rollup/rollup-linux-x64-gnu@4.57.1': + resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.54.0': - resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==} + '@rollup/rollup-linux-x64-musl@4.57.1': + resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.54.0': - resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==} + '@rollup/rollup-openbsd-x64@4.57.1': + resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.57.1': + resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.54.0': - resolution: {integrity: sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==} + '@rollup/rollup-win32-arm64-msvc@4.57.1': + resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.54.0': - resolution: {integrity: sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==} + '@rollup/rollup-win32-ia32-msvc@4.57.1': + resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.54.0': - resolution: {integrity: sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==} + '@rollup/rollup-win32-x64-gnu@4.57.1': + resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.54.0': - resolution: {integrity: sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==} + '@rollup/rollup-win32-x64-msvc@4.57.1': + resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==} cpu: [x64] os: [win32] @@ -1212,68 +1342,68 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@swc/core-darwin-arm64@1.15.7': - resolution: {integrity: sha512-+hNVUfezUid7LeSHqnhoC6Gh3BROABxjlDNInuZ/fie1RUxaEX4qzDwdTgozJELgHhvYxyPIg1ro8ibnKtgO4g==} + '@swc/core-darwin-arm64@1.15.11': + resolution: {integrity: sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.15.7': - resolution: {integrity: sha512-ZAFuvtSYZTuXPcrhanaD5eyp27H8LlDzx2NAeVyH0FchYcuXf0h5/k3GL9ZU6Jw9eQ63R1E8KBgpXEJlgRwZUQ==} + '@swc/core-darwin-x64@1.15.11': + resolution: {integrity: sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.15.7': - resolution: {integrity: sha512-K3HTYocpqnOw8KcD8SBFxiDHjIma7G/X+bLdfWqf+qzETNBrzOub/IEkq9UaeupaJiZJkPptr/2EhEXXWryS/A==} + '@swc/core-linux-arm-gnueabihf@1.15.11': + resolution: {integrity: sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.15.7': - resolution: {integrity: sha512-HCnVIlsLnCtQ3uXcXgWrvQ6SAraskLA9QJo9ykTnqTH6TvUYqEta+TdTdGjzngD6TOE7XjlAiUs/RBtU8Z0t+Q==} + '@swc/core-linux-arm64-gnu@1.15.11': + resolution: {integrity: sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.15.7': - resolution: {integrity: sha512-/OOp9UZBg4v2q9+x/U21Jtld0Wb8ghzBScwhscI7YvoSh4E8RALaJ1msV8V8AKkBkZH7FUAFB7Vbv0oVzZsezA==} + '@swc/core-linux-arm64-musl@1.15.11': + resolution: {integrity: sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.15.7': - resolution: {integrity: sha512-VBbs4gtD4XQxrHuQ2/2+TDZpPQQgrOHYRnS6SyJW+dw0Nj/OomRqH+n5Z4e/TgKRRbieufipeIGvADYC/90PYQ==} + '@swc/core-linux-x64-gnu@1.15.11': + resolution: {integrity: sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.15.7': - resolution: {integrity: sha512-kVuy2unodso6p0rMauS2zby8/bhzoGRYxBDyD6i2tls/fEYAE74oP0VPFzxIyHaIjK1SN6u5TgvV9MpyJ5xVug==} + '@swc/core-linux-x64-musl@1.15.11': + resolution: {integrity: sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.15.7': - resolution: {integrity: sha512-uddYoo5Xmo1XKLhAnh4NBIyy5d0xk33x1sX3nIJboFySLNz878ksCFCZ3IBqrt1Za0gaoIWoOSSSk0eNhAc/sw==} + '@swc/core-win32-arm64-msvc@1.15.11': + resolution: {integrity: sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.15.7': - resolution: {integrity: sha512-rqq8JjNMLx3QNlh0aPTtN/4+BGLEHC94rj9mkH1stoNRf3ra6IksNHMHy+V1HUqElEgcZyx+0yeXx3eLOTcoFw==} + '@swc/core-win32-ia32-msvc@1.15.11': + resolution: {integrity: sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.15.7': - resolution: {integrity: sha512-4BK06EGdPnuplgcNhmSbOIiLdRgHYX3v1nl4HXo5uo4GZMfllXaCyBUes+0ePRfwbn9OFgVhCWPcYYjMT6hycQ==} + '@swc/core-win32-x64-msvc@1.15.11': + resolution: {integrity: sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.15.7': - resolution: {integrity: sha512-kTGB8XI7P+pTKW83tnUEDVP4zduF951u3UAOn5eTi0vyW6MvL56A3+ggMdfuVFtDI0/DsbSzf5z34HVBbuScWw==} + '@swc/core@1.15.11': + resolution: {integrity: sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -1384,14 +1514,14 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 - '@tanstack/react-virtual@3.13.14': - resolution: {integrity: sha512-WG0d7mBD54eA7dgA3+sO5csS0B49QKqM6Gy5Rf31+Oq/LTKROQSao9m2N/vz1IqVragOKU5t5k1LAcqh/DfTxw==} + '@tanstack/react-virtual@3.13.18': + resolution: {integrity: sha512-dZkhyfahpvlaV0rIKnvQiVoWPyURppl6w4m9IwMDpuIjcJ1sD9YGWrt0wISvgU7ewACXx2Ct46WPgI6qAD4v6A==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/virtual-core@3.13.14': - resolution: {integrity: sha512-b5Uvd8J2dc7ICeX9SRb/wkCxWk7pUwN214eEPAQsqrsktSKTCmyLxOQWSMgogBByXclZeAdgZ3k4o0fIYUIBqQ==} + '@tanstack/virtual-core@3.13.18': + resolution: {integrity: sha512-Mx86Hqu1k39icq2Zusq+Ey2J6dDWTjDvEv43PJtRCoEYTLyfaPnxIQ6iy7YAOK0NV/qOEmZQ/uCufrppZxTgcg==} '@tootallnate/once@2.0.0': resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} @@ -1412,12 +1542,12 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@turbo/gen@2.7.1': - resolution: {integrity: sha512-aG+9goyHq7En96pEeCx88Ougc9wesWscZxTGyWVinDazqE8qfka2+cntZKokd9TOPfhN5ImDckP8ITmoG0eGUg==} + '@turbo/gen@2.8.3': + resolution: {integrity: sha512-UQP6zMJPfnJKKFO7skLcTJWBFHG+XdMnXszliFXg/TEhd53CuVYmIXCN23n7UoMnxRBSsq0LB4sUM9JgsPewSQ==} hasBin: true - '@turbo/workspaces@2.7.1': - resolution: {integrity: sha512-cSdUacc2OWCkgbqZOkLKc2ZqbTEcP2LLoVNL/fOw2lefm1VkSL4sirdoKZNDEdn/2LqLcseyZkg0pfazBZhvBg==} + '@turbo/workspaces@2.8.3': + resolution: {integrity: sha512-p31wsDQ2DSd+TCld9xIqTG4pNA+we6/+AAZ9iCtpITRfUz3/iO8wzcz0fPfya3ostEj2B4UksLAXF570VAeO5w==} hasBin: true '@types/cacheable-request@6.0.3': @@ -1441,8 +1571,8 @@ packages: '@types/glob@7.2.0': resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} - '@types/http-cache-semantics@4.0.4': - resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} '@types/inquirer@6.5.0': resolution: {integrity: sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==} @@ -1463,11 +1593,11 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@18.19.130': - resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + '@types/node@24.10.10': + resolution: {integrity: sha512-+0/4J266CBGPUq/ELg7QUHhN25WYjE0wYTPSQJn1xeu8DOlIOPxXxrNGiLmfAWl7HMMgWFWXpt9IDjMWrF5Iow==} - '@types/node@20.19.27': - resolution: {integrity: sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==} + '@types/node@25.2.0': + resolution: {integrity: sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==} '@types/plist@3.0.5': resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} @@ -1477,8 +1607,8 @@ packages: peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.7': - resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} + '@types/react@19.2.11': + resolution: {integrity: sha512-tORuanb01iEzWvMGVGv2ZDhYZVeRMrw453DCSAIn/5yvcSVnMoUMTyf33nQJLahYEnv9xqrTNbgz4qY5EfSh0g==} '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} @@ -1495,85 +1625,85 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.50.0': - resolution: {integrity: sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==} + '@typescript-eslint/eslint-plugin@8.54.0': + resolution: {integrity: sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.50.0 + '@typescript-eslint/parser': ^8.54.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.50.0': - resolution: {integrity: sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==} + '@typescript-eslint/parser@8.54.0': + resolution: {integrity: sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.50.0': - resolution: {integrity: sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==} + '@typescript-eslint/project-service@8.54.0': + resolution: {integrity: sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.50.0': - resolution: {integrity: sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==} + '@typescript-eslint/scope-manager@8.54.0': + resolution: {integrity: sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.50.0': - resolution: {integrity: sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==} + '@typescript-eslint/tsconfig-utils@8.54.0': + resolution: {integrity: sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.50.0': - resolution: {integrity: sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==} + '@typescript-eslint/type-utils@8.54.0': + resolution: {integrity: sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.50.0': - resolution: {integrity: sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==} + '@typescript-eslint/types@8.54.0': + resolution: {integrity: sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.50.0': - resolution: {integrity: sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==} + '@typescript-eslint/typescript-estree@8.54.0': + resolution: {integrity: sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.50.0': - resolution: {integrity: sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==} + '@typescript-eslint/utils@8.54.0': + resolution: {integrity: sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.50.0': - resolution: {integrity: sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==} + '@typescript-eslint/visitor-keys@8.54.0': + resolution: {integrity: sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitejs/plugin-react-swc@4.2.2': - resolution: {integrity: sha512-x+rE6tsxq/gxrEJN3Nv3dIV60lFflPj94c90b+NNo6n1QV1QQUTLoL0MpaOVasUZ0zqVBn7ead1B5ecx1JAGfA==} + '@vitejs/plugin-react-swc@4.2.3': + resolution: {integrity: sha512-QIluDil2prhY1gdA3GGwxZzTAmLdi8cQ2CcuMW4PB/Wu4e/1pzqrwhYWVd09LInCRlDUidQjd0B70QWbjWtLxA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^4 || ^5 || ^6 || ^7 - '@vitest/coverage-v8@4.0.16': - resolution: {integrity: sha512-2rNdjEIsPRzsdu6/9Eq0AYAzYdpP6Bx9cje9tL3FE5XzXRQF1fNU9pe/1yE8fCrS0HD+fBtt6gLPh6LI57tX7A==} + '@vitest/coverage-v8@4.0.18': + resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==} peerDependencies: - '@vitest/browser': 4.0.16 - vitest: 4.0.16 + '@vitest/browser': 4.0.18 + vitest: 4.0.18 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.0.16': - resolution: {integrity: sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==} + '@vitest/expect@4.0.18': + resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} - '@vitest/mocker@4.0.16': - resolution: {integrity: sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==} + '@vitest/mocker@4.0.18': + resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -1583,25 +1713,29 @@ packages: vite: optional: true - '@vitest/pretty-format@4.0.16': - resolution: {integrity: sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==} + '@vitest/pretty-format@4.0.18': + resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} - '@vitest/runner@4.0.16': - resolution: {integrity: sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==} + '@vitest/runner@4.0.18': + resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} - '@vitest/snapshot@4.0.16': - resolution: {integrity: sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==} + '@vitest/snapshot@4.0.18': + resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} - '@vitest/spy@4.0.16': - resolution: {integrity: sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==} + '@vitest/spy@4.0.18': + resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} - '@vitest/utils@4.0.16': - resolution: {integrity: sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==} + '@vitest/utils@4.0.18': + resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} '@xmldom/xmldom@0.8.11': resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} engines: {node: '>=10.0.0'} + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1628,8 +1762,8 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} peerDependencies: ajv: ^8.0.0 peerDependenciesMeta: @@ -1674,6 +1808,9 @@ packages: app-builder-bin@4.0.0: resolution: {integrity: sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==} + app-builder-bin@5.0.0-alpha.12: + resolution: {integrity: sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==} + app-builder-lib@24.13.3: resolution: {integrity: sha512-FAzX6IBit2POXYGnTCT8YHFO/lr5AapAII6zzhQO3Rw4cEDOgK+t1xhLc5tNcKlicTHlo9zxIwnYCX9X2DLkig==} engines: {node: '>=14.0.0'} @@ -1681,6 +1818,13 @@ packages: dmg-builder: 24.13.3 electron-builder-squirrel-windows: 24.13.3 + app-builder-lib@26.7.0: + resolution: {integrity: sha512-/UgCD8VrO79Wv8aBNpjMfsS1pIUfIPURoRn0Ik6tMe5avdZF+vQgl/juJgipcMmH3YS0BD573lCdCHyoi84USg==} + engines: {node: '>=14.0.0'} + peerDependencies: + dmg-builder: 26.7.0 + electron-builder-squirrel-windows: 26.7.0 + archiver-utils@2.1.0: resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} engines: {node: '>= 6'} @@ -1753,8 +1897,8 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} - ast-v8-to-istanbul@0.3.9: - resolution: {integrity: sha512-dSC6tJeOJxbZrPzPbv5mMd6CMiQ1ugaVXXPRad2fXUSsy1kstFn9XQWemV9VW7Y7kpxgQ/4WMoZfwdH8XSU48w==} + ast-v8-to-istanbul@0.3.11: + resolution: {integrity: sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==} astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} @@ -1778,9 +1922,8 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} - atomically@1.7.0: - resolution: {integrity: sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==} - engines: {node: '>=10.12.0'} + atomically@2.1.0: + resolution: {integrity: sha512-+gDffFXRW6sl/HCwbta7zK4uNqbPjv4YJEAdz7Vu+FLQHe77eZ4bvbJGi4hE0QPeJlMYMA3piXEr1UL3dAwx7Q==} available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} @@ -1792,8 +1935,12 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - basic-ftp@5.0.5: - resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} + hasBin: true + + basic-ftp@5.1.0: + resolution: {integrity: sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==} engines: {node: '>=10.0.0'} bl@4.1.0: @@ -1819,6 +1966,11 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} @@ -1836,12 +1988,23 @@ packages: resolution: {integrity: sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==} engines: {node: '>=12.0.0'} + builder-util-runtime@9.5.1: + resolution: {integrity: sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ==} + engines: {node: '>=12.0.0'} + builder-util@24.13.1: resolution: {integrity: sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA==} + builder-util@26.4.1: + resolution: {integrity: sha512-FlgH43XZ50w3UtS1RVGDWOz8v9qMXPC7upMtKMtBEnYdt1OVoS61NYhKm/4x+cIaWqJTXua0+VVPI+fSPGXNIw==} + builtins@5.1.0: resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} + cacache@19.0.1: + resolution: {integrity: sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==} + engines: {node: ^18.17.0 || >=20.5.0} + cacheable-lookup@5.0.4: resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} engines: {node: '>=10.6.0'} @@ -1869,8 +2032,11 @@ packages: camel-case@3.0.0: resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} - chai@6.2.1: - resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} + caniuse-lite@1.0.30001768: + resolution: {integrity: sha512-qY3aDRZC5nWPgHUgIB84WL+nySuo19wk0VJpp/XI9T34lrvkyhRvNVOFJOp2kxClQhiFBu+TaUSudf6oa3vkSA==} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} chalk@2.4.2: @@ -1891,10 +2057,17 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + chromium-pickle-js@0.2.0: resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} @@ -1902,6 +2075,14 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} + engines: {node: '>=8'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -1976,9 +2157,9 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - conf@10.2.0: - resolution: {integrity: sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==} - engines: {node: '>=12'} + conf@15.1.0: + resolution: {integrity: sha512-Uy5YN9KEu0WWDaZAVJ5FAmZoaJt9rdK6kH+utItPyGsCqCgaTKkrmZx3zoE0/3q6S3bcp3Ihkk+ZqPxWxFK5og==} + engines: {node: '>=20'} config-file-ts@0.2.6: resolution: {integrity: sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w==} @@ -1986,12 +2167,15 @@ packages: constant-case@2.0.0: resolution: {integrity: sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@1.1.1: resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} - core-js-pure@3.47.0: - resolution: {integrity: sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw==} + core-js-pure@3.48.0: + resolution: {integrity: sha512-1slJgk89tWC51HQ1AEqG+s2VuwpTRr8ocu4n20QUcH1v9lAN0RXen0Q0AABa/DK1I7RrNWLucplOHMx8hfTGTw==} core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} @@ -2037,9 +2221,9 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} - debounce-fn@4.0.0: - resolution: {integrity: sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==} - engines: {node: '>=10'} + debounce-fn@6.0.0: + resolution: {integrity: sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==} + engines: {node: '>=18'} debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} @@ -2098,19 +2282,22 @@ packages: detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + diff@4.0.4: + resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} engines: {node: '>=0.3.1'} dir-compare@3.3.0: resolution: {integrity: sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==} + dir-compare@4.2.0: + resolution: {integrity: sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - dmg-builder@24.13.3: - resolution: {integrity: sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ==} + dmg-builder@26.7.0: + resolution: {integrity: sha512-uOOBA3f+kW3o4KpSoMQ6SNpdXU7WtxlJRb9vCZgOvqhTz4b3GjcoWKstdisizNZLsylhTMv8TLHFPFW0Uxsj/g==} dmg-license@1.0.11: resolution: {integrity: sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==} @@ -2125,9 +2312,13 @@ packages: dot-case@2.1.1: resolution: {integrity: sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==} - dot-prop@6.0.1: - resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} - engines: {node: '>=10'} + dot-prop@10.1.0: + resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} + engines: {node: '>=20'} + + dotenv-expand@11.0.7: + resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} + engines: {node: '>=12'} dotenv-expand@5.1.0: resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} @@ -2136,6 +2327,10 @@ packages: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dotenv@9.0.2: resolution: {integrity: sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==} engines: {node: '>=10'} @@ -2155,19 +2350,29 @@ packages: electron-builder-squirrel-windows@24.13.3: resolution: {integrity: sha512-oHkV0iogWfyK+ah9ZIvMDpei1m9ZRpdXcvde1wTpra2U8AFDNNpqJdnin5z+PM1GbQ5BoaKCWas2HSjtR0HwMg==} - electron-builder@24.13.3: - resolution: {integrity: sha512-yZSgVHft5dNVlo31qmJAe4BVKQfFdwpRw7sFp1iQglDRCDD6r22zfRJuZlhtB5gp9FHUxCMEoWGq10SkCnMAIg==} + electron-builder@26.7.0: + resolution: {integrity: sha512-LoXbCvSFxLesPneQ/fM7FB4OheIDA2tjqCdUkKlObV5ZKGhYgi5VHPHO/6UUOUodAlg7SrkPx7BZJPby+Vrtbg==} engines: {node: '>=14.0.0'} hasBin: true electron-publish@24.13.1: resolution: {integrity: sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A==} - electron-store@8.2.0: - resolution: {integrity: sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==} + electron-publish@26.6.0: + resolution: {integrity: sha512-LsyHMMqbvJ2vsOvuWJ19OezgF2ANdCiHpIucDHNiLhuI+/F3eW98ouzWSRmXXi82ZOPZXC07jnIravY4YYwCLQ==} - electron@28.3.3: - resolution: {integrity: sha512-ObKMLSPNhomtCOBAxFS8P2DW/4umkh72ouZUlUKzXGtYuPzgr1SYhskhFWgzAsPtUzhL2CzyV2sfbHcEW4CXqw==} + electron-store@11.0.2: + resolution: {integrity: sha512-4VkNRdN+BImL2KcCi41WvAYbh6zLX5AUTi4so68yPqiItjbgTjqpEnGAqasgnG+lB6GuAyUltKwVopp6Uv+gwQ==} + engines: {node: '>=20'} + + electron-to-chromium@1.5.286: + resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} + + electron-updater@6.7.3: + resolution: {integrity: sha512-EgkT8Z9noqXKbwc3u5FkJA+r48jwZ5DTUiOkJMOTEEH//n5Am6wfQGz7nvSFEA2oIAMv9jRzn5JKTyWeSKOPgg==} + + electron@40.1.0: + resolution: {integrity: sha512-2j/kvw7uF0H1PnzYBzw2k2Q6q16J8ToKrtQzZfsAoXbbMY0l5gQi2DLOauIZLzwp4O01n8Wt/74JhSRwG0yj9A==} engines: {node: '>= 12.20.55'} hasBin: true @@ -2177,17 +2382,24 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.18.4: - resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} engines: {node: '>=10.13.0'} env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} @@ -2251,8 +2463,8 @@ packages: engines: {node: '>=6.0'} hasBin: true - eslint-config-prettier@9.1.2: - resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} hasBin: true peerDependencies: eslint: '>=7.0.0' @@ -2261,16 +2473,16 @@ packages: resolution: {integrity: sha512-2tktqUAT+Q3hCAU0iSf4xAN1k9zOpjK5WO8104mB0rT/dGhOa09582HN5HlbxNbPRZ0THV7nLGvzugcNOSjzfA==} engines: {node: '>=6'} - eslint-plugin-react-hooks@5.2.0: - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} + eslint-plugin-react-hooks@7.0.1: + resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} + engines: {node: '>=18'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react-refresh@0.4.26: - resolution: {integrity: sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==} + eslint-plugin-react-refresh@0.5.0: + resolution: {integrity: sha512-ZYvmh7VfVgqR/7wR71I3Zl6hK/C5CcxdWYKZSpHawS5JCNgE4efhQWg/+/WPpgGAp9Ngp/rRZYyaIwmPQBq/lA==} peerDependencies: - eslint: '>=8.40' + eslint: '>=9' eslint-plugin-react@7.37.5: resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} @@ -2278,8 +2490,8 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-plugin-turbo@2.7.1: - resolution: {integrity: sha512-ZC7dTOdw6tGuvx1CeC1WQ0pMkgT/Jmj69QW93d63nysiLbbKRLiDKKA9s/TvwJHq8Uvbou2+hnU8if1L0jHsVQ==} + eslint-plugin-turbo@2.8.3: + resolution: {integrity: sha512-9ACQrrjzOfrbBGG1CqzyC67NtOSRcA+vyc9cjbyLyIoVtcK27czO7/WM+R5K3Opz0fb4Uezo6X+csMfL//RfJQ==} peerDependencies: eslint: '>6.6.0' turbo: '>2.0.0' @@ -2315,8 +2527,8 @@ packages: engines: {node: '>=4'} hasBin: true - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -2342,6 +2554,9 @@ packages: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -2375,8 +2590,8 @@ packages: fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} @@ -2405,10 +2620,6 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - find-up@3.0.0: - resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} - engines: {node: '>=6'} - find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -2439,6 +2650,10 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} + fs-extra@11.3.3: + resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} + engines: {node: '>=14.14'} + fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -2451,6 +2666,10 @@ packages: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2473,6 +2692,10 @@ packages: resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2530,8 +2753,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.15.0: - resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + globals@17.3.0: + resolution: {integrity: sha512-yMqGUQVVCkD4tqjOJf3TnrvaaHDMYp4VlUSObbkIiuCPe/ofdMBFIAcBbCSRFWOnos6qRiTVStDwqPLUclaxIw==} engines: {node: '>=18'} globalthis@1.0.4: @@ -2596,6 +2819,12 @@ packages: header-case@1.0.1: resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==} + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + hosted-git-info@4.1.0: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} engines: {node: '>=10'} @@ -2643,6 +2872,10 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -2683,8 +2916,8 @@ packages: resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} engines: {node: '>=8.0.0'} - inquirer@8.2.4: - resolution: {integrity: sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==} + inquirer@8.2.7: + resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} engines: {node: '>=12.0.0'} internal-slot@1.1.0: @@ -2774,10 +3007,6 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-obj@2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} - is-path-cwd@2.2.0: resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} engines: {node: '>=6'} @@ -2850,6 +3079,10 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -2858,10 +3091,6 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} - istanbul-lib-source-maps@5.0.6: - resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} - engines: {node: '>=10'} - istanbul-reports@3.2.0: resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} @@ -2882,20 +3111,21 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - js-yaml@4.1.1: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -2905,8 +3135,8 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-schema-typed@7.0.3: - resolution: {integrity: sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==} + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -3013,10 +3243,6 @@ packages: resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} engines: {node: '>= 12.0.0'} - locate-path@3.0.0: - resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} - engines: {node: '>=6'} - locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -3027,6 +3253,9 @@ packages: lodash.difference@4.5.0: resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + lodash.flatten@4.4.0: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} @@ -3034,6 +3263,10 @@ packages: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} @@ -3043,8 +3276,8 @@ packages: lodash.union@4.6.0: resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} log-symbols@3.0.0: resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==} @@ -3071,6 +3304,9 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -3079,16 +3315,16 @@ packages: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} - lucide-react@0.475.0: - resolution: {integrity: sha512-NJzvVu1HwFVeZ+Gwq2q00KygM1aBhy/ZrhY9FsAgJtpB+E4R7uxRk9M2iKvHa6/vNxZydIB59htha4c2vvwvVg==} + lucide-react@0.563.0: + resolution: {integrity: sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magicast@0.5.1: - resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} + magicast@0.5.2: + resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} @@ -3097,6 +3333,10 @@ packages: make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + make-fetch-happen@14.0.3: + resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==} + engines: {node: ^18.17.0 || >=20.5.0} + matcher@3.0.0: resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} engines: {node: '>=10'} @@ -3133,9 +3373,9 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - mimic-fn@3.1.0: - resolution: {integrity: sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==} - engines: {node: '>=8'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} @@ -3145,6 +3385,10 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} + minimatch@10.1.2: + resolution: {integrity: sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -3163,6 +3407,26 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass-collect@2.0.1: + resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass-fetch@4.0.1: + resolution: {integrity: sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==} + engines: {node: ^18.17.0 || >=20.5.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} engines: {node: '>=8'} @@ -3179,6 +3443,10 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -3202,6 +3470,10 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} @@ -3218,13 +3490,33 @@ packages: no-case@2.3.2: resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} + node-abi@4.26.0: + resolution: {integrity: sha512-8QwIZqikRvDIkXS2S93LjzhsSPJuIbfaMETWH+Bx8oOT9Sa9UsUtBFQlc3gBNd1+QINjaTloitXr1W3dQLi9Iw==} + engines: {node: '>=22.12.0'} + node-addon-api@1.7.2: resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + node-api-version@0.2.1: + resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==} + + node-gyp@11.5.0: + resolution: {integrity: sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + node-plop@0.26.3: resolution: {integrity: sha512-Cov028YhBZ5aB7MdMWJEmwyBig43aGL5WT4vdoB28Oitau1zZAcHUn8Sgfk9HM33TqhtLJ9PlM/O0Mv+QpV/4Q==} engines: {node: '>=8.9.4'} + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -3299,18 +3591,10 @@ packages: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-locate@3.0.0: - resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} - engines: {node: '>=6'} - p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -3319,9 +3603,9 @@ packages: resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} engines: {node: '>=8'} - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} pac-proxy-agent@7.2.0: resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} @@ -3347,10 +3631,6 @@ packages: path-case@2.1.1: resolution: {integrity: sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==} - path-exists@3.0.0: - resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} - engines: {node: '>=4'} - path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -3377,6 +3657,10 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pe-library@0.4.1: + resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==} + engines: {node: '>=12', npm: '>=6'} + pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} @@ -3394,10 +3678,6 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} - pkg-up@3.1.0: - resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} - engines: {node: '>=8'} - plist@3.1.0: resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} engines: {node: '>=10.4.0'} @@ -3414,9 +3694,9 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-plugin-tailwindcss@0.6.14: - resolution: {integrity: sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==} - engines: {node: '>=14.21.3'} + prettier-plugin-tailwindcss@0.7.2: + resolution: {integrity: sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA==} + engines: {node: '>=20.19'} peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' '@prettier/plugin-hermes': '*' @@ -3428,14 +3708,12 @@ packages: prettier: ^3.0 prettier-plugin-astro: '*' prettier-plugin-css-order: '*' - prettier-plugin-import-sort: '*' prettier-plugin-jsdoc: '*' prettier-plugin-marko: '*' prettier-plugin-multiline-arrays: '*' prettier-plugin-organize-attributes: '*' prettier-plugin-organize-imports: '*' prettier-plugin-sort-imports: '*' - prettier-plugin-style-order: '*' prettier-plugin-svelte: '*' peerDependenciesMeta: '@ianvs/prettier-plugin-sort-imports': @@ -3456,8 +3734,6 @@ packages: optional: true prettier-plugin-css-order: optional: true - prettier-plugin-import-sort: - optional: true prettier-plugin-jsdoc: optional: true prettier-plugin-marko: @@ -3470,16 +3746,18 @@ packages: optional: true prettier-plugin-sort-imports: optional: true - prettier-plugin-style-order: - optional: true prettier-plugin-svelte: optional: true - prettier@3.7.4: - resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} hasBin: true + proc-log@5.0.0: + resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} + engines: {node: ^18.17.0 || >=20.5.0} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -3494,6 +3772,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + proxy-agent@6.5.0: resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} engines: {node: '>= 14'} @@ -3519,10 +3800,10 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-dom@19.2.3: - resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: - react: ^19.2.3 + react: ^19.2.4 react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -3547,11 +3828,11 @@ packages: '@types/react': optional: true - react-resizable-panels@3.0.6: - resolution: {integrity: sha512-b3qKHQ3MLqOgSS+FRYKapNkJZf5EQzuf6+RLiq1/IlTHw99YrZ2NJZLk4hQIzTnnIkRg2LUqyVinu6YWWpUYew==} + react-resizable-panels@4.6.0: + resolution: {integrity: sha512-I0GUBybvHQ9xde06MH1pmhnnoZfj3lytVhA8r9Pu6r6zunoUfVRy3tU1XT9lE83yUfjlCIMaXKxPrQMmjANIkA==} peerDependencies: - react: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 react-router@7.13.0: resolution: {integrity: sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==} @@ -3573,10 +3854,14 @@ packages: '@types/react': optional: true - react@19.2.3: - resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} + read-binary-file-arch@1.0.6: + resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} + hasBin: true + read-config-file@6.3.2: resolution: {integrity: sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==} engines: {node: '>=12.0.0'} @@ -3614,6 +3899,10 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resedit@1.7.2: + resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==} + engines: {node: '>=12', npm: '>=6'} + resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -3654,8 +3943,8 @@ packages: resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} engines: {node: '>=8.0'} - rollup@4.54.0: - resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==} + rollup@4.57.1: + resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3697,8 +3986,9 @@ packages: sanitize-filename@1.6.3: resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} - sax@1.4.3: - resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + sax@1.4.4: + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + engines: {node: '>=11.0.0'} scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} @@ -3706,6 +3996,10 @@ packages: semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -3817,6 +4111,10 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + ssri@12.0.0: + resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} + engines: {node: ^18.17.0 || >=20.5.0} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -3884,6 +4182,12 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + stubborn-fs@2.0.0: + resolution: {integrity: sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==} + + stubborn-utils@1.0.2: + resolution: {integrity: sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==} + sumchecker@3.0.1: resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} engines: {node: '>= 8.0'} @@ -3903,6 +4207,10 @@ packages: swap-case@1.1.2: resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + tailwind-merge@3.4.0: resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} @@ -3922,12 +4230,22 @@ packages: engines: {node: '>=10'} deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + tar@7.5.7: + resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==} + engines: {node: '>=18'} + temp-file@3.4.0: resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tiny-async-pool@1.3.0: + resolution: {integrity: sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==} + + tiny-typed-emitter@2.1.0: + resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -3970,8 +4288,8 @@ packages: truncate-utf8-bytes@1.0.2: resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -3996,72 +4314,38 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - turbo-darwin-64@2.7.1: - resolution: {integrity: sha512-EaA7UfYujbY9/Ku0WqPpvfctxm91h9LF7zo8vjielz+omfAPB54Si+ADmUoBczBDC6RoLgbURC3GmUW2alnjJg==} - cpu: [x64] - os: [darwin] - - turbo-darwin-64@2.8.2: - resolution: {integrity: sha512-sumREbxABHxrWIwlK67sZEaDRE7+BFSU8gZj8OK+X7dLpgW1vTjsHzTECB5m2qzWlXHRdueAk8sKv7wyHqv9jw==} + turbo-darwin-64@2.8.3: + resolution: {integrity: sha512-4kXRLfcygLOeNcP6JquqRLmGB/ATjjfehiojL2dJkL7GFm3SPSXbq7oNj8UbD8XriYQ5hPaSuz59iF1ijPHkTw==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.7.1: - resolution: {integrity: sha512-/pWGSygtBugd7sKQOeMm+jKY3qN1vyB0RiHBM6bN/6qUOo2VHo8IQwBTIaSgINN4Ue6fzEU+WfePNvonSU9yXw==} + turbo-darwin-arm64@2.8.3: + resolution: {integrity: sha512-xF7uCeC0UY0Hrv/tqax0BMbFlVP1J/aRyeGQPZT4NjvIPj8gSPDgFhfkfz06DhUwDg5NgMo04uiSkAWE8WB/QQ==} cpu: [arm64] os: [darwin] - turbo-darwin-arm64@2.8.2: - resolution: {integrity: sha512-J3zoDkf+k9yozdJmdNUOc9YfIoFs01Zm+GgNyfY8pU6siMWlPlgdt+3ezbIMeOns6CAQUzUcqo9awowykAS9Vw==} - cpu: [arm64] - os: [darwin] - - turbo-linux-64@2.7.1: - resolution: {integrity: sha512-Y5H11mdhASw/dJuRFyGtTCDFX5/MPT73EKsVEiHbw5MkFc77lx3nMc5L/Q7bKEhef/vYJAsAb61QuHsB6qdP8Q==} - cpu: [x64] - os: [linux] - - turbo-linux-64@2.8.2: - resolution: {integrity: sha512-iVYUM+tyNAPd34HhMSjYWi7OSXnxnDhPjFKVvzSb7cZmQS6GlDSr7MALc5Wt/zn6/7jm1FuS7c5Wffg9WD2e1Q==} + turbo-linux-64@2.8.3: + resolution: {integrity: sha512-vxMDXwaOjweW/4etY7BxrXCSkvtwh0PbwVafyfT1Ww659SedUxd5rM3V2ZCmbwG8NiCfY7d6VtxyHx3Wh1GoZA==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.7.1: - resolution: {integrity: sha512-L/r77jD7cqIEXoyu2LGBUrTY5GJSi/XcGLsQ2nZ/fefk6x3MpljTvwsXUVG1BUkiBPc4zaKRj6yGyWMo5MbLxQ==} - cpu: [arm64] - os: [linux] - - turbo-linux-arm64@2.8.2: - resolution: {integrity: sha512-v7FJAHUhY2nSEE87mr5ZBO51GmsFKp0EmK2P6rO+vGimCPmnGlLNj1at/eVcnp/cHRDnJj8J+b3QHWdUzTPTkg==} + turbo-linux-arm64@2.8.3: + resolution: {integrity: sha512-mQX7uYBZFkuPLLlKaNe9IjR1JIef4YvY8f21xFocvttXvdPebnq3PK1Zjzl9A1zun2BEuWNUwQIL8lgvN9Pm3Q==} cpu: [arm64] os: [linux] - turbo-windows-64@2.7.1: - resolution: {integrity: sha512-rkeuviXZ/1F7lCare7TNKvYtT/SH9dZR55FAMrxrFRh88b+ZKwlXEBfq5/1OctEzRUo/VLIm+s5LJMOEy+QshA==} - cpu: [x64] - os: [win32] - - turbo-windows-64@2.8.2: - resolution: {integrity: sha512-d1X+U5JLhyAse0VXM0rpmu6iLbBTAvjwc7MX0PBkEaTz2aZQqOHBpQkkrxia7bZzRNbfXHbGSqY/vbE3GSFWzw==} + turbo-windows-64@2.8.3: + resolution: {integrity: sha512-YLGEfppGxZj3VWcNOVa08h6ISsVKiG85aCAWosOKNUjb6yErWEuydv6/qImRJUI+tDLvDvW7BxopAkujRnWCrw==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.7.1: - resolution: {integrity: sha512-1rZk9htm3+iP/rWCf/h4/DFQey9sMs2TJPC4T5QQfwqAdMWsphgrxBuFqHdxczlbBCgbWNhVw0CH2bTxe1/GFg==} + turbo-windows-arm64@2.8.3: + resolution: {integrity: sha512-afTUGKBRmOJU1smQSBnFGcbq0iabAPwh1uXu2BVk7BREg30/1gMnJh9DFEQTah+UD3n3ru8V55J83RQNFfqoyw==} cpu: [arm64] os: [win32] - turbo-windows-arm64@2.8.2: - resolution: {integrity: sha512-fMln07/l/5kscs79V0kTwdf17gkZW+E2iyqnzz691gLM7Jf6la0afd3IMsNtLzUh+dxKIFCswNiFVmHe8g+2jA==} - cpu: [arm64] - os: [win32] - - turbo@2.7.1: - resolution: {integrity: sha512-zAj9jGc7VDvuAo/5Jbos4QTtWz9uUpkMhMKGyTjDJkx//hdL2bM31qQoJSAbU+7JyK5vb0LPzpwf6DUt3zayqg==} - hasBin: true - - turbo@2.8.2: - resolution: {integrity: sha512-biW/S5hENCcJ5vxxJszCozEKcXtwGK29vxXzNbdfY/0q7QpYTCoyKdj0e8k/ADA6qkqaKDJwgrrHbC8Vy6wszg==} + turbo@2.8.3: + resolution: {integrity: sha512-8Osxz5Tu/Dw2kb31EAY+nhq/YZ3wzmQSmYa1nIArqxgCAldxv9TPlrAiaBUDVnKA4aiPn0OFBD1ACcpc5VFOAQ==} hasBin: true tw-animate-css@1.4.0: @@ -4079,9 +4363,9 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} + type-fest@5.4.3: + resolution: {integrity: sha512-AXSAQJu79WGc79/3e9/CR77I/KQgeY1AhNvcShIH4PTcGYyC4xv6H4R4AUOwkPS5799KlVDAu8zExeCrkGquiA==} + engines: {node: '>=20'} typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} @@ -4099,18 +4383,13 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.50.0: - resolution: {integrity: sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==} + typescript-eslint@8.54.0: + resolution: {integrity: sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - typescript@5.7.3: - resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -4121,15 +4400,24 @@ packages: engines: {node: '>=0.8.0'} hasBin: true + uint8array-extras@1.5.0: + resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} + engines: {node: '>=18'} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + unique-filename@4.0.0: + resolution: {integrity: sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==} + engines: {node: ^18.17.0 || >=20.5.0} + + unique-slug@5.0.0: + resolution: {integrity: sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==} + engines: {node: ^18.17.0 || >=20.5.0} universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} @@ -4139,6 +4427,12 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + update-check@1.5.4: resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==} @@ -4196,8 +4490,8 @@ packages: resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==} engines: {node: '>=0.6.0'} - vite@7.3.0: - resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==} + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -4236,18 +4530,18 @@ packages: yaml: optional: true - vitest@4.0.16: - resolution: {integrity: sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==} + vitest@4.0.18: + resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.16 - '@vitest/browser-preview': 4.0.16 - '@vitest/browser-webdriverio': 4.0.16 - '@vitest/ui': 4.0.16 + '@vitest/browser-playwright': 4.0.18 + '@vitest/browser-preview': 4.0.18 + '@vitest/browser-webdriverio': 4.0.18 + '@vitest/ui': 4.0.18 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -4273,6 +4567,9 @@ packages: wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + when-exit@2.1.5: + resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==} + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -4285,8 +4582,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} which@2.0.2: @@ -4294,6 +4591,11 @@ packages: engines: {node: '>= 8'} hasBin: true + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} @@ -4306,6 +4608,10 @@ packages: wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -4325,9 +4631,16 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -4351,8 +4664,14 @@ packages: resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} engines: {node: '>= 10'} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} zustand@5.0.11: resolution: {integrity: sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==} @@ -4378,57 +4697,144 @@ snapshots: '@alloc/quick-lru@5.2.0': {} - '@babel/helper-string-parser@7.27.1': {} + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 - '@babel/helper-validator-identifier@7.28.5': {} + '@babel/compat-data@7.29.0': {} - '@babel/parser@7.28.5': + '@babel/core@7.29.0': dependencies: - '@babel/types': 7.28.5 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color - '@babel/runtime-corejs3@7.28.4': + '@babel/generator@7.29.1': dependencies: - core-js-pure: 3.47.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 - '@babel/types@7.28.5': + '@babel/helper-compilation-targets@7.28.6': dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 - '@bcoe/v8-coverage@1.0.2': {} + '@babel/helper-globals@7.28.0': {} - '@cspotcode/source-map-support@0.8.1': + '@babel/helper-module-imports@7.28.6': dependencies: - '@jridgewell/trace-mapping': 0.3.9 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color - '@develar/schema-utils@2.6.5': + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': dependencies: - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color - '@dnd-kit/accessibility@3.1.1(react@19.2.3)': + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.0': + dependencies: + '@babel/types': 7.29.0 + + '@babel/runtime-corejs3@7.29.0': + dependencies: + core-js-pure: 3.48.0 + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@bcoe/v8-coverage@1.0.2': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@develar/schema-utils@2.6.5': + dependencies: + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + + '@dnd-kit/accessibility@3.1.1(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 tslib: 2.8.1 - '@dnd-kit/core@6.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@dnd-kit/accessibility': 3.1.1(react@19.2.3) - '@dnd-kit/utilities': 3.2.2(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@dnd-kit/accessibility': 3.1.1(react@19.2.4) + '@dnd-kit/utilities': 3.2.2(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 - '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)': + '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)': dependencies: - '@dnd-kit/core': 6.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@dnd-kit/utilities': 3.2.2(react@19.2.3) - react: 19.2.3 + '@dnd-kit/core': 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@dnd-kit/utilities': 3.2.2(react@19.2.4) + react: 19.2.4 tslib: 2.8.1 - '@dnd-kit/utilities@3.2.2(react@19.2.3)': + '@dnd-kit/utilities@3.2.2(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 tslib: 2.8.1 '@electron/asar@3.4.1': @@ -4437,6 +4843,12 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 + '@electron/fuses@1.8.0': + dependencies: + chalk: 4.1.2 + fs-extra: 9.1.0 + minimist: 1.2.8 + '@electron/get@2.0.3': dependencies: debug: 4.4.3 @@ -4451,6 +4863,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@electron/get@3.1.0': + dependencies: + debug: 4.4.3 + env-paths: 2.2.1 + fs-extra: 8.1.0 + got: 11.8.6 + progress: 2.0.3 + semver: 6.3.1 + sumchecker: 3.0.1 + optionalDependencies: + global-agent: 3.0.0 + transitivePeerDependencies: + - supports-color + '@electron/notarize@2.2.1': dependencies: debug: 4.4.3 @@ -4459,6 +4885,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@electron/notarize@2.5.0': + dependencies: + debug: 4.4.3 + fs-extra: 9.1.0 + promise-retry: 2.0.1 + transitivePeerDependencies: + - supports-color + '@electron/osx-sign@1.0.5': dependencies: compare-version: 0.1.2 @@ -4470,6 +4904,35 @@ snapshots: transitivePeerDependencies: - supports-color + '@electron/osx-sign@1.3.3': + dependencies: + compare-version: 0.1.2 + debug: 4.4.3 + fs-extra: 10.1.0 + isbinaryfile: 4.0.10 + minimist: 1.2.8 + plist: 3.1.0 + transitivePeerDependencies: + - supports-color + + '@electron/rebuild@4.0.3': + dependencies: + '@malept/cross-spawn-promise': 2.0.0 + debug: 4.4.3 + detect-libc: 2.1.2 + got: 11.8.6 + graceful-fs: 4.2.11 + node-abi: 4.26.0 + node-api-version: 0.2.1 + node-gyp: 11.5.0 + ora: 5.4.1 + read-binary-file-arch: 1.0.6 + semver: 7.7.3 + tar: 7.5.7 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + '@electron/universal@1.5.1': dependencies: '@electron/asar': 3.4.1 @@ -4482,6 +4945,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@electron/universal@2.0.3': + dependencies: + '@electron/asar': 3.4.1 + '@malept/cross-spawn-promise': 2.0.0 + debug: 4.4.3 + dir-compare: 4.2.0 + fs-extra: 11.3.3 + minimatch: 9.0.5 + plist: 3.1.0 + transitivePeerDependencies: + - supports-color + '@esbuild/aix-ppc64@0.27.2': optional: true @@ -4560,7 +5035,7 @@ snapshots: '@esbuild/win32-x64@0.27.2': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))': dependencies: eslint: 9.39.2(jiti@2.6.1) eslint-visitor-keys: 3.4.3 @@ -4606,20 +5081,20 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 - '@floating-ui/core@1.7.3': + '@floating-ui/core@1.7.4': dependencies: '@floating-ui/utils': 0.2.10 - '@floating-ui/dom@1.7.4': + '@floating-ui/dom@1.7.5': dependencies: - '@floating-ui/core': 1.7.3 + '@floating-ui/core': 1.7.4 '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@floating-ui/react-dom@2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@floating-ui/dom': 1.7.4 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@floating-ui/dom': 1.7.5 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) '@floating-ui/utils@0.2.10': {} @@ -4636,6 +5111,19 @@ snapshots: '@iarna/toml@2.2.5': {} + '@inquirer/external-editor@1.0.3(@types/node@25.2.0)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 25.2.0 + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.1': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -4645,6 +5133,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -4673,11 +5165,15 @@ snapshots: dependencies: cross-spawn: 7.0.6 + '@malept/cross-spawn-promise@2.0.0': + dependencies: + cross-spawn: 7.0.6 + '@malept/flatpak-bundler@0.4.0': dependencies: debug: 4.4.3 fs-extra: 9.1.0 - lodash: 4.17.21 + lodash: 4.17.23 tmp-promise: 3.0.3 transitivePeerDependencies: - supports-color @@ -4692,7 +5188,21 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 + fastq: 1.20.1 + + '@npmcli/agent@3.0.0': + dependencies: + agent-base: 7.1.4 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 10.4.3 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + '@npmcli/fs@4.0.0': + dependencies: + semver: 7.7.3 '@pkgjs/parseargs@0.11.0': optional: true @@ -4701,552 +5211,561 @@ snapshots: '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.11)(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-context@1.1.2(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-context@1.1.2(@types/react@19.2.11)(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.4) aria-hidden: 1.2.6 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.11)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-direction@1.1.1(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-direction@1.1.1(@types/react@19.2.11)(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.11)(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-id@1.1.1(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-id@1.1.1(@types/react@19.2.11)(react@19.2.4)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.4) aria-hidden: 1.2.6 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.11)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.4) aria-hidden: 1.2.6 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.11)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) - - '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@floating-ui/react-dom': 2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.11)(react@19.2.4) '@radix-ui/rect': 1.1.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-slot': 1.2.4(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) aria-hidden: 1.2.6 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.11)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-slot@1.2.3(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-slot@1.2.3(@types/react@19.2.11)(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-slot@1.2.4(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-slot@1.2.4(@types/react@19.2.11)(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.11)(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.11)(react@19.2.4)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.7)(react@19.2.3) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.11)(react@19.2.4)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.11)(react@19.2.4)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.11)(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.11)(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.11)(react@19.2.4)': dependencies: '@radix-ui/rect': 1.1.1 - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-use-size@1.1.1(@types/react@19.2.7)(react@19.2.3)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.11)(react@19.2.4)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) - react: 19.2.3 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 - '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/react': 19.2.11 + '@types/react-dom': 19.2.3(@types/react@19.2.11) '@radix-ui/rect@1.1.1': {} - '@rolldown/pluginutils@1.0.0-beta.47': {} + '@rolldown/pluginutils@1.0.0-rc.2': {} + + '@rollup/rollup-android-arm-eabi@4.57.1': + optional: true + + '@rollup/rollup-android-arm64@4.57.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.57.1': + optional: true - '@rollup/rollup-android-arm-eabi@4.54.0': + '@rollup/rollup-darwin-x64@4.57.1': optional: true - '@rollup/rollup-android-arm64@4.54.0': + '@rollup/rollup-freebsd-arm64@4.57.1': optional: true - '@rollup/rollup-darwin-arm64@4.54.0': + '@rollup/rollup-freebsd-x64@4.57.1': optional: true - '@rollup/rollup-darwin-x64@4.54.0': + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': optional: true - '@rollup/rollup-freebsd-arm64@4.54.0': + '@rollup/rollup-linux-arm-musleabihf@4.57.1': optional: true - '@rollup/rollup-freebsd-x64@4.54.0': + '@rollup/rollup-linux-arm64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.54.0': + '@rollup/rollup-linux-arm64-musl@4.57.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.54.0': + '@rollup/rollup-linux-loong64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.54.0': + '@rollup/rollup-linux-loong64-musl@4.57.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.54.0': + '@rollup/rollup-linux-ppc64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-loong64-gnu@4.54.0': + '@rollup/rollup-linux-ppc64-musl@4.57.1': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.54.0': + '@rollup/rollup-linux-riscv64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.54.0': + '@rollup/rollup-linux-riscv64-musl@4.57.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.54.0': + '@rollup/rollup-linux-s390x-gnu@4.57.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.54.0': + '@rollup/rollup-linux-x64-gnu@4.57.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.54.0': + '@rollup/rollup-linux-x64-musl@4.57.1': optional: true - '@rollup/rollup-linux-x64-musl@4.54.0': + '@rollup/rollup-openbsd-x64@4.57.1': optional: true - '@rollup/rollup-openharmony-arm64@4.54.0': + '@rollup/rollup-openharmony-arm64@4.57.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.54.0': + '@rollup/rollup-win32-arm64-msvc@4.57.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.54.0': + '@rollup/rollup-win32-ia32-msvc@4.57.1': optional: true - '@rollup/rollup-win32-x64-gnu@4.54.0': + '@rollup/rollup-win32-x64-gnu@4.57.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.54.0': + '@rollup/rollup-win32-x64-msvc@4.57.1': optional: true '@sindresorhus/is@4.6.0': {} '@standard-schema/spec@1.1.0': {} - '@swc/core-darwin-arm64@1.15.7': + '@swc/core-darwin-arm64@1.15.11': optional: true - '@swc/core-darwin-x64@1.15.7': + '@swc/core-darwin-x64@1.15.11': optional: true - '@swc/core-linux-arm-gnueabihf@1.15.7': + '@swc/core-linux-arm-gnueabihf@1.15.11': optional: true - '@swc/core-linux-arm64-gnu@1.15.7': + '@swc/core-linux-arm64-gnu@1.15.11': optional: true - '@swc/core-linux-arm64-musl@1.15.7': + '@swc/core-linux-arm64-musl@1.15.11': optional: true - '@swc/core-linux-x64-gnu@1.15.7': + '@swc/core-linux-x64-gnu@1.15.11': optional: true - '@swc/core-linux-x64-musl@1.15.7': + '@swc/core-linux-x64-musl@1.15.11': optional: true - '@swc/core-win32-arm64-msvc@1.15.7': + '@swc/core-win32-arm64-msvc@1.15.11': optional: true - '@swc/core-win32-ia32-msvc@1.15.7': + '@swc/core-win32-ia32-msvc@1.15.11': optional: true - '@swc/core-win32-x64-msvc@1.15.7': + '@swc/core-win32-x64-msvc@1.15.11': optional: true - '@swc/core@1.15.7': + '@swc/core@1.15.11': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.25 optionalDependencies: - '@swc/core-darwin-arm64': 1.15.7 - '@swc/core-darwin-x64': 1.15.7 - '@swc/core-linux-arm-gnueabihf': 1.15.7 - '@swc/core-linux-arm64-gnu': 1.15.7 - '@swc/core-linux-arm64-musl': 1.15.7 - '@swc/core-linux-x64-gnu': 1.15.7 - '@swc/core-linux-x64-musl': 1.15.7 - '@swc/core-win32-arm64-msvc': 1.15.7 - '@swc/core-win32-ia32-msvc': 1.15.7 - '@swc/core-win32-x64-msvc': 1.15.7 + '@swc/core-darwin-arm64': 1.15.11 + '@swc/core-darwin-x64': 1.15.11 + '@swc/core-linux-arm-gnueabihf': 1.15.11 + '@swc/core-linux-arm64-gnu': 1.15.11 + '@swc/core-linux-arm64-musl': 1.15.11 + '@swc/core-linux-x64-gnu': 1.15.11 + '@swc/core-linux-x64-musl': 1.15.11 + '@swc/core-win32-arm64-msvc': 1.15.11 + '@swc/core-win32-ia32-msvc': 1.15.11 + '@swc/core-win32-x64-msvc': 1.15.11 '@swc/counter@0.1.3': {} @@ -5261,7 +5780,7 @@ snapshots: '@tailwindcss/node@4.1.18': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.19.0 jiti: 2.6.1 lightningcss: 1.30.2 magic-string: 0.30.21 @@ -5327,20 +5846,20 @@ snapshots: postcss: 8.5.6 tailwindcss: 4.1.18 - '@tailwindcss/vite@4.1.18(vite@7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2))': + '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@tailwindcss/node': 4.1.18 '@tailwindcss/oxide': 4.1.18 tailwindcss: 4.1.18 - vite: 7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2) - '@tanstack/react-virtual@3.13.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@tanstack/react-virtual@3.13.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@tanstack/virtual-core': 3.13.14 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@tanstack/virtual-core': 3.13.18 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@tanstack/virtual-core@3.13.14': {} + '@tanstack/virtual-core@3.13.18': {} '@tootallnate/once@2.0.0': {} @@ -5354,17 +5873,17 @@ snapshots: '@tsconfig/node16@1.0.4': {} - '@turbo/gen@2.7.1(@swc/core@1.15.7)(@types/node@20.19.27)(typescript@5.9.3)': + '@turbo/gen@2.8.3(@swc/core@1.15.11)(@types/node@25.2.0)(typescript@5.9.3)': dependencies: - '@turbo/workspaces': 2.7.1 + '@turbo/workspaces': 2.8.3(@types/node@25.2.0) commander: 10.0.0 fs-extra: 10.1.0 - inquirer: 8.2.4 + inquirer: 8.2.7(@types/node@25.2.0) minimatch: 9.0.0 node-plop: 0.26.3 picocolors: 1.0.1 proxy-agent: 6.5.0 - ts-node: 10.9.2(@swc/core@1.15.7)(@types/node@20.19.27)(typescript@5.9.3) + ts-node: 10.9.2(@swc/core@1.15.11)(@types/node@25.2.0)(typescript@5.9.3) update-check: 1.5.4 validate-npm-package-name: 5.0.0 transitivePeerDependencies: @@ -5374,25 +5893,27 @@ snapshots: - supports-color - typescript - '@turbo/workspaces@2.7.1': + '@turbo/workspaces@2.8.3(@types/node@25.2.0)': dependencies: commander: 10.0.0 execa: 5.1.1 fast-glob: 3.2.12 fs-extra: 10.1.0 gradient-string: 2.0.1 - inquirer: 8.2.4 - js-yaml: 4.1.0 + inquirer: 8.2.7(@types/node@25.2.0) + js-yaml: 4.1.1 ora: 4.1.1 picocolors: 1.0.1 semver: 7.6.2 update-check: 1.5.4 + transitivePeerDependencies: + - '@types/node' '@types/cacheable-request@6.0.3': dependencies: - '@types/http-cache-semantics': 4.0.4 + '@types/http-cache-semantics': 4.2.0 '@types/keyv': 3.1.4 - '@types/node': 20.19.27 + '@types/node': 24.10.10 '@types/responselike': 1.0.3 '@types/chai@5.2.3': @@ -5410,14 +5931,14 @@ snapshots: '@types/fs-extra@9.0.13': dependencies: - '@types/node': 20.19.27 + '@types/node': 25.2.0 '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 20.19.27 + '@types/node': 25.2.0 - '@types/http-cache-semantics@4.0.4': {} + '@types/http-cache-semantics@4.2.0': {} '@types/inquirer@6.5.0': dependencies: @@ -5428,7 +5949,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 20.19.27 + '@types/node': 24.10.10 '@types/lodash@4.17.23': {} @@ -5438,35 +5959,35 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@18.19.130': + '@types/node@24.10.10': dependencies: - undici-types: 5.26.5 + undici-types: 7.16.0 - '@types/node@20.19.27': + '@types/node@25.2.0': dependencies: - undici-types: 6.21.0 + undici-types: 7.16.0 '@types/plist@3.0.5': dependencies: - '@types/node': 20.19.27 + '@types/node': 25.2.0 xmlbuilder: 15.1.1 optional: true - '@types/react-dom@19.2.3(@types/react@19.2.7)': + '@types/react-dom@19.2.3(@types/react@19.2.11)': dependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - '@types/react@19.2.7': + '@types/react@19.2.11': dependencies: csstype: 3.2.3 '@types/responselike@1.0.3': dependencies: - '@types/node': 20.19.27 + '@types/node': 24.10.10 '@types/through@0.0.33': dependencies: - '@types/node': 20.19.27 + '@types/node': 25.2.0 '@types/tinycolor2@1.4.6': {} @@ -5475,166 +5996,165 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 20.19.27 + '@types/node': 24.10.10 optional: true - '@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.50.0 - '@typescript-eslint/type-utils': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.0 + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 eslint: 9.39.2(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.50.0 - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.0 + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.50.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.54.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) - '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.50.0': + '@typescript-eslint/scope-manager@8.54.0': dependencies: - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/visitor-keys': 8.50.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 - '@typescript-eslint/tsconfig-utils@8.50.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.54.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.50.0': {} + '@typescript-eslint/types@8.54.0': {} - '@typescript-eslint/typescript-estree@8.50.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.54.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.50.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/visitor-keys': 8.50.0 + '@typescript-eslint/project-service': 8.54.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 minimatch: 9.0.5 semver: 7.7.3 tinyglobby: 0.2.15 - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.50.0 - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.50.0': + '@typescript-eslint/visitor-keys@8.54.0': dependencies: - '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/types': 8.54.0 eslint-visitor-keys: 4.2.1 - '@vitejs/plugin-react-swc@4.2.2(vite@7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2))': + '@vitejs/plugin-react-swc@4.2.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: - '@rolldown/pluginutils': 1.0.0-beta.47 - '@swc/core': 1.15.7 - vite: 7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2) + '@rolldown/pluginutils': 1.0.0-rc.2 + '@swc/core': 1.15.11 + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - '@swc/helpers' - '@vitest/coverage-v8@4.0.16(vitest@4.0.16(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2))': + '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.16 - ast-v8-to-istanbul: 0.3.9 + '@vitest/utils': 4.0.18 + ast-v8-to-istanbul: 0.3.11 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.2.0 - magicast: 0.5.1 + magicast: 0.5.2 obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.16(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2) - transitivePeerDependencies: - - supports-color + vitest: 4.0.18(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2) - '@vitest/expect@4.0.16': + '@vitest/expect@4.0.18': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.0.16 - '@vitest/utils': 4.0.16 - chai: 6.2.1 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.16(vite@7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2))': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: - '@vitest/spy': 4.0.16 + '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2) - '@vitest/pretty-format@4.0.16': + '@vitest/pretty-format@4.0.18': dependencies: tinyrainbow: 3.0.3 - '@vitest/runner@4.0.16': + '@vitest/runner@4.0.18': dependencies: - '@vitest/utils': 4.0.16 + '@vitest/utils': 4.0.18 pathe: 2.0.3 - '@vitest/snapshot@4.0.16': + '@vitest/snapshot@4.0.18': dependencies: - '@vitest/pretty-format': 4.0.16 + '@vitest/pretty-format': 4.0.18 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.0.16': {} + '@vitest/spy@4.0.18': {} - '@vitest/utils@4.0.16': + '@vitest/utils@4.0.18': dependencies: - '@vitest/pretty-format': 4.0.16 + '@vitest/pretty-format': 4.0.18 tinyrainbow: 3.0.3 '@xmldom/xmldom@0.8.11': {} + abbrev@3.0.1: {} + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -5658,7 +6178,7 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ajv-formats@2.1.1(ajv@8.17.1): + ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -5700,7 +6220,9 @@ snapshots: app-builder-bin@4.0.0: {} - app-builder-lib@24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3): + app-builder-bin@5.0.0-alpha.12: {} + + app-builder-lib@24.13.3(dmg-builder@26.7.0)(electron-builder-squirrel-windows@24.13.3): dependencies: '@develar/schema-utils': 2.6.5 '@electron/notarize': 2.2.1 @@ -5714,9 +6236,9 @@ snapshots: builder-util-runtime: 9.2.4 chromium-pickle-js: 0.2.0 debug: 4.4.3 - dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3) + dmg-builder: 26.7.0(electron-builder-squirrel-windows@24.13.3) ejs: 3.1.10 - electron-builder-squirrel-windows: 24.13.3(dmg-builder@24.13.3) + electron-builder-squirrel-windows: 24.13.3(dmg-builder@26.7.0) electron-publish: 24.13.1 form-data: 4.0.5 fs-extra: 10.1.0 @@ -5734,6 +6256,49 @@ snapshots: transitivePeerDependencies: - supports-color + app-builder-lib@26.7.0(dmg-builder@26.7.0)(electron-builder-squirrel-windows@24.13.3): + dependencies: + '@develar/schema-utils': 2.6.5 + '@electron/asar': 3.4.1 + '@electron/fuses': 1.8.0 + '@electron/get': 3.1.0 + '@electron/notarize': 2.5.0 + '@electron/osx-sign': 1.3.3 + '@electron/rebuild': 4.0.3 + '@electron/universal': 2.0.3 + '@malept/flatpak-bundler': 0.4.0 + '@types/fs-extra': 9.0.13 + async-exit-hook: 2.0.1 + builder-util: 26.4.1 + builder-util-runtime: 9.5.1 + chromium-pickle-js: 0.2.0 + ci-info: 4.3.1 + debug: 4.4.3 + dmg-builder: 26.7.0(electron-builder-squirrel-windows@24.13.3) + dotenv: 16.6.1 + dotenv-expand: 11.0.7 + ejs: 3.1.10 + electron-builder-squirrel-windows: 24.13.3(dmg-builder@26.7.0) + electron-publish: 26.6.0 + fs-extra: 10.1.0 + hosted-git-info: 4.1.0 + isbinaryfile: 5.0.7 + jiti: 2.6.1 + js-yaml: 4.1.1 + json5: 2.2.3 + lazy-val: 1.0.5 + minimatch: 10.1.2 + plist: 3.1.0 + proper-lockfile: 4.1.2 + resedit: 1.7.2 + semver: 7.7.3 + tar: 7.5.7 + temp-file: 3.4.0 + tiny-async-pool: 1.3.0 + which: 5.0.0 + transitivePeerDependencies: + - supports-color + archiver-utils@2.1.0: dependencies: glob: 7.2.3 @@ -5855,11 +6420,11 @@ snapshots: dependencies: tslib: 2.8.1 - ast-v8-to-istanbul@0.3.9: + ast-v8-to-istanbul@0.3.11: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 - js-tokens: 9.0.1 + js-tokens: 10.0.0 astral-regex@2.0.0: optional: true @@ -5874,7 +6439,10 @@ snapshots: at-least-node@1.0.0: {} - atomically@1.7.0: {} + atomically@2.1.0: + dependencies: + stubborn-fs: 2.0.0 + when-exit: 2.1.5 available-typed-arrays@1.0.7: dependencies: @@ -5884,7 +6452,9 @@ snapshots: base64-js@1.5.1: {} - basic-ftp@5.0.5: {} + baseline-browser-mapping@2.9.19: {} + + basic-ftp@5.1.0: {} bl@4.1.0: dependencies: @@ -5914,6 +6484,14 @@ snapshots: dependencies: fill-range: 7.1.1 + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001768 + electron-to-chromium: 1.5.286 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + buffer-crc32@0.2.13: {} buffer-equal@1.0.1: {} @@ -5928,7 +6506,14 @@ snapshots: builder-util-runtime@9.2.4: dependencies: debug: 4.4.3 - sax: 1.4.3 + sax: 1.4.4 + transitivePeerDependencies: + - supports-color + + builder-util-runtime@9.5.1: + dependencies: + debug: 4.4.3 + sax: 1.4.4 transitivePeerDependencies: - supports-color @@ -5953,10 +6538,46 @@ snapshots: transitivePeerDependencies: - supports-color + builder-util@26.4.1: + dependencies: + 7zip-bin: 5.2.0 + '@types/debug': 4.1.12 + app-builder-bin: 5.0.0-alpha.12 + builder-util-runtime: 9.5.1 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + fs-extra: 10.1.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + js-yaml: 4.1.1 + sanitize-filename: 1.6.3 + source-map-support: 0.5.21 + stat-mode: 1.0.0 + temp-file: 3.4.0 + tiny-async-pool: 1.3.0 + transitivePeerDependencies: + - supports-color + builtins@5.1.0: dependencies: semver: 7.7.3 + cacache@19.0.1: + dependencies: + '@npmcli/fs': 4.0.0 + fs-minipass: 3.0.3 + glob: 10.5.0 + lru-cache: 10.4.3 + minipass: 7.1.2 + minipass-collect: 2.0.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 7.0.4 + ssri: 12.0.0 + tar: 7.5.7 + unique-filename: 4.0.0 + cacheable-lookup@5.0.4: {} cacheable-request@7.0.4: @@ -5993,7 +6614,9 @@ snapshots: no-case: 2.3.2 upper-case: 1.1.3 - chai@6.2.1: {} + caniuse-lite@1.0.30001768: {} + + chai@6.2.2: {} chalk@2.4.2: dependencies: @@ -6034,12 +6657,20 @@ snapshots: chardet@0.7.0: {} + chardet@2.1.1: {} + chownr@2.0.0: {} + chownr@3.0.0: {} + chromium-pickle-js@0.2.0: {} ci-info@3.9.0: {} + ci-info@4.3.1: {} + + ci-info@4.4.0: {} + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -6105,18 +6736,17 @@ snapshots: concat-map@0.0.1: {} - conf@10.2.0: + conf@15.1.0: dependencies: ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - atomically: 1.7.0 - debounce-fn: 4.0.0 - dot-prop: 6.0.1 - env-paths: 2.2.1 - json-schema-typed: 7.0.3 - onetime: 5.1.2 - pkg-up: 3.1.0 + ajv-formats: 3.0.1(ajv@8.17.1) + atomically: 2.1.0 + debounce-fn: 6.0.0 + dot-prop: 10.1.0 + env-paths: 3.0.0 + json-schema-typed: 8.0.2 semver: 7.7.3 + uint8array-extras: 1.5.0 config-file-ts@0.2.6: dependencies: @@ -6128,9 +6758,11 @@ snapshots: snake-case: 2.1.0 upper-case: 1.1.3 + convert-source-map@2.0.0: {} + cookie@1.1.1: {} - core-js-pure@3.47.0: {} + core-js-pure@3.48.0: {} core-util-is@1.0.2: optional: true @@ -6179,9 +6811,9 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - debounce-fn@4.0.0: + debounce-fn@6.0.0: dependencies: - mimic-fn: 3.1.0 + mimic-function: 5.0.1 debug@4.4.3: dependencies: @@ -6239,22 +6871,26 @@ snapshots: detect-node@2.1.0: optional: true - diff@4.0.2: {} + diff@4.0.4: {} dir-compare@3.3.0: dependencies: buffer-equal: 1.0.1 minimatch: 3.1.2 + dir-compare@4.2.0: + dependencies: + minimatch: 3.1.2 + p-limit: 3.1.0 + dir-glob@3.0.1: dependencies: path-type: 4.0.0 - dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3): + dmg-builder@26.7.0(electron-builder-squirrel-windows@24.13.3): dependencies: - app-builder-lib: 24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3) - builder-util: 24.13.1 - builder-util-runtime: 9.2.4 + app-builder-lib: 26.7.0(dmg-builder@26.7.0)(electron-builder-squirrel-windows@24.13.3) + builder-util: 26.4.1 fs-extra: 10.1.0 iconv-lite: 0.6.3 js-yaml: 4.1.1 @@ -6284,14 +6920,20 @@ snapshots: dependencies: no-case: 2.3.2 - dot-prop@6.0.1: + dot-prop@10.1.0: + dependencies: + type-fest: 5.4.3 + + dotenv-expand@11.0.7: dependencies: - is-obj: 2.0.0 + dotenv: 16.6.1 dotenv-expand@5.1.0: {} dotenv@16.0.3: {} + dotenv@16.6.1: {} + dotenv@9.0.2: {} dunder-proto@1.0.1: @@ -6306,9 +6948,9 @@ snapshots: dependencies: jake: 10.9.4 - electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3): + electron-builder-squirrel-windows@24.13.3(dmg-builder@26.7.0): dependencies: - app-builder-lib: 24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3) + app-builder-lib: 24.13.3(dmg-builder@26.7.0)(electron-builder-squirrel-windows@24.13.3) archiver: 5.3.2 builder-util: 24.13.1 fs-extra: 10.1.0 @@ -6316,17 +6958,16 @@ snapshots: - dmg-builder - supports-color - electron-builder@24.13.3(electron-builder-squirrel-windows@24.13.3): + electron-builder@26.7.0(electron-builder-squirrel-windows@24.13.3): dependencies: - app-builder-lib: 24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3) - builder-util: 24.13.1 - builder-util-runtime: 9.2.4 + app-builder-lib: 26.7.0(dmg-builder@26.7.0)(electron-builder-squirrel-windows@24.13.3) + builder-util: 26.4.1 + builder-util-runtime: 9.5.1 chalk: 4.1.2 - dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3) + ci-info: 4.4.0 + dmg-builder: 26.7.0(electron-builder-squirrel-windows@24.13.3) fs-extra: 10.1.0 - is-ci: 3.0.1 lazy-val: 1.0.5 - read-config-file: 6.3.2 simple-update-notifier: 2.0.0 yargs: 17.7.2 transitivePeerDependencies: @@ -6345,15 +6986,43 @@ snapshots: transitivePeerDependencies: - supports-color - electron-store@8.2.0: + electron-publish@26.6.0: + dependencies: + '@types/fs-extra': 9.0.13 + builder-util: 26.4.1 + builder-util-runtime: 9.5.1 + chalk: 4.1.2 + form-data: 4.0.5 + fs-extra: 10.1.0 + lazy-val: 1.0.5 + mime: 2.6.0 + transitivePeerDependencies: + - supports-color + + electron-store@11.0.2: + dependencies: + conf: 15.1.0 + type-fest: 5.4.3 + + electron-to-chromium@1.5.286: {} + + electron-updater@6.7.3: dependencies: - conf: 10.2.0 - type-fest: 2.19.0 + builder-util-runtime: 9.5.1 + fs-extra: 10.1.0 + js-yaml: 4.1.1 + lazy-val: 1.0.5 + lodash.escaperegexp: 4.1.2 + lodash.isequal: 4.5.0 + semver: 7.7.3 + tiny-typed-emitter: 2.1.0 + transitivePeerDependencies: + - supports-color - electron@28.3.3: + electron@40.1.0: dependencies: '@electron/get': 2.0.3 - '@types/node': 18.19.130 + '@types/node': 24.10.10 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color @@ -6362,17 +7031,24 @@ snapshots: emoji-regex@9.2.2: {} + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + end-of-stream@1.4.5: dependencies: once: 1.4.0 - enhanced-resolve@5.18.4: + enhanced-resolve@5.19.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.0 env-paths@2.2.1: {} + env-paths@3.0.0: {} + err-code@2.0.3: {} es-abstract@1.24.1: @@ -6430,7 +7106,7 @@ snapshots: typed-array-byte-offset: 1.0.4 typed-array-length: 1.0.7 unbox-primitive: 1.1.0 - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 es-define-property@1.0.1: {} @@ -6524,17 +7200,24 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-prettier@9.1.2(eslint@9.39.2(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)): dependencies: eslint: 9.39.2(jiti@2.6.1) eslint-plugin-only-warn@1.1.0: {} - eslint-plugin-react-hooks@5.2.0(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@2.6.1)): dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 eslint: 9.39.2(jiti@2.6.1) + hermes-parser: 0.25.1 + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color - eslint-plugin-react-refresh@0.4.26(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-react-refresh@0.5.0(eslint@9.39.2(jiti@2.6.1)): dependencies: eslint: 9.39.2(jiti@2.6.1) @@ -6560,11 +7243,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.7.1(eslint@9.39.2(jiti@2.6.1))(turbo@2.8.2): + eslint-plugin-turbo@2.8.3(eslint@9.39.2(jiti@2.6.1))(turbo@2.8.3): dependencies: dotenv: 16.0.3 eslint: 9.39.2(jiti@2.6.1) - turbo: 2.8.2 + turbo: 2.8.3 eslint-scope@8.4.0: dependencies: @@ -6577,7 +7260,7 @@ snapshots: eslint@9.39.2(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.1 '@eslint/config-helpers': 0.4.2 @@ -6597,7 +7280,7 @@ snapshots: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 - esquery: 1.6.0 + esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 @@ -6624,7 +7307,7 @@ snapshots: esprima@4.0.1: {} - esquery@1.6.0: + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -6654,6 +7337,8 @@ snapshots: expect-type@1.3.0: {} + exponential-backoff@3.1.3: {} + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -6697,7 +7382,7 @@ snapshots: fast-uri@3.1.0: {} - fastq@1.19.1: + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -6725,10 +7410,6 @@ snapshots: dependencies: to-regex-range: 5.0.1 - find-up@3.0.0: - dependencies: - locate-path: 3.0.0 - find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -6766,6 +7447,12 @@ snapshots: jsonfile: 6.2.0 universalify: 2.0.1 + fs-extra@11.3.3: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fs-extra@8.1.0: dependencies: graceful-fs: 4.2.11 @@ -6783,6 +7470,10 @@ snapshots: dependencies: minipass: 3.3.6 + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.2 + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -6803,6 +7494,8 @@ snapshots: generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} get-intrinsic@1.3.0: @@ -6839,7 +7532,7 @@ snapshots: get-uri@6.0.5: dependencies: - basic-ftp: 5.0.5 + basic-ftp: 5.1.0 data-uri-to-buffer: 6.0.2 debug: 4.4.3 transitivePeerDependencies: @@ -6883,7 +7576,7 @@ snapshots: globals@14.0.0: {} - globals@15.15.0: {} + globals@17.3.0: {} globalthis@1.0.4: dependencies: @@ -6962,6 +7655,12 @@ snapshots: no-case: 2.3.2 upper-case: 1.1.3 + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + hosted-git-info@4.1.0: dependencies: lru-cache: 6.0.0 @@ -7020,6 +7719,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -7055,7 +7758,7 @@ snapshots: cli-width: 3.0.0 external-editor: 3.1.0 figures: 3.2.0 - lodash: 4.17.21 + lodash: 4.17.23 mute-stream: 0.0.8 run-async: 2.4.1 rxjs: 6.6.7 @@ -7063,15 +7766,15 @@ snapshots: strip-ansi: 6.0.1 through: 2.3.8 - inquirer@8.2.4: + inquirer@8.2.7(@types/node@25.2.0): dependencies: + '@inquirer/external-editor': 1.0.3(@types/node@25.2.0) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 cli-width: 3.0.0 - external-editor: 3.1.0 figures: 3.2.0 - lodash: 4.17.21 + lodash: 4.17.23 mute-stream: 0.0.8 ora: 5.4.1 run-async: 2.4.1 @@ -7079,7 +7782,9 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 through: 2.3.8 - wrap-ansi: 7.0.0 + wrap-ansi: 6.2.0 + transitivePeerDependencies: + - '@types/node' internal-slot@1.1.0: dependencies: @@ -7170,8 +7875,6 @@ snapshots: is-number@7.0.0: {} - is-obj@2.0.0: {} - is-path-cwd@2.2.0: {} is-path-inside@3.0.3: {} @@ -7204,7 +7907,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 is-unicode-supported@0.1.0: {} @@ -7233,6 +7936,8 @@ snapshots: isexe@2.0.0: {} + isexe@3.1.1: {} + istanbul-lib-coverage@3.2.2: {} istanbul-lib-report@3.0.1: @@ -7241,14 +7946,6 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@5.0.6: - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - debug: 4.4.3 - istanbul-lib-coverage: 3.2.2 - transitivePeerDependencies: - - supports-color - istanbul-reports@3.2.0: dependencies: html-escaper: 2.0.2 @@ -7277,25 +7974,23 @@ snapshots: jiti@2.6.1: {} - js-tokens@4.0.0: {} - - js-tokens@9.0.1: {} + js-tokens@10.0.0: {} - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 + js-tokens@4.0.0: {} js-yaml@4.1.1: dependencies: argparse: 2.0.1 + jsesc@3.1.0: {} + json-buffer@3.0.1: {} json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} - json-schema-typed@7.0.3: {} + json-schema-typed@8.0.2: {} json-stable-stringify-without-jsonify@1.0.1: {} @@ -7385,11 +8080,6 @@ snapshots: lightningcss-win32-arm64-msvc: 1.30.2 lightningcss-win32-x64-msvc: 1.30.2 - locate-path@3.0.0: - dependencies: - p-locate: 3.0.0 - path-exists: 3.0.0 - locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -7398,17 +8088,21 @@ snapshots: lodash.difference@4.5.0: {} + lodash.escaperegexp@4.1.2: {} + lodash.flatten@4.4.0: {} lodash.get@4.4.2: {} + lodash.isequal@4.5.0: {} + lodash.isplainobject@4.0.6: {} lodash.merge@4.6.2: {} lodash.union@4.6.0: {} - lodash@4.17.21: {} + lodash@4.17.23: {} log-symbols@3.0.0: dependencies: @@ -7433,24 +8127,28 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + lru-cache@6.0.0: dependencies: yallist: 4.0.0 lru-cache@7.18.3: {} - lucide-react@0.475.0(react@19.2.3): + lucide-react@0.563.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - magicast@0.5.1: + magicast@0.5.2: dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 source-map-js: 1.2.1 make-dir@4.0.0: @@ -7459,6 +8157,22 @@ snapshots: make-error@1.3.6: {} + make-fetch-happen@14.0.3: + dependencies: + '@npmcli/agent': 3.0.0 + cacache: 19.0.1 + http-cache-semantics: 4.2.0 + minipass: 7.1.2 + minipass-fetch: 4.0.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 1.0.0 + proc-log: 5.0.0 + promise-retry: 2.0.1 + ssri: 12.0.0 + transitivePeerDependencies: + - supports-color + matcher@3.0.0: dependencies: escape-string-regexp: 4.0.0 @@ -7485,12 +8199,16 @@ snapshots: mimic-fn@2.1.0: {} - mimic-fn@3.1.0: {} + mimic-function@5.0.1: {} mimic-response@1.0.1: {} mimic-response@3.1.0: {} + minimatch@10.1.2: + dependencies: + '@isaacs/brace-expansion': 5.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -7509,6 +8227,30 @@ snapshots: minimist@1.2.8: {} + minipass-collect@2.0.1: + dependencies: + minipass: 7.1.2 + + minipass-fetch@4.0.1: + dependencies: + minipass: 7.1.2 + minipass-sized: 1.0.3 + minizlib: 3.1.0 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + minipass@3.3.6: dependencies: yallist: 4.0.0 @@ -7522,6 +8264,10 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 + minizlib@3.1.0: + dependencies: + minipass: 7.1.2 + mkdirp@0.5.6: dependencies: minimist: 1.2.8 @@ -7536,25 +8282,50 @@ snapshots: natural-compare@1.4.0: {} + negotiator@1.0.0: {} + neo-async@2.6.2: {} netmask@2.0.2: {} - next-themes@0.4.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + next-themes@0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) no-case@2.3.2: dependencies: lower-case: 1.1.4 + node-abi@4.26.0: + dependencies: + semver: 7.7.3 + node-addon-api@1.7.2: optional: true + node-api-version@0.2.1: + dependencies: + semver: 7.7.3 + + node-gyp@11.5.0: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + graceful-fs: 4.2.11 + make-fetch-happen: 14.0.3 + nopt: 8.1.0 + proc-log: 5.0.0 + semver: 7.7.3 + tar: 7.5.7 + tinyglobby: 0.2.15 + which: 5.0.0 + transitivePeerDependencies: + - supports-color + node-plop@0.26.3: dependencies: - '@babel/runtime-corejs3': 7.28.4 + '@babel/runtime-corejs3': 7.29.0 '@types/inquirer': 6.5.0 change-case: 3.1.0 del: 5.1.0 @@ -7566,6 +8337,12 @@ snapshots: mkdirp: 0.5.6 resolve: 1.22.11 + node-releases@2.0.27: {} + + nopt@8.1.0: + dependencies: + abbrev: 3.0.1 + normalize-path@3.0.0: {} normalize-url@6.1.0: {} @@ -7662,18 +8439,10 @@ snapshots: p-cancelable@2.1.1: {} - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - p-locate@3.0.0: - dependencies: - p-limit: 2.3.0 - p-locate@5.0.0: dependencies: p-limit: 3.1.0 @@ -7682,7 +8451,7 @@ snapshots: dependencies: aggregate-error: 3.1.0 - p-try@2.2.0: {} + p-map@7.0.4: {} pac-proxy-agent@7.2.0: dependencies: @@ -7721,8 +8490,6 @@ snapshots: dependencies: no-case: 2.3.2 - path-exists@3.0.0: {} - path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -7740,6 +8507,8 @@ snapshots: pathe@2.0.3: {} + pe-library@0.4.1: {} + pend@1.2.0: {} picocolors@1.0.1: {} @@ -7750,10 +8519,6 @@ snapshots: picomatch@4.0.3: {} - pkg-up@3.1.0: - dependencies: - find-up: 3.0.0 - plist@3.1.0: dependencies: '@xmldom/xmldom': 0.8.11 @@ -7770,11 +8535,13 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-tailwindcss@0.6.14(prettier@3.7.4): + prettier-plugin-tailwindcss@0.7.2(prettier@3.8.1): dependencies: - prettier: 3.7.4 + prettier: 3.8.1 - prettier@3.7.4: {} + prettier@3.8.1: {} + + proc-log@5.0.0: {} process-nextick-args@2.0.1: {} @@ -7791,6 +8558,12 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + proxy-agent@6.5.0: dependencies: agent-base: 7.1.4 @@ -7824,54 +8597,60 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dom@19.2.3(react@19.2.3): + react-dom@19.2.4(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 scheduler: 0.27.0 react-is@16.13.1: {} - react-remove-scroll-bar@2.3.8(@types/react@19.2.7)(react@19.2.3): + react-remove-scroll-bar@2.3.8(@types/react@19.2.11)(react@19.2.4): dependencies: - react: 19.2.3 - react-style-singleton: 2.2.3(@types/react@19.2.7)(react@19.2.3) + react: 19.2.4 + react-style-singleton: 2.2.3(@types/react@19.2.11)(react@19.2.4) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - react-remove-scroll@2.7.2(@types/react@19.2.7)(react@19.2.3): + react-remove-scroll@2.7.2(@types/react@19.2.11)(react@19.2.4): dependencies: - react: 19.2.3 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.7)(react@19.2.3) - react-style-singleton: 2.2.3(@types/react@19.2.7)(react@19.2.3) + react: 19.2.4 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.11)(react@19.2.4) + react-style-singleton: 2.2.3(@types/react@19.2.11)(react@19.2.4) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.7)(react@19.2.3) - use-sidecar: 1.1.3(@types/react@19.2.7)(react@19.2.3) + use-callback-ref: 1.3.3(@types/react@19.2.11)(react@19.2.4) + use-sidecar: 1.1.3(@types/react@19.2.11)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - react-resizable-panels@3.0.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-resizable-panels@4.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - react-router@7.13.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: cookie: 1.1.1 - react: 19.2.3 + react: 19.2.4 set-cookie-parser: 2.7.2 optionalDependencies: - react-dom: 19.2.3(react@19.2.3) + react-dom: 19.2.4(react@19.2.4) - react-style-singleton@2.2.3(@types/react@19.2.7)(react@19.2.3): + react-style-singleton@2.2.3(@types/react@19.2.11)(react@19.2.4): dependencies: get-nonce: 1.0.1 - react: 19.2.3 + react: 19.2.4 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - react@19.2.3: {} + react@19.2.4: {} + + read-binary-file-arch@1.0.6: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color read-config-file@6.3.2: dependencies: @@ -7935,6 +8714,10 @@ snapshots: require-from-string@2.0.2: {} + resedit@1.7.2: + dependencies: + pe-library: 0.4.1 + resolve-alpn@1.2.1: {} resolve-from@4.0.0: {} @@ -7978,32 +8761,35 @@ snapshots: sprintf-js: 1.1.3 optional: true - rollup@4.54.0: + rollup@4.57.1: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.54.0 - '@rollup/rollup-android-arm64': 4.54.0 - '@rollup/rollup-darwin-arm64': 4.54.0 - '@rollup/rollup-darwin-x64': 4.54.0 - '@rollup/rollup-freebsd-arm64': 4.54.0 - '@rollup/rollup-freebsd-x64': 4.54.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.54.0 - '@rollup/rollup-linux-arm-musleabihf': 4.54.0 - '@rollup/rollup-linux-arm64-gnu': 4.54.0 - '@rollup/rollup-linux-arm64-musl': 4.54.0 - '@rollup/rollup-linux-loong64-gnu': 4.54.0 - '@rollup/rollup-linux-ppc64-gnu': 4.54.0 - '@rollup/rollup-linux-riscv64-gnu': 4.54.0 - '@rollup/rollup-linux-riscv64-musl': 4.54.0 - '@rollup/rollup-linux-s390x-gnu': 4.54.0 - '@rollup/rollup-linux-x64-gnu': 4.54.0 - '@rollup/rollup-linux-x64-musl': 4.54.0 - '@rollup/rollup-openharmony-arm64': 4.54.0 - '@rollup/rollup-win32-arm64-msvc': 4.54.0 - '@rollup/rollup-win32-ia32-msvc': 4.54.0 - '@rollup/rollup-win32-x64-gnu': 4.54.0 - '@rollup/rollup-win32-x64-msvc': 4.54.0 + '@rollup/rollup-android-arm-eabi': 4.57.1 + '@rollup/rollup-android-arm64': 4.57.1 + '@rollup/rollup-darwin-arm64': 4.57.1 + '@rollup/rollup-darwin-x64': 4.57.1 + '@rollup/rollup-freebsd-arm64': 4.57.1 + '@rollup/rollup-freebsd-x64': 4.57.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.57.1 + '@rollup/rollup-linux-arm-musleabihf': 4.57.1 + '@rollup/rollup-linux-arm64-gnu': 4.57.1 + '@rollup/rollup-linux-arm64-musl': 4.57.1 + '@rollup/rollup-linux-loong64-gnu': 4.57.1 + '@rollup/rollup-linux-loong64-musl': 4.57.1 + '@rollup/rollup-linux-ppc64-gnu': 4.57.1 + '@rollup/rollup-linux-ppc64-musl': 4.57.1 + '@rollup/rollup-linux-riscv64-gnu': 4.57.1 + '@rollup/rollup-linux-riscv64-musl': 4.57.1 + '@rollup/rollup-linux-s390x-gnu': 4.57.1 + '@rollup/rollup-linux-x64-gnu': 4.57.1 + '@rollup/rollup-linux-x64-musl': 4.57.1 + '@rollup/rollup-openbsd-x64': 4.57.1 + '@rollup/rollup-openharmony-arm64': 4.57.1 + '@rollup/rollup-win32-arm64-msvc': 4.57.1 + '@rollup/rollup-win32-ia32-msvc': 4.57.1 + '@rollup/rollup-win32-x64-gnu': 4.57.1 + '@rollup/rollup-win32-x64-msvc': 4.57.1 fsevents: 2.3.3 run-async@2.4.1: {} @@ -8049,13 +8835,15 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sax@1.4.3: {} + sax@1.4.4: {} scheduler@0.27.0: {} semver-compare@1.0.0: optional: true + semver@5.7.2: {} + semver@6.3.1: {} semver@7.6.2: {} @@ -8180,6 +8968,10 @@ snapshots: sprintf-js@1.1.3: optional: true + ssri@12.0.0: + dependencies: + minipass: 7.1.2 + stackback@0.0.2: {} stat-mode@1.0.0: {} @@ -8269,6 +9061,12 @@ snapshots: strip-json-comments@3.1.1: {} + stubborn-fs@2.0.0: + dependencies: + stubborn-utils: 1.0.2 + + stubborn-utils@1.0.2: {} + sumchecker@3.0.1: dependencies: debug: 4.4.3 @@ -8290,6 +9088,8 @@ snapshots: lower-case: 1.1.4 upper-case: 1.1.3 + tagged-tag@1.0.0: {} + tailwind-merge@3.4.0: {} tailwindcss@4.1.18: {} @@ -8313,6 +9113,14 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 + tar@7.5.7: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 + temp-file@3.4.0: dependencies: async-exit-hook: 2.0.1 @@ -8320,6 +9128,12 @@ snapshots: through@2.3.8: {} + tiny-async-pool@1.3.0: + dependencies: + semver: 5.7.2 + + tiny-typed-emitter@2.1.0: {} + tinybench@2.9.0: {} tinycolor2@1.6.0: {} @@ -8361,87 +9175,60 @@ snapshots: dependencies: utf8-byte-length: 1.0.5 - ts-api-utils@2.1.0(typescript@5.9.3): + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 - ts-node@10.9.2(@swc/core@1.15.7)(@types/node@20.19.27)(typescript@5.9.3): + ts-node@10.9.2(@swc/core@1.15.11)(@types/node@25.2.0)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.27 + '@types/node': 25.2.0 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 - diff: 4.0.2 + diff: 4.0.4 make-error: 1.3.6 typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.15.7 + '@swc/core': 1.15.11 tslib@1.14.1: {} tslib@2.8.1: {} - turbo-darwin-64@2.7.1: - optional: true - - turbo-darwin-64@2.8.2: - optional: true - - turbo-darwin-arm64@2.7.1: - optional: true - - turbo-darwin-arm64@2.8.2: - optional: true - - turbo-linux-64@2.7.1: - optional: true - - turbo-linux-64@2.8.2: - optional: true - - turbo-linux-arm64@2.7.1: + turbo-darwin-64@2.8.3: optional: true - turbo-linux-arm64@2.8.2: + turbo-darwin-arm64@2.8.3: optional: true - turbo-windows-64@2.7.1: + turbo-linux-64@2.8.3: optional: true - turbo-windows-64@2.8.2: + turbo-linux-arm64@2.8.3: optional: true - turbo-windows-arm64@2.7.1: + turbo-windows-64@2.8.3: optional: true - turbo-windows-arm64@2.8.2: + turbo-windows-arm64@2.8.3: optional: true - turbo@2.7.1: + turbo@2.8.3: optionalDependencies: - turbo-darwin-64: 2.7.1 - turbo-darwin-arm64: 2.7.1 - turbo-linux-64: 2.7.1 - turbo-linux-arm64: 2.7.1 - turbo-windows-64: 2.7.1 - turbo-windows-arm64: 2.7.1 - - turbo@2.8.2: - optionalDependencies: - turbo-darwin-64: 2.8.2 - turbo-darwin-arm64: 2.8.2 - turbo-linux-64: 2.8.2 - turbo-linux-arm64: 2.8.2 - turbo-windows-64: 2.8.2 - turbo-windows-arm64: 2.8.2 + turbo-darwin-64: 2.8.3 + turbo-darwin-arm64: 2.8.3 + turbo-linux-64: 2.8.3 + turbo-linux-arm64: 2.8.3 + turbo-windows-64: 2.8.3 + turbo-windows-arm64: 2.8.3 tw-animate-css@1.4.0: {} @@ -8454,7 +9241,9 @@ snapshots: type-fest@0.21.3: {} - type-fest@2.19.0: {} + type-fest@5.4.3: + dependencies: + tagged-tag: 1.0.0 typed-array-buffer@1.0.3: dependencies: @@ -8489,24 +9278,24 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - typescript@5.7.3: {} - typescript@5.9.3: {} uglify-js@3.19.3: optional: true + uint8array-extras@1.5.0: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -8514,14 +9303,26 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - undici-types@5.26.5: {} + undici-types@7.16.0: {} + + unique-filename@4.0.0: + dependencies: + unique-slug: 5.0.0 - undici-types@6.21.0: {} + unique-slug@5.0.0: + dependencies: + imurmurhash: 0.1.4 universalify@0.1.2: {} universalify@2.0.1: {} + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + update-check@1.5.4: dependencies: registry-auth-token: 3.3.2 @@ -8539,24 +9340,24 @@ snapshots: dependencies: punycode: 2.3.1 - use-callback-ref@1.3.3(@types/react@19.2.7)(react@19.2.3): + use-callback-ref@1.3.3(@types/react@19.2.11)(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - use-sidecar@1.1.3(@types/react@19.2.7)(react@19.2.3): + use-sidecar@1.1.3(@types/react@19.2.11)(react@19.2.4): dependencies: detect-node-es: 1.1.0 - react: 19.2.3 + react: 19.2.4 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 - use-sync-external-store@1.6.0(react@19.2.3): + use-sync-external-store@1.6.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 optional: true utf8-byte-length@1.0.5: {} @@ -8576,29 +9377,29 @@ snapshots: extsprintf: 1.4.1 optional: true - vite@7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2): + vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2): dependencies: esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.54.0 + rollup: 4.57.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 20.19.27 + '@types/node': 25.2.0 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 - vitest@4.0.16(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2): + vitest@4.0.18(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2): dependencies: - '@vitest/expect': 4.0.16 - '@vitest/mocker': 4.0.16(vite@7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2)) - '@vitest/pretty-format': 4.0.16 - '@vitest/runner': 4.0.16 - '@vitest/snapshot': 4.0.16 - '@vitest/spy': 4.0.16 - '@vitest/utils': 4.0.16 + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 es-module-lexer: 1.7.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -8610,10 +9411,10 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.0(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 20.19.27 + '@types/node': 25.2.0 transitivePeerDependencies: - jiti - less @@ -8631,6 +9432,8 @@ snapshots: dependencies: defaults: 1.0.4 + when-exit@2.1.5: {} + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -8653,7 +9456,7 @@ snapshots: isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 which-collection@1.0.2: dependencies: @@ -8662,7 +9465,7 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.19: + which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 @@ -8676,6 +9479,10 @@ snapshots: dependencies: isexe: 2.0.0 + which@5.0.0: + dependencies: + isexe: 3.1.1 + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 @@ -8685,6 +9492,12 @@ snapshots: wordwrap@1.0.0: {} + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -8703,8 +9516,12 @@ snapshots: y18n@5.0.8: {} + yallist@3.1.1: {} + yallist@4.0.0: {} + yallist@5.0.0: {} + yargs-parser@21.1.1: {} yargs@17.7.2: @@ -8732,11 +9549,15 @@ snapshots: compress-commons: 4.1.2 readable-stream: 3.6.2 - zod@3.25.76: {} + zod-validation-error@4.0.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@4.3.6: {} - zustand@5.0.11(@types/react@19.2.7)(immer@11.1.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)): + zustand@5.0.11(@types/react@19.2.11)(immer@11.1.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)): optionalDependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.11 immer: 11.1.0 - react: 19.2.3 - use-sync-external-store: 1.6.0(react@19.2.3) + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) diff --git a/frontend/testing-view/shell.nix b/shell.nix similarity index 100% rename from frontend/testing-view/shell.nix rename to shell.nix