From 480ca46a9515a0245618d4f464b2a9e5fe635905 Mon Sep 17 00:00:00 2001 From: Dan Ditomaso Date: Sun, 4 May 2025 15:55:04 -0400 Subject: [PATCH] chore: lint/format all files (#604) * chore: lint/format all files * Fix config sidebar button state (#602) * chore: Update deno.lock version and add Radix UI slider component (#601) * fix: improve how table addresses even/odd rows --------- Co-authored-by: philon- Co-authored-by: Kamil Dzieniszewski --- deno.json | 13 + deno.lock | 1648 ++++++++--------- package.json | 76 +- src/App.tsx | 42 +- src/__mocks__/components/UI/Button.tsx | 19 +- src/__mocks__/components/UI/Checkbox.tsx | 23 +- src/__mocks__/components/UI/Dialog/Dialog.tsx | 40 +- src/__mocks__/components/UI/Label.tsx | 19 +- src/__mocks__/components/UI/Link.tsx | 12 +- src/components/BatteryStatus.tsx | 46 +- src/components/CommandPalette/index.tsx | 34 +- .../DeleteMessagesDialog.test.tsx | 67 +- .../DeleteMessagesDialog.tsx | 1 - src/components/Dialog/DeviceNameDialog.tsx | 18 +- src/components/Dialog/DialogManager.tsx | 1 - src/components/Dialog/ImportDialog.tsx | 2 +- .../Dialog/LocationResponseDialog.tsx | 5 +- src/components/Dialog/NewDeviceDialog.tsx | 14 +- .../NodeDetailsDialog.test.tsx | 33 +- .../NodeDetailsDialog/NodeDetailsDialog.tsx | 28 +- src/components/Dialog/NodeOptionsDialog.tsx | 5 +- src/components/Dialog/PkiRegenerateDialog.tsx | 2 +- src/components/Dialog/QRDialog.tsx | 24 +- .../Dialog/RebootOTADialog.test.tsx | 56 +- src/components/Dialog/RebootOTADialog.tsx | 14 +- .../RefreshKeysDialog.test.tsx | 30 +- .../RefreshKeysDialog/RefreshKeysDialog.tsx | 19 +- .../useRefreshKeysDialog.test.ts | 14 +- .../RefreshKeysDialog/useRefreshKeysDialog.ts | 9 +- .../Dialog/TracerouteResponseDialog.tsx | 4 +- .../UnsafeRolesDialog.test.tsx | 73 +- .../UnsafeRolesDialog/UnsafeRolesDialog.tsx | 41 +- .../useUnsafeRolesDialog.test.tsx | 98 +- .../UnsafeRolesDialog/useUnsafeRolesDialog.ts | 6 +- src/components/Form/DynamicForm.tsx | 5 +- src/components/Form/FormInput.tsx | 28 +- src/components/Form/FormMultiSelect.tsx | 2 +- src/components/Form/FormPasswordGenerator.tsx | 2 +- src/components/Form/FormSelect.tsx | 5 +- src/components/Form/FormWrapper.tsx | 4 +- src/components/PageComponents/Channel.tsx | 13 +- .../Config/Device/Device.test.tsx | 66 +- .../PageComponents/Config/Device/index.tsx | 12 +- .../Config/Network/Network.test.tsx | 190 +- .../PageComponents/Config/Network/index.tsx | 14 +- .../PageComponents/Config/Position.tsx | 2 +- .../Config/Security/Security.tsx | 14 +- src/components/PageComponents/Connect/BLE.tsx | 10 +- .../PageComponents/Connect/HTTP.test.tsx | 24 +- .../PageComponents/Connect/HTTP.tsx | 39 +- .../PageComponents/Connect/Serial.tsx | 11 +- .../PageComponents/Map/NodeDetail.tsx | 19 +- .../PageComponents/Messages/ChannelChat.tsx | 20 +- .../Messages/MessageActionsMenu.tsx | 20 +- .../Messages/MessageInput.test.tsx | 168 +- .../PageComponents/Messages/MessageInput.tsx | 11 +- .../PageComponents/Messages/MessageItem.tsx | 99 +- .../Messages/TraceRoute.test.tsx | 25 +- .../PageComponents/Messages/TraceRoute.tsx | 13 +- src/components/PageLayout.tsx | 18 +- src/components/ThemeSwitcher.tsx | 2 +- src/components/UI/Avatar.tsx | 22 +- src/components/UI/Button.tsx | 9 +- src/components/UI/Checkbox/Checkbox.test.tsx | 111 +- src/components/UI/Dialog.tsx | 11 +- src/components/UI/ErrorPage.tsx | 1 - src/components/UI/Footer.tsx | 11 +- src/components/UI/Generator.tsx | 168 +- src/components/UI/Input.tsx | 55 +- src/components/UI/Sidebar/SidebarButton.tsx | 20 +- src/components/UI/Sidebar/sidebarButton.tsx | 20 +- src/components/generic/Table/index.test.tsx | 207 ++- src/components/generic/Table/index.tsx | 178 +- src/core/dto/NodeNumToNodeInfoDTO.ts | 13 +- src/core/dto/PacketToMessageDTO.ts | 24 +- src/core/hooks/useCopyToClipboard.ts | 12 +- src/core/hooks/useKeyBackupReminder.tsx | 13 +- src/core/hooks/useLocalStorage.test.ts | 78 +- src/core/hooks/useLocalStorage.ts | 27 +- .../hooks/usePasswordVisibilityToggle.test.ts | 28 +- src/core/hooks/usePasswordVisibilityToggle.ts | 14 +- src/core/hooks/usePinnedItems.test.ts | 11 +- src/core/hooks/usePinnedItems.ts | 9 +- src/core/hooks/useToast.test.tsx | 108 +- src/core/stores/deviceStore.ts | 154 +- src/core/stores/messageStore/index.ts | 91 +- .../stores/messageStore/messageStore.test.ts | 308 +-- src/core/stores/messageStore/types.ts | 20 +- src/core/stores/sidebarStore.tsx | 18 +- src/core/stores/storage/indexDB.ts | 25 +- src/core/subscriptions.ts | 17 +- src/core/utils/eventBus.test.ts | 4 +- src/core/utils/eventBus.ts | 18 +- src/core/utils/github.ts | 1 - src/core/utils/ip.ts | 5 +- src/core/utils/string.ts | 23 +- src/index.css | 4 +- src/pages/Channels.tsx | 9 +- src/pages/Messages.test.tsx | 129 +- src/pages/Messages.tsx | 240 ++- src/pages/Nodes.tsx | 21 +- src/tests/setupTests.ts | 25 +- src/validation/config/network.ts | 9 +- src/validation/validate.ts | 4 +- 104 files changed, 3112 insertions(+), 2535 deletions(-) diff --git a/deno.json b/deno.json index 2ab367be..6a835aef 100644 --- a/deno.json +++ b/deno.json @@ -28,6 +28,19 @@ ], "strictPropertyInitialization": false }, + "fmt": { + "exclude": [ + "*.test.ts", + "*.test.tsx" + ] + }, + "lint": { + "exclude": [ + "*.test.ts", + "*.test.tsx" + ], + "report": "pretty" + }, "unstable": [ "sloppy-imports" ] diff --git a/deno.lock b/deno.lock index 5e133341..33d1e81a 100644 --- a/deno.lock +++ b/deno.lock @@ -7,71 +7,71 @@ "npm:@jsr/meshtastic__transport-http@*": "0.2.1", "npm:@jsr/meshtastic__transport-web-bluetooth@*": "0.1.1", "npm:@jsr/meshtastic__transport-web-serial@*": "0.2.1", - "npm:@noble/curves@^1.8.1": "1.8.1", - "npm:@radix-ui/react-accordion@^1.2.3": "1.2.3_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-checkbox@^1.1.4": "1.1.4_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-dialog@^1.1.6": "1.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-dropdown-menu@^2.1.6": "2.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-label@^2.1.2": "2.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-menubar@^1.1.6": "1.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-popover@^1.1.6": "1.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-scroll-area@^1.2.3": "1.2.3_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-select@^2.1.6": "2.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-separator@^1.1.2": "1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-slider@^1.3.2": "1.3.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-switch@^1.1.3": "1.1.3_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-tabs@^1.1.3": "1.1.3_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-toast@^1.2.6": "1.2.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@radix-ui/react-tooltip@^1.1.8": "1.1.8_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:@tailwindcss/postcss@^4.1.0": "4.1.0", + "npm:@noble/curves@^1.9.0": "1.9.0", + "npm:@radix-ui/react-accordion@^1.2.8": "1.2.8_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-checkbox@^1.2.3": "1.2.3_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-dialog@^1.1.11": "1.1.11_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-dropdown-menu@^2.1.12": "2.1.12_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-label@^2.1.4": "2.1.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-menubar@^1.1.12": "1.1.12_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-popover@^1.1.11": "1.1.11_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-scroll-area@^1.2.6": "1.2.6_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-select@^2.2.2": "2.2.2_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-separator@^1.1.4": "1.1.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-slider@^1.3.2": "1.3.2_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-switch@^1.2.2": "1.2.2_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-tabs@^1.1.9": "1.1.9_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-toast@^1.2.11": "1.2.11_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-tooltip@^1.2.4": "1.2.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@tailwindcss/postcss@^4.1.5": "4.1.5", "npm:@testing-library/jest-dom@^6.6.3": "6.6.3", - "npm:@testing-library/react@^16.2.0": "16.2.0_@testing-library+dom@10.4.0_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@testing-library/react@^16.3.0": "16.3.0_@testing-library+dom@10.4.0_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0", "npm:@testing-library/user-event@^14.6.1": "14.6.1_@testing-library+dom@10.4.0", "npm:@turf/turf@^7.2.0": "7.2.0", - "npm:@types/chrome@^0.0.313": "0.0.313", + "npm:@types/chrome@^0.0.318": "0.0.318", "npm:@types/js-cookie@^3.0.6": "3.0.6", - "npm:@types/node@^22.13.17": "22.13.17", - "npm:@types/react-dom@^19.0.4": "19.0.4_@types+react@19.0.12", - "npm:@types/react@^19.0.12": "19.0.12", - "npm:@types/serviceworker@^0.0.127": "0.0.127", + "npm:@types/node@^22.15.3": "22.15.3", + "npm:@types/react-dom@^19.1.3": "19.1.3_@types+react@19.1.2", + "npm:@types/react@^19.1.2": "19.1.2", + "npm:@types/serviceworker@^0.0.133": "0.0.133", "npm:@types/w3c-web-serial@^1.0.8": "1.0.8", "npm:@types/web-bluetooth@^0.0.21": "0.0.21", - "npm:@vitejs/plugin-react@^4.3.4": "4.3.4_vite@6.2.4__@types+node@22.13.17_@babel+core@7.26.10_@types+node@22.13.17", + "npm:@vitejs/plugin-react@^4.4.1": "4.4.1_vite@6.3.4__@types+node@22.15.3__picomatch@4.0.2_@babel+core@7.27.1_@types+node@22.15.3", "npm:autoprefixer@^10.4.21": "10.4.21_postcss@8.5.3", "npm:base64-js@^1.5.1": "1.5.1", - "npm:class-validator@~0.14.1": "0.14.1", + "npm:class-validator@~0.14.2": "0.14.2", "npm:class-variance-authority@~0.7.1": "0.7.1", "npm:clsx@^2.1.1": "2.1.1", - "npm:cmdk@^1.1.1": "1.1.1_react@19.1.0_react-dom@19.1.0__react@19.1.0_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12", + "npm:cmdk@^1.1.1": "1.1.1_react@19.1.0_react-dom@19.1.0__react@19.1.0_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2", "npm:crypto-random-string@5": "5.0.0", "npm:gzipper@^8.2.1": "8.2.1", - "npm:happy-dom@^17.4.4": "17.4.4", + "npm:happy-dom@^17.4.6": "17.4.6", "npm:idb-keyval@^6.2.1": "6.2.1", "npm:immer@^10.1.1": "10.1.1", "npm:js-cookie@^3.0.5": "3.0.5", - "npm:lucide-react@0.486": "0.486.0_react@19.1.0", - "npm:maplibre-gl@5.3.0": "5.3.0", + "npm:lucide-react@0.507": "0.507.0_react@19.1.0", + "npm:maplibre-gl@5.4.0": "5.4.0", "npm:postcss@^8.5.3": "8.5.3", "npm:react-dom@^19.1.0": "19.1.0_react@19.1.0", - "npm:react-error-boundary@5": "5.0.0_react@19.1.0", - "npm:react-hook-form@^7.55.0": "7.55.0_react@19.1.0", - "npm:react-map-gl@8.0.2": "8.0.2_maplibre-gl@5.3.0_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:react-error-boundary@6": "6.0.0_react@19.1.0", + "npm:react-hook-form@^7.56.2": "7.56.2_react@19.1.0", + "npm:react-map-gl@8.0.4": "8.0.4_maplibre-gl@5.4.0_react@19.1.0_react-dom@19.1.0__react@19.1.0", "npm:react-qrcode-logo@3": "3.0.0_react@19.1.0_react-dom@19.1.0__react@19.1.0", "npm:react@^19.1.0": "19.1.0", "npm:rfc4648@^1.5.4": "1.5.4", - "npm:simple-git-hooks@^2.12.1": "2.12.1", - "npm:tailwind-merge@^3.1.0": "3.1.0", - "npm:tailwindcss-animate@^1.0.7": "1.0.7_tailwindcss@4.1.0", - "npm:tailwindcss@^4.1.0": "4.1.0", + "npm:simple-git-hooks@^2.13.0": "2.13.0", + "npm:tailwind-merge@^3.2.0": "3.2.0", + "npm:tailwindcss-animate@^1.0.7": "1.0.7_tailwindcss@4.1.5", + "npm:tailwindcss@^4.1.5": "4.1.5", "npm:tar@^7.4.3": "7.4.3", "npm:testing-library@^0.0.2": "0.0.2_@angular+common@6.1.10__@angular+core@6.1.10___rxjs@6.6.7___zone.js@0.8.29__rxjs@6.6.7_@angular+core@6.1.10__rxjs@6.6.7__zone.js@0.8.29", - "npm:typescript@^5.8.2": "5.8.2", - "npm:vite-plugin-node-polyfills@0.23": "0.23.0_vite@6.2.4__@types+node@22.13.17_@types+node@22.13.17", - "npm:vite-plugin-pwa@1": "1.0.0_vite@6.2.4__@types+node@22.13.17_workbox-build@7.3.0__ajv@8.17.1__@babel+core@7.26.10__rollup@2.79.2_workbox-window@7.3.0_@types+node@22.13.17", - "npm:vite@^6.2.4": "6.2.4_@types+node@22.13.17", - "npm:vitest@^3.1.1": "3.1.1_@types+node@22.13.17_happy-dom@17.4.4_vite@6.2.4__@types+node@22.13.17", - "npm:zod@^3.24.2": "3.24.2", - "npm:zustand@5.0.3": "5.0.3_@types+react@19.0.12_immer@10.1.1_react@19.1.0" + "npm:typescript@^5.8.3": "5.8.3", + "npm:vite-plugin-node-polyfills@0.23": "0.23.0_vite@6.3.4__@types+node@22.15.3__picomatch@4.0.2_@types+node@22.15.3", + "npm:vite-plugin-pwa@1": "1.0.0_vite@6.3.4__@types+node@22.15.3__picomatch@4.0.2_workbox-build@7.3.0__ajv@8.17.1__@babel+core@7.27.1__rollup@2.79.2_workbox-window@7.3.0_@types+node@22.15.3", + "npm:vite@^6.3.4": "6.3.4_@types+node@22.15.3_picomatch@4.0.2", + "npm:vitest@^3.1.2": "3.1.2_@types+node@22.15.3_happy-dom@17.4.6_vite@6.3.4__@types+node@22.15.3__picomatch@4.0.2", + "npm:zod@^3.24.3": "3.24.3", + "npm:zustand@5.0.4": "5.0.4_@types+react@19.1.2_immer@10.1.1_react@19.1.0" }, "npm": { "@adobe/css-tools@4.4.2": { @@ -112,19 +112,19 @@ "leven" ] }, - "@babel/code-frame@7.26.2": { - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "@babel/code-frame@7.27.1": { + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dependencies": [ "@babel/helper-validator-identifier", "js-tokens", "picocolors" ] }, - "@babel/compat-data@7.26.8": { - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==" + "@babel/compat-data@7.27.1": { + "integrity": "sha512-Q+E+rd/yBzNQhXkG+zQnF58e4zoZfBedaxwzPmicKsiK3nt8iJYrSrDbjwFFDGC4f+rPafqRaPH6TsDoSvMf7A==" }, - "@babel/core@7.26.10": { - "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "@babel/core@7.27.1": { + "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", "dependencies": [ "@ampproject/remapping", "@babel/code-frame", @@ -143,8 +143,8 @@ "semver" ] }, - "@babel/generator@7.27.0": { - "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "@babel/generator@7.27.1": { + "integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==", "dependencies": [ "@babel/parser", "@babel/types", @@ -153,14 +153,14 @@ "jsesc@3.1.0" ] }, - "@babel/helper-annotate-as-pure@7.25.9": { - "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "@babel/helper-annotate-as-pure@7.27.1": { + "integrity": "sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==", "dependencies": [ "@babel/types" ] }, - "@babel/helper-compilation-targets@7.27.0": { - "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "@babel/helper-compilation-targets@7.27.1": { + "integrity": "sha512-2YaDd/Rd9E598B5+WIc8wJPmWETiiJXFYVE60oX8FDohv7rAUU3CQj+A1MgeEmcsk2+dQuEjIe/GDvig0SqL4g==", "dependencies": [ "@babel/compat-data", "@babel/helper-validator-option", @@ -169,8 +169,8 @@ "semver" ] }, - "@babel/helper-create-class-features-plugin@7.27.0_@babel+core@7.26.10": { - "integrity": "sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==", + "@babel/helper-create-class-features-plugin@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", "dependencies": [ "@babel/core", "@babel/helper-annotate-as-pure", @@ -182,8 +182,8 @@ "semver" ] }, - "@babel/helper-create-regexp-features-plugin@7.27.0_@babel+core@7.26.10": { - "integrity": "sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==", + "@babel/helper-create-regexp-features-plugin@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", "dependencies": [ "@babel/core", "@babel/helper-annotate-as-pure", @@ -191,7 +191,7 @@ "semver" ] }, - "@babel/helper-define-polyfill-provider@0.6.4_@babel+core@7.26.10": { + "@babel/helper-define-polyfill-provider@0.6.4_@babel+core@7.27.1": { "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", "dependencies": [ "@babel/core", @@ -202,22 +202,22 @@ "resolve" ] }, - "@babel/helper-member-expression-to-functions@7.25.9": { - "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "@babel/helper-member-expression-to-functions@7.27.1": { + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", "dependencies": [ "@babel/traverse", "@babel/types" ] }, - "@babel/helper-module-imports@7.25.9": { - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "@babel/helper-module-imports@7.27.1": { + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dependencies": [ "@babel/traverse", "@babel/types" ] }, - "@babel/helper-module-transforms@7.26.0_@babel+core@7.26.10": { - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "@babel/helper-module-transforms@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==", "dependencies": [ "@babel/core", "@babel/helper-module-imports", @@ -225,17 +225,17 @@ "@babel/traverse" ] }, - "@babel/helper-optimise-call-expression@7.25.9": { - "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "@babel/helper-optimise-call-expression@7.27.1": { + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "dependencies": [ "@babel/types" ] }, - "@babel/helper-plugin-utils@7.26.5": { - "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==" + "@babel/helper-plugin-utils@7.27.1": { + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==" }, - "@babel/helper-remap-async-to-generator@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "@babel/helper-remap-async-to-generator@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", "dependencies": [ "@babel/core", "@babel/helper-annotate-as-pure", @@ -243,8 +243,8 @@ "@babel/traverse" ] }, - "@babel/helper-replace-supers@7.26.5_@babel+core@7.26.10": { - "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", + "@babel/helper-replace-supers@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", "dependencies": [ "@babel/core", "@babel/helper-member-expression-to-functions", @@ -252,68 +252,68 @@ "@babel/traverse" ] }, - "@babel/helper-skip-transparent-expression-wrappers@7.25.9": { - "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "@babel/helper-skip-transparent-expression-wrappers@7.27.1": { + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "dependencies": [ "@babel/traverse", "@babel/types" ] }, - "@babel/helper-string-parser@7.25.9": { - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==" + "@babel/helper-string-parser@7.27.1": { + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==" }, - "@babel/helper-validator-identifier@7.25.9": { - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==" + "@babel/helper-validator-identifier@7.27.1": { + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==" }, - "@babel/helper-validator-option@7.25.9": { - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==" + "@babel/helper-validator-option@7.27.1": { + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==" }, - "@babel/helper-wrap-function@7.25.9": { - "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "@babel/helper-wrap-function@7.27.1": { + "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", "dependencies": [ "@babel/template", "@babel/traverse", "@babel/types" ] }, - "@babel/helpers@7.27.0": { - "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "@babel/helpers@7.27.1": { + "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==", "dependencies": [ "@babel/template", "@babel/types" ] }, - "@babel/parser@7.27.0": { - "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "@babel/parser@7.27.1": { + "integrity": "sha512-I0dZ3ZpCrJ1c04OqlNsQcKiZlsrXf/kkE4FXzID9rIOYICsAbA8mMDzhW/luRNAHdCNt7os/u8wenklZDlUVUQ==", "dependencies": [ "@babel/types" ], "bin": true }, - "@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils", "@babel/traverse" ] }, - "@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils", @@ -321,35 +321,35 @@ "@babel/plugin-transform-optional-chaining" ] }, - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils", "@babel/traverse" ] }, - "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2_@babel+core@7.26.10": { + "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2_@babel+core@7.27.1": { "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dependencies": [ "@babel/core" ] }, - "@babel/plugin-syntax-import-assertions@7.26.0_@babel+core@7.26.10": { - "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "@babel/plugin-syntax-import-assertions@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-syntax-import-attributes@7.26.0_@babel+core@7.26.10": { - "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "@babel/plugin-syntax-import-attributes@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-syntax-unicode-sets-regex@7.18.6_@babel+core@7.26.10": { + "@babel/plugin-syntax-unicode-sets-regex@7.18.6_@babel+core@7.27.1": { "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dependencies": [ "@babel/core", @@ -357,15 +357,15 @@ "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-arrow-functions@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "@babel/plugin-transform-arrow-functions@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-async-generator-functions@7.26.8_@babel+core@7.26.10": { - "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", + "@babel/plugin-transform-async-generator-functions@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils", @@ -373,8 +373,8 @@ "@babel/traverse" ] }, - "@babel/plugin-transform-async-to-generator@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "@babel/plugin-transform-async-to-generator@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", "dependencies": [ "@babel/core", "@babel/helper-module-imports", @@ -382,38 +382,38 @@ "@babel/helper-remap-async-to-generator" ] }, - "@babel/plugin-transform-block-scoped-functions@7.26.5_@babel+core@7.26.10": { - "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", + "@babel/plugin-transform-block-scoped-functions@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-block-scoping@7.27.0_@babel+core@7.26.10": { - "integrity": "sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==", + "@babel/plugin-transform-block-scoping@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-QEcFlMl9nGTgh1rn2nIeU5bkfb9BAjaQcWbiP4LvKxUot52ABcTkpcyJ7f2Q2U2RuQ84BNLgts3jRme2dTx6Fw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-class-properties@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "@babel/plugin-transform-class-properties@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", "dependencies": [ "@babel/core", "@babel/helper-create-class-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-class-static-block@7.26.0_@babel+core@7.26.10": { - "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "@babel/plugin-transform-class-static-block@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==", "dependencies": [ "@babel/core", "@babel/helper-create-class-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-classes@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "@babel/plugin-transform-classes@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==", "dependencies": [ "@babel/core", "@babel/helper-annotate-as-pure", @@ -424,75 +424,75 @@ "globals" ] }, - "@babel/plugin-transform-computed-properties@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "@babel/plugin-transform-computed-properties@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils", "@babel/template" ] }, - "@babel/plugin-transform-destructuring@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "@babel/plugin-transform-destructuring@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-ttDCqhfvpE9emVkXbPD8vyxxh4TWYACVybGkDj+oReOGwnp066ITEivDlLwe0b1R0+evJ13IXQuLNB5w1fhC5Q==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-dotall-regex@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "@babel/plugin-transform-dotall-regex@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", "dependencies": [ "@babel/core", "@babel/helper-create-regexp-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-duplicate-keys@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "@babel/plugin-transform-duplicate-keys@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", "dependencies": [ "@babel/core", "@babel/helper-create-regexp-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-dynamic-import@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "@babel/plugin-transform-dynamic-import@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-exponentiation-operator@7.26.3_@babel+core@7.26.10": { - "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "@babel/plugin-transform-exponentiation-operator@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-export-namespace-from@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "@babel/plugin-transform-export-namespace-from@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-for-of@7.26.9_@babel+core@7.26.10": { - "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==", + "@babel/plugin-transform-for-of@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils", "@babel/helper-skip-transparent-expression-wrappers" ] }, - "@babel/plugin-transform-function-name@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "@babel/plugin-transform-function-name@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "dependencies": [ "@babel/core", "@babel/helper-compilation-targets", @@ -500,52 +500,52 @@ "@babel/traverse" ] }, - "@babel/plugin-transform-json-strings@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "@babel/plugin-transform-json-strings@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-literals@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "@babel/plugin-transform-literals@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-logical-assignment-operators@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "@babel/plugin-transform-logical-assignment-operators@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-member-expression-literals@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "@babel/plugin-transform-member-expression-literals@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-modules-amd@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "@babel/plugin-transform-modules-amd@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "dependencies": [ "@babel/core", "@babel/helper-module-transforms", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-modules-commonjs@7.26.3_@babel+core@7.26.10": { - "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "@babel/plugin-transform-modules-commonjs@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", "dependencies": [ "@babel/core", "@babel/helper-module-transforms", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-modules-systemjs@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "@babel/plugin-transform-modules-systemjs@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", "dependencies": [ "@babel/core", "@babel/helper-module-transforms", @@ -554,45 +554,45 @@ "@babel/traverse" ] }, - "@babel/plugin-transform-modules-umd@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "@babel/plugin-transform-modules-umd@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "dependencies": [ "@babel/core", "@babel/helper-module-transforms", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-named-capturing-groups-regex@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "@babel/plugin-transform-named-capturing-groups-regex@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", "dependencies": [ "@babel/core", "@babel/helper-create-regexp-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-new-target@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "@babel/plugin-transform-new-target@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-nullish-coalescing-operator@7.26.6_@babel+core@7.26.10": { - "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", + "@babel/plugin-transform-nullish-coalescing-operator@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-numeric-separator@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "@babel/plugin-transform-numeric-separator@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-object-rest-spread@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "@babel/plugin-transform-object-rest-spread@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-/sSliVc9gHE20/7D5qsdGlq7RG5NCDTWsAhyqzGuq174EtWJoGzIu1BQ7G56eDsTcy1jseBZwv50olSdXOlGuA==", "dependencies": [ "@babel/core", "@babel/helper-compilation-targets", @@ -600,46 +600,46 @@ "@babel/plugin-transform-parameters" ] }, - "@babel/plugin-transform-object-super@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "@babel/plugin-transform-object-super@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils", "@babel/helper-replace-supers" ] }, - "@babel/plugin-transform-optional-catch-binding@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "@babel/plugin-transform-optional-catch-binding@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-optional-chaining@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "@babel/plugin-transform-optional-chaining@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils", "@babel/helper-skip-transparent-expression-wrappers" ] }, - "@babel/plugin-transform-parameters@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "@babel/plugin-transform-parameters@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-private-methods@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "@babel/plugin-transform-private-methods@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", "dependencies": [ "@babel/core", "@babel/helper-create-class-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-private-property-in-object@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "@babel/plugin-transform-private-property-in-object@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", "dependencies": [ "@babel/core", "@babel/helper-annotate-as-pure", @@ -647,119 +647,118 @@ "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-property-literals@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "@babel/plugin-transform-property-literals@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-react-jsx-self@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "@babel/plugin-transform-react-jsx-self@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-react-jsx-source@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "@babel/plugin-transform-react-jsx-source@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-regenerator@7.27.0_@babel+core@7.26.10": { - "integrity": "sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==", + "@babel/plugin-transform-regenerator@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-B19lbbL7PMrKr52BNPjCqg1IyNUIjTcxKj8uX9zHO+PmWN93s19NDr/f69mIkEp2x9nmDJ08a7lgHaTTzvW7mw==", "dependencies": [ "@babel/core", - "@babel/helper-plugin-utils", - "regenerator-transform" + "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-regexp-modifiers@7.26.0_@babel+core@7.26.10": { - "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "@babel/plugin-transform-regexp-modifiers@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", "dependencies": [ "@babel/core", "@babel/helper-create-regexp-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-reserved-words@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "@babel/plugin-transform-reserved-words@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-shorthand-properties@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "@babel/plugin-transform-shorthand-properties@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-spread@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "@babel/plugin-transform-spread@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils", "@babel/helper-skip-transparent-expression-wrappers" ] }, - "@babel/plugin-transform-sticky-regex@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "@babel/plugin-transform-sticky-regex@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-template-literals@7.26.8_@babel+core@7.26.10": { - "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==", + "@babel/plugin-transform-template-literals@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-typeof-symbol@7.27.0_@babel+core@7.26.10": { - "integrity": "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==", + "@babel/plugin-transform-typeof-symbol@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-unicode-escapes@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "@babel/plugin-transform-unicode-escapes@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-unicode-property-regex@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "@babel/plugin-transform-unicode-property-regex@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", "dependencies": [ "@babel/core", "@babel/helper-create-regexp-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-unicode-regex@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "@babel/plugin-transform-unicode-regex@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", "dependencies": [ "@babel/core", "@babel/helper-create-regexp-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-unicode-sets-regex@7.25.9_@babel+core@7.26.10": { - "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "@babel/plugin-transform-unicode-sets-regex@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", "dependencies": [ "@babel/core", "@babel/helper-create-regexp-features-plugin", "@babel/helper-plugin-utils" ] }, - "@babel/preset-env@7.26.9_@babel+core@7.26.10": { - "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", + "@babel/preset-env@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-TZ5USxFpLgKDpdEt8YWBR7p6g+bZo6sHaXLqP2BY/U0acaoI8FTVflcYCr/v94twM1C5IWFdZ/hscq9WjUeLXA==", "dependencies": [ "@babel/compat-data", "@babel/core", @@ -833,7 +832,7 @@ "semver" ] }, - "@babel/preset-modules@0.1.6-no-external-plugins_@babel+core@7.26.10": { + "@babel/preset-modules@0.1.6-no-external-plugins_@babel+core@7.27.1": { "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dependencies": [ "@babel/core", @@ -842,22 +841,19 @@ "esutils" ] }, - "@babel/runtime@7.27.0": { - "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", - "dependencies": [ - "regenerator-runtime" - ] + "@babel/runtime@7.27.1": { + "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==" }, - "@babel/template@7.27.0": { - "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "@babel/template@7.27.1": { + "integrity": "sha512-Fyo3ghWMqkHHpHQCoBs2VnYjR4iWFFjguTDEqA5WgZDOrFesVjMhMM2FSqTKSoUSDO1VQtavj8NFpdRBEvJTtg==", "dependencies": [ "@babel/code-frame", "@babel/parser", "@babel/types" ] }, - "@babel/traverse@7.27.0": { - "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "@babel/traverse@7.27.1": { + "integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==", "dependencies": [ "@babel/code-frame", "@babel/generator", @@ -868,8 +864,8 @@ "globals" ] }, - "@babel/types@7.27.0": { - "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "@babel/types@7.27.1": { + "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", "dependencies": [ "@babel/helper-string-parser", "@babel/helper-validator-identifier" @@ -878,139 +874,158 @@ "@bufbuild/protobuf@2.2.5": { "integrity": "sha512-/g5EzJifw5GF8aren8wZ/G5oMuPoGeS6MQD3ca8ddcvdXR5UELUfdTZITCGNhNXynY/AYl3Z4plmxdj/tRl/hQ==" }, - "@esbuild/aix-ppc64@0.25.2": { - "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", + "@emnapi/core@1.4.3": { + "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", + "dependencies": [ + "@emnapi/wasi-threads", + "tslib@2.8.1" + ] + }, + "@emnapi/runtime@1.4.3": { + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "dependencies": [ + "tslib@2.8.1" + ] + }, + "@emnapi/wasi-threads@1.0.2": { + "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", + "dependencies": [ + "tslib@2.8.1" + ] + }, + "@esbuild/aix-ppc64@0.25.3": { + "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==", "os": ["aix"], "cpu": ["ppc64"] }, - "@esbuild/android-arm64@0.25.2": { - "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", + "@esbuild/android-arm64@0.25.3": { + "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==", "os": ["android"], "cpu": ["arm64"] }, - "@esbuild/android-arm@0.25.2": { - "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", + "@esbuild/android-arm@0.25.3": { + "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==", "os": ["android"], "cpu": ["arm"] }, - "@esbuild/android-x64@0.25.2": { - "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", + "@esbuild/android-x64@0.25.3": { + "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==", "os": ["android"], "cpu": ["x64"] }, - "@esbuild/darwin-arm64@0.25.2": { - "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", + "@esbuild/darwin-arm64@0.25.3": { + "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==", "os": ["darwin"], "cpu": ["arm64"] }, - "@esbuild/darwin-x64@0.25.2": { - "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", + "@esbuild/darwin-x64@0.25.3": { + "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==", "os": ["darwin"], "cpu": ["x64"] }, - "@esbuild/freebsd-arm64@0.25.2": { - "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", + "@esbuild/freebsd-arm64@0.25.3": { + "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==", "os": ["freebsd"], "cpu": ["arm64"] }, - "@esbuild/freebsd-x64@0.25.2": { - "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", + "@esbuild/freebsd-x64@0.25.3": { + "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==", "os": ["freebsd"], "cpu": ["x64"] }, - "@esbuild/linux-arm64@0.25.2": { - "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", + "@esbuild/linux-arm64@0.25.3": { + "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==", "os": ["linux"], "cpu": ["arm64"] }, - "@esbuild/linux-arm@0.25.2": { - "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", + "@esbuild/linux-arm@0.25.3": { + "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==", "os": ["linux"], "cpu": ["arm"] }, - "@esbuild/linux-ia32@0.25.2": { - "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", + "@esbuild/linux-ia32@0.25.3": { + "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==", "os": ["linux"], "cpu": ["ia32"] }, - "@esbuild/linux-loong64@0.25.2": { - "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", + "@esbuild/linux-loong64@0.25.3": { + "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==", "os": ["linux"], "cpu": ["loong64"] }, - "@esbuild/linux-mips64el@0.25.2": { - "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", + "@esbuild/linux-mips64el@0.25.3": { + "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==", "os": ["linux"], "cpu": ["mips64el"] }, - "@esbuild/linux-ppc64@0.25.2": { - "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", + "@esbuild/linux-ppc64@0.25.3": { + "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==", "os": ["linux"], "cpu": ["ppc64"] }, - "@esbuild/linux-riscv64@0.25.2": { - "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", + "@esbuild/linux-riscv64@0.25.3": { + "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==", "os": ["linux"], "cpu": ["riscv64"] }, - "@esbuild/linux-s390x@0.25.2": { - "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", + "@esbuild/linux-s390x@0.25.3": { + "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==", "os": ["linux"], "cpu": ["s390x"] }, - "@esbuild/linux-x64@0.25.2": { - "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", + "@esbuild/linux-x64@0.25.3": { + "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==", "os": ["linux"], "cpu": ["x64"] }, - "@esbuild/netbsd-arm64@0.25.2": { - "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", + "@esbuild/netbsd-arm64@0.25.3": { + "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==", "os": ["netbsd"], "cpu": ["arm64"] }, - "@esbuild/netbsd-x64@0.25.2": { - "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", + "@esbuild/netbsd-x64@0.25.3": { + "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==", "os": ["netbsd"], "cpu": ["x64"] }, - "@esbuild/openbsd-arm64@0.25.2": { - "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", + "@esbuild/openbsd-arm64@0.25.3": { + "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==", "os": ["openbsd"], "cpu": ["arm64"] }, - "@esbuild/openbsd-x64@0.25.2": { - "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", + "@esbuild/openbsd-x64@0.25.3": { + "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==", "os": ["openbsd"], "cpu": ["x64"] }, - "@esbuild/sunos-x64@0.25.2": { - "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", + "@esbuild/sunos-x64@0.25.3": { + "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==", "os": ["sunos"], "cpu": ["x64"] }, - "@esbuild/win32-arm64@0.25.2": { - "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", + "@esbuild/win32-arm64@0.25.3": { + "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==", "os": ["win32"], "cpu": ["arm64"] }, - "@esbuild/win32-ia32@0.25.2": { - "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", + "@esbuild/win32-ia32@0.25.3": { + "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==", "os": ["win32"], "cpu": ["ia32"] }, - "@esbuild/win32-x64@0.25.2": { - "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", + "@esbuild/win32-x64@0.25.3": { + "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==", "os": ["win32"], "cpu": ["x64"] }, - "@floating-ui/core@1.6.9": { - "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "@floating-ui/core@1.7.0": { + "integrity": "sha512-FRdBLykrPPA6P76GGGqlex/e7fbe0F1ykgxHYNXQsH/iTEtjMj/f9bpY5oQqbjt5VgZvgz/uKXbGuROijh3VLA==", "dependencies": [ "@floating-ui/utils" ] }, - "@floating-ui/dom@1.6.13": { - "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "@floating-ui/dom@1.7.0": { + "integrity": "sha512-lGTor4VlXcesUMh1cupTUTDoCxMb0V6bm3CnxHzQcw8Eaf1jQbgQX4i02fYgT0vJ82tb5MZ4CZk1LRGkktJCzg==", "dependencies": [ "@floating-ui/core", "@floating-ui/utils" @@ -1161,8 +1176,8 @@ ], "bin": true }, - "@maplibre/maplibre-gl-style-spec@23.1.0": { - "integrity": "sha512-R6/ihEuC5KRexmKIYkWqUv84Gm+/QwsOUgHyt1yy2XqCdGdLvlBWVWIIeTZWN4NGdwmY6xDzdSGU2R9oBLNg2w==", + "@maplibre/maplibre-gl-style-spec@23.2.2": { + "integrity": "sha512-kLcVlItPCULc20SM6pSVA7u8nST9xmQA8d7utc9j3KB0Tf/xhM4GgCn/QsZcmlbN/wW0ujyomDrvZ3/LbwvAmw==", "dependencies": [ "@mapbox/jsonlint-lines-primitives", "@mapbox/unitbezier", @@ -1174,39 +1189,41 @@ ], "bin": true }, - "@noble/curves@1.8.1": { - "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", + "@napi-rs/wasm-runtime@0.2.9": { + "integrity": "sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg==", "dependencies": [ - "@noble/hashes" + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util" ] }, - "@noble/hashes@1.7.1": { - "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==" + "@noble/curves@1.9.0": { + "integrity": "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==", + "dependencies": [ + "@noble/hashes" + ] }, - "@radix-ui/number@1.1.0": { - "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==" + "@noble/hashes@1.8.0": { + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==" }, "@radix-ui/number@1.1.1": { "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==" }, - "@radix-ui/primitive@1.1.1": { - "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" - }, "@radix-ui/primitive@1.1.2": { "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==" }, - "@radix-ui/react-accordion@1.2.3_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-RIQ15mrcvqIkDARJeERSuXSry2N8uYnxkdDetpfmalT/+0ntOXLkFOsh9iwlAsCv+qcmhZjbdJogIm6WBa6c4A==", + "@radix-ui/react-accordion@1.2.8_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-c7OKBvO36PfQIUGIjj1Wko0hH937pYFU2tR5zbIJDUsmTzHoZVHHt4bmb7OOJbzTaWJtVELKWojBHa7OcnUHmQ==", "dependencies": [ - "@radix-ui/primitive@1.1.1", + "@radix-ui/primitive", "@radix-ui/react-collapsible", - "@radix-ui/react-collection@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-direction@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-collection", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-direction", "@radix-ui/react-id", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-primitive", + "@radix-ui/react-use-controllable-state", "@types/react", "@types/react-dom", "react", @@ -1217,10 +1234,10 @@ "@types/react-dom" ] }, - "@radix-ui/react-arrow@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==", + "@radix-ui/react-arrow@1.1.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-qz+fxrqgNxG0dYew5l7qR3c7wdgRu1XVUHGnGYX7rg5HM4p9SWaRmJwfgR3J0SgyUKayLmzQIun+N6rWRgiRKw==", "dependencies": [ - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@types/react", "@types/react-dom", "react", @@ -1231,17 +1248,17 @@ "@types/react-dom" ] }, - "@radix-ui/react-checkbox@1.1.4_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==", + "@radix-ui/react-checkbox@1.2.3_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-pHVzDYsnaDmBlAuwim45y3soIN8H4R7KbkSVirGhXO+R/kO2OLCe0eucUEbddaTcdMHHdzcIGHtZSMSQlA+apw==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", "@radix-ui/react-presence", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-previous@1.1.0_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-size@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-primitive", + "@radix-ui/react-use-controllable-state", + "@radix-ui/react-use-previous", + "@radix-ui/react-use-size", "@types/react", "@types/react-dom", "react", @@ -1252,34 +1269,17 @@ "@types/react-dom" ] }, - "@radix-ui/react-collapsible@1.1.3_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==", + "@radix-ui/react-collapsible@1.1.8_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-hxEsLvK9WxIAPyxdDRULL4hcaSjMZCfP7fHB0Z1uUnDoDBat1Zh46hwYfa69DeZAbJrPckjf0AGAtEZyvDyJbw==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", "@radix-ui/react-id", "@radix-ui/react-presence", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0", - "@types/react", - "@types/react-dom", - "react", - "react-dom" - ], - "optionalPeers": [ - "@types/react", - "@types/react-dom" - ] - }, - "@radix-ui/react-collection@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==", - "dependencies": [ - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-slot@1.1.2_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-primitive", + "@radix-ui/react-use-controllable-state", + "@radix-ui/react-use-layout-effect", "@types/react", "@types/react-dom", "react", @@ -1290,13 +1290,13 @@ "@types/react-dom" ] }, - "@radix-ui/react-collection@1.1.4_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "@radix-ui/react-collection@1.1.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-cv4vSf7HttqXilDnAnvINd53OTl1/bjUYVZrkFnA7nwmY9Ob2POUy0WY0sfqBAe1s5FyKsyceQlqiEGPYNTadg==", "dependencies": [ - "@radix-ui/react-compose-refs@1.1.2_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.2_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-primitive@2.1.0_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-slot@1.2.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-primitive", + "@radix-ui/react-slot", "@types/react", "@types/react-dom", "react", @@ -1307,17 +1307,7 @@ "@types/react-dom" ] }, - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", - "dependencies": [ - "@types/react", - "react" - ], - "optionalPeers": [ - "@types/react" - ] - }, - "@radix-ui/react-compose-refs@1.1.2_@types+react@19.0.12_react@19.1.0": { + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", "dependencies": [ "@types/react", @@ -1327,17 +1317,7 @@ "@types/react" ] }, - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", - "dependencies": [ - "@types/react", - "react" - ], - "optionalPeers": [ - "@types/react" - ] - }, - "@radix-ui/react-context@1.1.2_@types+react@19.0.12_react@19.1.0": { + "@radix-ui/react-context@1.1.2_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", "dependencies": [ "@types/react", @@ -1347,21 +1327,21 @@ "@types/react" ] }, - "@radix-ui/react-dialog@1.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==", + "@radix-ui/react-dialog@1.1.11_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-yI7S1ipkP5/+99qhSI6nthfo/tR6bL6Zgxi/+1UO6qPa6UeM6nlafWcQ65vB4rU2XjgjMfMhI3k9Y5MztA62VQ==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", "@radix-ui/react-dismissable-layer", "@radix-ui/react-focus-guards", "@radix-ui/react-focus-scope", "@radix-ui/react-id", "@radix-ui/react-portal", "@radix-ui/react-presence", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-slot@1.1.2_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-primitive", + "@radix-ui/react-slot", + "@radix-ui/react-use-controllable-state", "@types/react", "@types/react-dom", "aria-hidden", @@ -1374,17 +1354,7 @@ "@types/react-dom" ] }, - "@radix-ui/react-direction@1.1.0_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", - "dependencies": [ - "@types/react", - "react" - ], - "optionalPeers": [ - "@types/react" - ] - }, - "@radix-ui/react-direction@1.1.1_@types+react@19.0.12_react@19.1.0": { + "@radix-ui/react-direction@1.1.1_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", "dependencies": [ "@types/react", @@ -1394,12 +1364,12 @@ "@types/react" ] }, - "@radix-ui/react-dismissable-layer@1.1.5_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==", + "@radix-ui/react-dismissable-layer@1.1.7_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-j5+WBUdhccJsmH5/H0K6RncjDtoALSEr6jbkaZu+bjw6hOPOhHycr6vEUujl+HBK8kjUfWcoCJXxP6e4lUlMZw==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs", + "@radix-ui/react-primitive", "@radix-ui/react-use-callback-ref", "@radix-ui/react-use-escape-keydown", "@types/react", @@ -1412,16 +1382,16 @@ "@types/react-dom" ] }, - "@radix-ui/react-dropdown-menu@2.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==", + "@radix-ui/react-dropdown-menu@2.1.12_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-VJoMs+BWWE7YhzEQyVwvF9n22Eiyr83HotCVrMQzla/OwRovXCgah7AcaEr4hMNj4gJxSdtIbcHGvmJXOoJVHA==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", "@radix-ui/react-id", "@radix-ui/react-menu", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-primitive", + "@radix-ui/react-use-controllable-state", "@types/react", "@types/react-dom", "react", @@ -1432,8 +1402,8 @@ "@types/react-dom" ] }, - "@radix-ui/react-focus-guards@1.1.1_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", + "@radix-ui/react-focus-guards@1.1.2_@types+react@19.1.2_react@19.1.0": { + "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", "dependencies": [ "@types/react", "react" @@ -1442,11 +1412,11 @@ "@types/react" ] }, - "@radix-ui/react-focus-scope@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==", + "@radix-ui/react-focus-scope@1.1.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-r2annK27lIW5w9Ho5NyQgqs0MmgZSTIKXWpVCJaLC1q2kZrZkcqnmHkCHMEmv8XLvsLlurKMPT+kbKkRkm/xVA==", "dependencies": [ - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-compose-refs", + "@radix-ui/react-primitive", "@radix-ui/react-use-callback-ref", "@types/react", "@types/react-dom", @@ -1458,10 +1428,10 @@ "@types/react-dom" ] }, - "@radix-ui/react-id@1.1.0_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "@radix-ui/react-id@1.1.1_@types+react@19.1.2_react@19.1.0": { + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", "dependencies": [ - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-layout-effect", "@types/react", "react" ], @@ -1469,10 +1439,10 @@ "@types/react" ] }, - "@radix-ui/react-label@2.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==", + "@radix-ui/react-label@2.1.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-wy3dqizZnZVV4ja0FNnUhIWNwWdoldXrneEyUcVtLYDAt8ovGS4ridtMAOGgXBBIfggL4BOveVWsjXDORdGEQg==", "dependencies": [ - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@types/react", "@types/react-dom", "react", @@ -1483,14 +1453,14 @@ "@types/react-dom" ] }, - "@radix-ui/react-menu@2.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==", + "@radix-ui/react-menu@2.1.12_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-+qYq6LfbiGo97Zz9fioX83HCiIYYFNs8zAsVCMQrIakoNYylIzWuoD/anAD3UzvvR6cnswmfRFJFq/zYYq/k7Q==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-collection@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-direction@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-collection", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-direction", "@radix-ui/react-dismissable-layer", "@radix-ui/react-focus-guards", "@radix-ui/react-focus-scope", @@ -1498,9 +1468,9 @@ "@radix-ui/react-popper", "@radix-ui/react-portal", "@radix-ui/react-presence", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@radix-ui/react-roving-focus", - "@radix-ui/react-slot@1.1.2_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-slot", "@radix-ui/react-use-callback-ref", "@types/react", "@types/react-dom", @@ -1514,19 +1484,19 @@ "@types/react-dom" ] }, - "@radix-ui/react-menubar@1.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-FHq7+3DlXwh/7FOM4i0G4bC4vPjiq89VEEvNF4VMLchGnaUuUbE5uKXMUCjdKaOghEEMeiKa5XCa2Pk4kteWmg==", + "@radix-ui/react-menubar@1.1.12_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-bM2vT5nxRqJH/d1vFQ9jLsW4qR70yFQw2ZD1TUPWUNskDsV0eYeMbbNJqxNjGMOVogEkOJaHtu11kzYdTJvVJg==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-collection@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-direction@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-collection", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-direction", "@radix-ui/react-id", "@radix-ui/react-menu", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@radix-ui/react-roving-focus", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-controllable-state", "@types/react", "@types/react-dom", "react", @@ -1537,12 +1507,12 @@ "@types/react-dom" ] }, - "@radix-ui/react-popover@1.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==", + "@radix-ui/react-popover@1.1.11_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-yFMfZkVA5G3GJnBgb2PxrrcLKm1ZLWXrbYVgdyTl//0TYEIHS9LJbnyz7WWcZ0qCq7hIlJZpRtxeSeIG5T5oJw==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", "@radix-ui/react-dismissable-layer", "@radix-ui/react-focus-guards", "@radix-ui/react-focus-scope", @@ -1550,9 +1520,9 @@ "@radix-ui/react-popper", "@radix-ui/react-portal", "@radix-ui/react-presence", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-slot@1.1.2_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-primitive", + "@radix-ui/react-slot", + "@radix-ui/react-use-controllable-state", "@types/react", "@types/react-dom", "aria-hidden", @@ -1565,18 +1535,18 @@ "@types/react-dom" ] }, - "@radix-ui/react-popper@1.2.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==", + "@radix-ui/react-popper@1.2.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-3p2Rgm/a1cK0r/UVkx5F/K9v/EplfjAeIFCGOPYPO4lZ0jtg4iSQXt/YGTSLWaf4x7NG6Z4+uKFcylcTZjeqDA==", "dependencies": [ "@floating-ui/react-dom", "@radix-ui/react-arrow", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-primitive", "@radix-ui/react-use-callback-ref", - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-layout-effect", "@radix-ui/react-use-rect", - "@radix-ui/react-use-size@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-size", "@radix-ui/rect", "@types/react", "@types/react-dom", @@ -1588,26 +1558,11 @@ "@types/react-dom" ] }, - "@radix-ui/react-portal@1.1.4_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==", - "dependencies": [ - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0", - "@types/react", - "@types/react-dom", - "react", - "react-dom" - ], - "optionalPeers": [ - "@types/react", - "@types/react-dom" - ] - }, - "@radix-ui/react-presence@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "@radix-ui/react-portal@1.1.6_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-XmsIl2z1n/TsYFLIdYam2rmFwf9OC/Sh2avkbmVMDuBZIe7hSpM0cYnWPAo7nHOVx8zTuwDZGByfcqLdnzp3Vw==", "dependencies": [ - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-primitive", + "@radix-ui/react-use-layout-effect", "@types/react", "@types/react-dom", "react", @@ -1618,10 +1573,11 @@ "@types/react-dom" ] }, - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==", + "@radix-ui/react-presence@1.1.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", "dependencies": [ - "@radix-ui/react-slot@1.1.2_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-compose-refs", + "@radix-ui/react-use-layout-effect", "@types/react", "@types/react-dom", "react", @@ -1632,10 +1588,10 @@ "@types/react-dom" ] }, - "@radix-ui/react-primitive@2.1.0_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "@radix-ui/react-primitive@2.1.0_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw==", "dependencies": [ - "@radix-ui/react-slot@1.2.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-slot", "@types/react", "@types/react-dom", "react", @@ -1646,18 +1602,18 @@ "@types/react-dom" ] }, - "@radix-ui/react-roving-focus@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==", + "@radix-ui/react-roving-focus@1.1.7_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-C6oAg451/fQT3EGbWHbCQjYTtbyjNO1uzQgMzwyivcHT3GKNEmu1q3UuREhN+HzHAVtv3ivMVK08QlC+PkYw9Q==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-collection@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-direction@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-collection", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-direction", "@radix-ui/react-id", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@radix-ui/react-use-callback-ref", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-controllable-state", "@types/react", "@types/react-dom", "react", @@ -1668,18 +1624,18 @@ "@types/react-dom" ] }, - "@radix-ui/react-scroll-area@1.2.3_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ==", + "@radix-ui/react-scroll-area@1.2.6_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-lj8OMlpPERXrQIHlEQdlXHJoRT52AMpBrgyPYylOhXYq5e/glsEdtOc/kCQlsTdtgN5U0iDbrrolDadvektJGQ==", "dependencies": [ - "@radix-ui/number@1.1.0", - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-direction@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/number", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-direction", "@radix-ui/react-presence", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@radix-ui/react-use-callback-ref", - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-layout-effect", "@types/react", "@types/react-dom", "react", @@ -1690,27 +1646,27 @@ "@types/react-dom" ] }, - "@radix-ui/react-select@2.1.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==", + "@radix-ui/react-select@2.2.2_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-HjkVHtBkuq+r3zUAZ/CvNWUGKPfuicGDbgtZgiQuFmNcV5F+Tgy24ep2nsAW2nFgvhGPJVqeBZa6KyVN0EyrBA==", "dependencies": [ - "@radix-ui/number@1.1.0", - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-collection@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-direction@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/number", + "@radix-ui/primitive", + "@radix-ui/react-collection", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-direction", "@radix-ui/react-dismissable-layer", "@radix-ui/react-focus-guards", "@radix-ui/react-focus-scope", "@radix-ui/react-id", "@radix-ui/react-popper", "@radix-ui/react-portal", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-slot@1.1.2_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-primitive", + "@radix-ui/react-slot", "@radix-ui/react-use-callback-ref", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-previous@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-controllable-state", + "@radix-ui/react-use-layout-effect", + "@radix-ui/react-use-previous", "@radix-ui/react-visually-hidden", "@types/react", "@types/react-dom", @@ -1724,10 +1680,10 @@ "@types/react-dom" ] }, - "@radix-ui/react-separator@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==", + "@radix-ui/react-separator@1.1.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-2fTm6PSiUm8YPq9W0E4reYuv01EE3aFSzt8edBiXqPHshF8N9+Kymt/k0/R+F3dkY5lQyB/zPtrP82phskLi7w==", "dependencies": [ - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@types/react", "@types/react-dom", "react", @@ -1738,20 +1694,20 @@ "@types/react-dom" ] }, - "@radix-ui/react-slider@1.3.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "@radix-ui/react-slider@1.3.2_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-oQnqfgSiYkxZ1MrF6672jw2/zZvpB+PJsrIc3Zm1zof1JHf/kj7WhmROw7JahLfOwYQ5/+Ip0rFORgF1tjSiaQ==", "dependencies": [ - "@radix-ui/number@1.1.1", - "@radix-ui/primitive@1.1.2", - "@radix-ui/react-collection@1.1.4_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-compose-refs@1.1.2_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.2_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-direction@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-primitive@2.1.0_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-previous@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-size@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/number", + "@radix-ui/primitive", + "@radix-ui/react-collection", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-direction", + "@radix-ui/react-primitive", + "@radix-ui/react-use-controllable-state", + "@radix-ui/react-use-layout-effect", + "@radix-ui/react-use-previous", + "@radix-ui/react-use-size", "@types/react", "@types/react-dom", "react", @@ -1762,21 +1718,10 @@ "@types/react-dom" ] }, - "@radix-ui/react-slot@1.1.2_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==", - "dependencies": [ - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@types/react", - "react" - ], - "optionalPeers": [ - "@types/react" - ] - }, - "@radix-ui/react-slot@1.2.0_@types+react@19.0.12_react@19.1.0": { + "@radix-ui/react-slot@1.2.0_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", "dependencies": [ - "@radix-ui/react-compose-refs@1.1.2_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-compose-refs", "@types/react", "react" ], @@ -1784,16 +1729,16 @@ "@types/react" ] }, - "@radix-ui/react-switch@1.1.3_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-1nc+vjEOQkJVsJtWPSiISGT6OKm4SiOdjMo+/icLxo2G4vxz1GntC5MzfL4v8ey9OEfw787QCD1y3mUv0NiFEQ==", + "@radix-ui/react-switch@1.2.2_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-7Z8n6L+ifMIIYZ83f28qWSceUpkXuslI2FJ34+kDMTiyj91ENdpdQ7VCidrzj5JfwfZTeano/BnGBbu/jqa5rQ==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-previous@1.1.0_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-size@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", + "@radix-ui/react-primitive", + "@radix-ui/react-use-controllable-state", + "@radix-ui/react-use-previous", + "@radix-ui/react-use-size", "@types/react", "@types/react-dom", "react", @@ -1804,17 +1749,17 @@ "@types/react-dom" ] }, - "@radix-ui/react-tabs@1.1.3_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==", + "@radix-ui/react-tabs@1.1.9_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-KIjtwciYvquiW/wAFkELZCVnaNLBsYNhTNcvl+zfMAbMhRkcvNuCLXDDd22L0j7tagpzVh/QwbFpwAATg7ILPw==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-direction@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-context", + "@radix-ui/react-direction", "@radix-ui/react-id", "@radix-ui/react-presence", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@radix-ui/react-roving-focus", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-controllable-state", "@types/react", "@types/react-dom", "react", @@ -1825,20 +1770,20 @@ "@types/react-dom" ] }, - "@radix-ui/react-toast@1.2.6_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-gN4dpuIVKEgpLn1z5FhzT9mYRUitbfZq9XqN/7kkBMUgFTzTG8x/KszWJugJXHcwxckY8xcKDZPz7kG3o6DsUA==", + "@radix-ui/react-toast@1.2.11_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-Ed2mlOmT+tktOsu2NZBK1bCSHh/uqULu1vWOkpQTVq53EoOuZUZw7FInQoDB3uil5wZc2oe0XN9a7uVZB7/6AQ==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-collection@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-collection", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", "@radix-ui/react-dismissable-layer", "@radix-ui/react-portal", "@radix-ui/react-presence", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@radix-ui/react-use-callback-ref", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-controllable-state", + "@radix-ui/react-use-layout-effect", "@radix-ui/react-visually-hidden", "@types/react", "@types/react-dom", @@ -1850,20 +1795,20 @@ "@types/react-dom" ] }, - "@radix-ui/react-tooltip@1.1.8_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==", + "@radix-ui/react-tooltip@1.2.4_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-DyW8VVeeMSSLFvAmnVnCwvI3H+1tpJFHT50r+tdOoMse9XqYDBCcyux8u3G2y+LOpt7fPQ6KKH0mhs+ce1+Z5w==", "dependencies": [ - "@radix-ui/primitive@1.1.1", - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-context@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs", + "@radix-ui/react-context", "@radix-ui/react-dismissable-layer", "@radix-ui/react-id", "@radix-ui/react-popper", "@radix-ui/react-portal", "@radix-ui/react-presence", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "@radix-ui/react-slot@1.1.2_@types+react@19.0.12_react@19.1.0", - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-primitive", + "@radix-ui/react-slot", + "@radix-ui/react-use-controllable-state", "@radix-ui/react-visually-hidden", "@types/react", "@types/react-dom", @@ -1875,8 +1820,8 @@ "@types/react-dom" ] }, - "@radix-ui/react-use-callback-ref@1.1.0_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.2_react@19.1.0": { + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", "dependencies": [ "@types/react", "react" @@ -1885,22 +1830,11 @@ "@types/react" ] }, - "@radix-ui/react-use-controllable-state@1.1.0_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", - "dependencies": [ - "@radix-ui/react-use-callback-ref", - "@types/react", - "react" - ], - "optionalPeers": [ - "@types/react" - ] - }, - "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.0.12_react@19.1.0": { + "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", "dependencies": [ "@radix-ui/react-use-effect-event", - "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-layout-effect", "@types/react", "react" ], @@ -1908,10 +1842,10 @@ "@types/react" ] }, - "@radix-ui/react-use-effect-event@0.0.2_@types+react@19.0.12_react@19.1.0": { + "@radix-ui/react-use-effect-event@0.0.2_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", "dependencies": [ - "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-layout-effect", "@types/react", "react" ], @@ -1919,8 +1853,8 @@ "@types/react" ] }, - "@radix-ui/react-use-escape-keydown@1.1.0_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "@radix-ui/react-use-escape-keydown@1.1.1_@types+react@19.1.2_react@19.1.0": { + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", "dependencies": [ "@radix-ui/react-use-callback-ref", "@types/react", @@ -1930,17 +1864,7 @@ "@types/react" ] }, - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", - "dependencies": [ - "@types/react", - "react" - ], - "optionalPeers": [ - "@types/react" - ] - }, - "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.0.12_react@19.1.0": { + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", "dependencies": [ "@types/react", @@ -1950,17 +1874,7 @@ "@types/react" ] }, - "@radix-ui/react-use-previous@1.1.0_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", - "dependencies": [ - "@types/react", - "react" - ], - "optionalPeers": [ - "@types/react" - ] - }, - "@radix-ui/react-use-previous@1.1.1_@types+react@19.0.12_react@19.1.0": { + "@radix-ui/react-use-previous@1.1.1_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", "dependencies": [ "@types/react", @@ -1970,8 +1884,8 @@ "@types/react" ] }, - "@radix-ui/react-use-rect@1.1.0_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "@radix-ui/react-use-rect@1.1.1_@types+react@19.1.2_react@19.1.0": { + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", "dependencies": [ "@radix-ui/rect", "@types/react", @@ -1981,21 +1895,10 @@ "@types/react" ] }, - "@radix-ui/react-use-size@1.1.0_@types+react@19.0.12_react@19.1.0": { - "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", - "dependencies": [ - "@radix-ui/react-use-layout-effect@1.1.0_@types+react@19.0.12_react@19.1.0", - "@types/react", - "react" - ], - "optionalPeers": [ - "@types/react" - ] - }, - "@radix-ui/react-use-size@1.1.1_@types+react@19.0.12_react@19.1.0": { + "@radix-ui/react-use-size@1.1.1_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", "dependencies": [ - "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-use-layout-effect", "@types/react", "react" ], @@ -2003,10 +1906,10 @@ "@types/react" ] }, - "@radix-ui/react-visually-hidden@1.1.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==", + "@radix-ui/react-visually-hidden@1.2.0_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-rQj0aAWOpCdCMRbI6pLQm8r7S2BM3YhTa0SzOYD55k+hJA8oo9J+H+9wLM9oMlZWOX/wJWPTzfDfmZkf7LvCfg==", "dependencies": [ - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "@types/react", "@types/react-dom", "react", @@ -2017,10 +1920,10 @@ "@types/react-dom" ] }, - "@radix-ui/rect@1.1.0": { - "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" + "@radix-ui/rect@1.1.1": { + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==" }, - "@rollup/plugin-babel@5.3.1_@babel+core@7.26.10_rollup@2.79.2": { + "@rollup/plugin-babel@5.3.1_@babel+core@7.27.1_rollup@2.79.2": { "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", "dependencies": [ "@babel/core", @@ -2080,17 +1983,6 @@ "rollup@2.79.2" ] }, - "@rollup/pluginutils@5.1.4": { - "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", - "dependencies": [ - "@types/estree@1.0.7", - "estree-walker@2.0.2", - "picomatch@4.0.2" - ], - "optionalPeers": [ - "rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0" - ] - }, "@rollup/pluginutils@5.1.4_rollup@2.79.2": { "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", "dependencies": [ @@ -2103,103 +1995,103 @@ "rollup@2.79.2" ] }, - "@rollup/rollup-android-arm-eabi@4.38.0": { - "integrity": "sha512-ldomqc4/jDZu/xpYU+aRxo3V4mGCV9HeTgUBANI3oIQMOL+SsxB+S2lxMpkFp5UamSS3XuTMQVbsS24R4J4Qjg==", + "@rollup/rollup-android-arm-eabi@4.40.1": { + "integrity": "sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw==", "os": ["android"], "cpu": ["arm"] }, - "@rollup/rollup-android-arm64@4.38.0": { - "integrity": "sha512-VUsgcy4GhhT7rokwzYQP+aV9XnSLkkhlEJ0St8pbasuWO/vwphhZQxYEKUP3ayeCYLhk6gEtacRpYP/cj3GjyQ==", + "@rollup/rollup-android-arm64@4.40.1": { + "integrity": "sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==", "os": ["android"], "cpu": ["arm64"] }, - "@rollup/rollup-darwin-arm64@4.38.0": { - "integrity": "sha512-buA17AYXlW9Rn091sWMq1xGUvWQFOH4N1rqUxGJtEQzhChxWjldGCCup7r/wUnaI6Au8sKXpoh0xg58a7cgcpg==", + "@rollup/rollup-darwin-arm64@4.40.1": { + "integrity": "sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==", "os": ["darwin"], "cpu": ["arm64"] }, - "@rollup/rollup-darwin-x64@4.38.0": { - "integrity": "sha512-Mgcmc78AjunP1SKXl624vVBOF2bzwNWFPMP4fpOu05vS0amnLcX8gHIge7q/lDAHy3T2HeR0TqrriZDQS2Woeg==", + "@rollup/rollup-darwin-x64@4.40.1": { + "integrity": "sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==", "os": ["darwin"], "cpu": ["x64"] }, - "@rollup/rollup-freebsd-arm64@4.38.0": { - "integrity": "sha512-zzJACgjLbQTsscxWqvrEQAEh28hqhebpRz5q/uUd1T7VTwUNZ4VIXQt5hE7ncs0GrF+s7d3S4on4TiXUY8KoQA==", + "@rollup/rollup-freebsd-arm64@4.40.1": { + "integrity": "sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==", "os": ["freebsd"], "cpu": ["arm64"] }, - "@rollup/rollup-freebsd-x64@4.38.0": { - "integrity": "sha512-hCY/KAeYMCyDpEE4pTETam0XZS4/5GXzlLgpi5f0IaPExw9kuB+PDTOTLuPtM10TlRG0U9OSmXJ+Wq9J39LvAg==", + "@rollup/rollup-freebsd-x64@4.40.1": { + "integrity": "sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==", "os": ["freebsd"], "cpu": ["x64"] }, - "@rollup/rollup-linux-arm-gnueabihf@4.38.0": { - "integrity": "sha512-mimPH43mHl4JdOTD7bUMFhBdrg6f9HzMTOEnzRmXbOZqjijCw8LA5z8uL6LCjxSa67H2xiLFvvO67PT05PRKGg==", + "@rollup/rollup-linux-arm-gnueabihf@4.40.1": { + "integrity": "sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==", "os": ["linux"], "cpu": ["arm"] }, - "@rollup/rollup-linux-arm-musleabihf@4.38.0": { - "integrity": "sha512-tPiJtiOoNuIH8XGG8sWoMMkAMm98PUwlriOFCCbZGc9WCax+GLeVRhmaxjJtz6WxrPKACgrwoZ5ia/uapq3ZVg==", + "@rollup/rollup-linux-arm-musleabihf@4.40.1": { + "integrity": "sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==", "os": ["linux"], "cpu": ["arm"] }, - "@rollup/rollup-linux-arm64-gnu@4.38.0": { - "integrity": "sha512-wZco59rIVuB0tjQS0CSHTTUcEde+pXQWugZVxWaQFdQQ1VYub/sTrNdY76D1MKdN2NB48JDuGABP6o6fqos8mA==", + "@rollup/rollup-linux-arm64-gnu@4.40.1": { + "integrity": "sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==", "os": ["linux"], "cpu": ["arm64"] }, - "@rollup/rollup-linux-arm64-musl@4.38.0": { - "integrity": "sha512-fQgqwKmW0REM4LomQ+87PP8w8xvU9LZfeLBKybeli+0yHT7VKILINzFEuggvnV9M3x1Ed4gUBmGUzCo/ikmFbQ==", + "@rollup/rollup-linux-arm64-musl@4.40.1": { + "integrity": "sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==", "os": ["linux"], "cpu": ["arm64"] }, - "@rollup/rollup-linux-loongarch64-gnu@4.38.0": { - "integrity": "sha512-hz5oqQLXTB3SbXpfkKHKXLdIp02/w3M+ajp8p4yWOWwQRtHWiEOCKtc9U+YXahrwdk+3qHdFMDWR5k+4dIlddg==", + "@rollup/rollup-linux-loongarch64-gnu@4.40.1": { + "integrity": "sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==", "os": ["linux"], "cpu": ["loong64"] }, - "@rollup/rollup-linux-powerpc64le-gnu@4.38.0": { - "integrity": "sha512-NXqygK/dTSibQ+0pzxsL3r4Xl8oPqVoWbZV9niqOnIHV/J92fe65pOir0xjkUZDRSPyFRvu+4YOpJF9BZHQImw==", + "@rollup/rollup-linux-powerpc64le-gnu@4.40.1": { + "integrity": "sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==", "os": ["linux"], "cpu": ["ppc64"] }, - "@rollup/rollup-linux-riscv64-gnu@4.38.0": { - "integrity": "sha512-GEAIabR1uFyvf/jW/5jfu8gjM06/4kZ1W+j1nWTSSB3w6moZEBm7iBtzwQ3a1Pxos2F7Gz+58aVEnZHU295QTg==", + "@rollup/rollup-linux-riscv64-gnu@4.40.1": { + "integrity": "sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==", "os": ["linux"], "cpu": ["riscv64"] }, - "@rollup/rollup-linux-riscv64-musl@4.38.0": { - "integrity": "sha512-9EYTX+Gus2EGPbfs+fh7l95wVADtSQyYw4DfSBcYdUEAmP2lqSZY0Y17yX/3m5VKGGJ4UmIH5LHLkMJft3bYoA==", + "@rollup/rollup-linux-riscv64-musl@4.40.1": { + "integrity": "sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==", "os": ["linux"], "cpu": ["riscv64"] }, - "@rollup/rollup-linux-s390x-gnu@4.38.0": { - "integrity": "sha512-Mpp6+Z5VhB9VDk7RwZXoG2qMdERm3Jw07RNlXHE0bOnEeX+l7Fy4bg+NxfyN15ruuY3/7Vrbpm75J9QHFqj5+Q==", + "@rollup/rollup-linux-s390x-gnu@4.40.1": { + "integrity": "sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==", "os": ["linux"], "cpu": ["s390x"] }, - "@rollup/rollup-linux-x64-gnu@4.38.0": { - "integrity": "sha512-vPvNgFlZRAgO7rwncMeE0+8c4Hmc+qixnp00/Uv3ht2x7KYrJ6ERVd3/R0nUtlE6/hu7/HiiNHJ/rP6knRFt1w==", + "@rollup/rollup-linux-x64-gnu@4.40.1": { + "integrity": "sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==", "os": ["linux"], "cpu": ["x64"] }, - "@rollup/rollup-linux-x64-musl@4.38.0": { - "integrity": "sha512-q5Zv+goWvQUGCaL7fU8NuTw8aydIL/C9abAVGCzRReuj5h30TPx4LumBtAidrVOtXnlB+RZkBtExMsfqkMfb8g==", + "@rollup/rollup-linux-x64-musl@4.40.1": { + "integrity": "sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==", "os": ["linux"], "cpu": ["x64"] }, - "@rollup/rollup-win32-arm64-msvc@4.38.0": { - "integrity": "sha512-u/Jbm1BU89Vftqyqbmxdq14nBaQjQX1HhmsdBWqSdGClNaKwhjsg5TpW+5Ibs1mb8Es9wJiMdl86BcmtUVXNZg==", + "@rollup/rollup-win32-arm64-msvc@4.40.1": { + "integrity": "sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==", "os": ["win32"], "cpu": ["arm64"] }, - "@rollup/rollup-win32-ia32-msvc@4.38.0": { - "integrity": "sha512-mqu4PzTrlpNHHbu5qleGvXJoGgHpChBlrBx/mEhTPpnAL1ZAYFlvHD7rLK839LLKQzqEQMFJfGrrOHItN4ZQqA==", + "@rollup/rollup-win32-ia32-msvc@4.40.1": { + "integrity": "sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==", "os": ["win32"], "cpu": ["ia32"] }, - "@rollup/rollup-win32-x64-msvc@4.38.0": { - "integrity": "sha512-jjqy3uWlecfB98Psxb5cD6Fny9Fupv9LrDSPTQZUROqjvZmcCqNu4UMl7qqhlUUGpwiAkotj6GYu4SZdcr/nLw==", + "@rollup/rollup-win32-x64-msvc@4.40.1": { + "integrity": "sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==", "os": ["win32"], "cpu": ["x64"] }, @@ -2212,8 +2104,8 @@ "string.prototype.matchall" ] }, - "@tailwindcss/node@4.1.0": { - "integrity": "sha512-mfgxGxFaxbsUbaGwKIAQXUSm7Qoojw53FftpoKwo4ANwr9wnDaByz4vi1gMti/xfJvmQ5lzA1DvPiX5yCHtBkQ==", + "@tailwindcss/node@4.1.5": { + "integrity": "sha512-CBhSWo0vLnWhXIvpD0qsPephiaUYfHUX3U9anwDaHZAeuGpTiB3XmsxPAN6qX7bFhipyGBqOa1QYQVVhkOUGxg==", "dependencies": [ "enhanced-resolve", "jiti", @@ -2221,63 +2113,75 @@ "tailwindcss" ] }, - "@tailwindcss/oxide-android-arm64@4.1.0": { - "integrity": "sha512-UredFljuHey2Kh5qyYfQVBr0Xfq70ZE5Df6i5IubNYQGs2JXXT4VL0SIUjwzHx5W9T6t7dT7banunlV6lthGPQ==", + "@tailwindcss/oxide-android-arm64@4.1.5": { + "integrity": "sha512-LVvM0GirXHED02j7hSECm8l9GGJ1RfgpWCW+DRn5TvSaxVsv28gRtoL4aWKGnXqwvI3zu1GABeDNDVZeDPOQrw==", "os": ["android"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-darwin-arm64@4.1.0": { - "integrity": "sha512-QHQ/46lRVwH9zEBNiRk8AJ3Af4pMq6DuZAI//q323qrPOXjsRdrhLsH9LUO3mqBfHr5EZNUxN3Am5vpO89sntw==", + "@tailwindcss/oxide-darwin-arm64@4.1.5": { + "integrity": "sha512-//TfCA3pNrgnw4rRJOqavW7XUk8gsg9ddi8cwcsWXp99tzdBAZW0WXrD8wDyNbqjW316Pk2hiN/NJx/KWHl8oA==", "os": ["darwin"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-darwin-x64@4.1.0": { - "integrity": "sha512-lEMgYHCvQQ6x2KOZ4FwnPprwfnc+UnjzwXRqEYIhB/NlYvXQD1QMf7oKEDRqy94DiZaYox9ZRfG2YJOBgM0UkA==", + "@tailwindcss/oxide-darwin-x64@4.1.5": { + "integrity": "sha512-XQorp3Q6/WzRd9OalgHgaqgEbjP3qjHrlSUb5k1EuS1Z9NE9+BbzSORraO+ecW432cbCN7RVGGL/lSnHxcd+7Q==", "os": ["darwin"], "cpu": ["x64"] }, - "@tailwindcss/oxide-freebsd-x64@4.1.0": { - "integrity": "sha512-9fdImTc+2lA5yHqJ61oeTXfCtzylNOzJVFhyWwVQAJESJJbVCPnj6f+b+Zf/AYAdKQfS6FCThbPEahkQrDCgLQ==", + "@tailwindcss/oxide-freebsd-x64@4.1.5": { + "integrity": "sha512-bPrLWbxo8gAo97ZmrCbOdtlz/Dkuy8NK97aFbVpkJ2nJ2Jo/rsCbu0TlGx8joCuA3q6vMWTSn01JY46iwG+clg==", "os": ["freebsd"], "cpu": ["x64"] }, - "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.0": { - "integrity": "sha512-HB0bTkUOuTLLSdadyRhKE9yps4/ZBjrojbHTPMSvvf/8yBLZRPpWb+A6IgW5R+2A2AL4KhVPgLwWfoXsErxJFg==", + "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.5": { + "integrity": "sha512-1gtQJY9JzMAhgAfvd/ZaVOjh/Ju/nCoAsvOVJenWZfs05wb8zq+GOTnZALWGqKIYEtyNpCzvMk+ocGpxwdvaVg==", "os": ["linux"], "cpu": ["arm"] }, - "@tailwindcss/oxide-linux-arm64-gnu@4.1.0": { - "integrity": "sha512-+QtYCwvKLjC46h6RikKkpELJWrpiMMtgyK0aaqhwPLEx1icGgIhwz8dqrkAiqbFRE0KiRrE2aenhYoEkplyRmA==", + "@tailwindcss/oxide-linux-arm64-gnu@4.1.5": { + "integrity": "sha512-dtlaHU2v7MtdxBXoqhxwsWjav7oim7Whc6S9wq/i/uUMTWAzq/gijq1InSgn2yTnh43kR+SFvcSyEF0GCNu1PQ==", "os": ["linux"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-linux-arm64-musl@4.1.0": { - "integrity": "sha512-nApadFKM9GauzuPZPlt6TKfELavMHqJ0gVd+GYkYBTwr2t9KhgCAb2sKiFDDIhs1a7gOjsU7P1lEauv3iKFp+Q==", + "@tailwindcss/oxide-linux-arm64-musl@4.1.5": { + "integrity": "sha512-fg0F6nAeYcJ3CriqDT1iVrqALMwD37+sLzXs8Rjy8Z1ZHshJoYceodfyUwGJEsQoTyWbliFNRs2wMQNXtT7MVA==", "os": ["linux"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-linux-x64-gnu@4.1.0": { - "integrity": "sha512-cp0Rf9Wit2kZHhrV8HIoDFD8dxU2+ZTCFCFbDj3a07pGyyPwLCJm5H5VipKXgYrBaLmlYu73ERidW0S5sdEXEg==", + "@tailwindcss/oxide-linux-x64-gnu@4.1.5": { + "integrity": "sha512-SO+F2YEIAHa1AITwc8oPwMOWhgorPzzcbhWEb+4oLi953h45FklDmM8dPSZ7hNHpIk9p/SCZKUYn35t5fjGtHA==", "os": ["linux"], "cpu": ["x64"] }, - "@tailwindcss/oxide-linux-x64-musl@4.1.0": { - "integrity": "sha512-4/wf42XWBJGXsOS6BhgPhdQbg/qyfdZ1nZvTL9sJoxYN+Ah+cfY5Dd7R0smzI8hmgCRt3TD1lYb72ChTyIA59w==", + "@tailwindcss/oxide-linux-x64-musl@4.1.5": { + "integrity": "sha512-6UbBBplywkk/R+PqqioskUeXfKcBht3KU7juTi1UszJLx0KPXUo10v2Ok04iBJIaDPkIFkUOVboXms5Yxvaz+g==", "os": ["linux"], "cpu": ["x64"] }, - "@tailwindcss/oxide-win32-arm64-msvc@4.1.0": { - "integrity": "sha512-caXJJ0G6NwGbcoxEYdH3MZYN84C3PldaMdAEPMU6bjJXURQlKdSlQ/Ecis7/nSgBkMkicZyhqWmb36Tw/BFSIw==", + "@tailwindcss/oxide-wasm32-wasi@4.1.5": { + "integrity": "sha512-hwALf2K9FHuiXTPqmo1KeOb83fTRNbe9r/Ixv9ZNQ/R24yw8Ge1HOWDDgTdtzntIaIUJG5dfXCf4g9AD4RiyhQ==", + "dependencies": [ + "@emnapi/core", + "@emnapi/runtime", + "@emnapi/wasi-threads", + "@napi-rs/wasm-runtime", + "@tybys/wasm-util", + "tslib@2.8.1" + ], + "cpu": ["wasm32"] + }, + "@tailwindcss/oxide-win32-arm64-msvc@4.1.5": { + "integrity": "sha512-oDKncffWzaovJbkuR7/OTNFRJQVdiw/n8HnzaCItrNQUeQgjy7oUiYpsm9HUBgpmvmDpSSbGaCa2Evzvk3eFmA==", "os": ["win32"], "cpu": ["arm64"] }, - "@tailwindcss/oxide-win32-x64-msvc@4.1.0": { - "integrity": "sha512-ZHXRXRxB7HBmkUE8U13nmkGGYfR1I2vsuhiYjeDDUFIYpk1BL6caU8hvzkSlL/X5CAQNdIUUJRGom5I0ZyfJOA==", + "@tailwindcss/oxide-win32-x64-msvc@4.1.5": { + "integrity": "sha512-WiR4dtyrFdbb+ov0LK+7XsFOsG+0xs0PKZKkt41KDn9jYpO7baE3bXiudPVkTqUEwNfiglCygQHl2jklvSBi7Q==", "os": ["win32"], "cpu": ["x64"] }, - "@tailwindcss/oxide@4.1.0": { - "integrity": "sha512-A33oyZKpPFH08d7xkl13Dc8OTsbPhsuls0z9gUCxIHvn8c1BsUACddQxL6HwaeJR1fSYyXZUw8bdWcD8bVawpQ==", + "@tailwindcss/oxide@4.1.5": { + "integrity": "sha512-1n4br1znquEvyW/QuqMKQZlBen+jxAbvyduU87RS8R3tUSvByAkcaMTkJepNIrTlYhD+U25K4iiCIxE6BGdRYA==", "optionalDependencies": [ "@tailwindcss/oxide-android-arm64", "@tailwindcss/oxide-darwin-arm64", @@ -2288,12 +2192,13 @@ "@tailwindcss/oxide-linux-arm64-musl", "@tailwindcss/oxide-linux-x64-gnu", "@tailwindcss/oxide-linux-x64-musl", + "@tailwindcss/oxide-wasm32-wasi", "@tailwindcss/oxide-win32-arm64-msvc", "@tailwindcss/oxide-win32-x64-msvc" ] }, - "@tailwindcss/postcss@4.1.0": { - "integrity": "sha512-b2NWFAFfLXY7960jLY5QkKbuYKrQUULx60XU3BCzyaUQpU/7lLf3n2CiHibZPdBq5CIXrUp10wdxhV0EI0Js2g==", + "@tailwindcss/postcss@4.1.5": { + "integrity": "sha512-5lAC2/pzuyfhsFgk6I58HcNy6vPK3dV/PoPxSDuOTVbDvCddYHzHiJZZInGIY0venvzzfrTEUAXJFULAfFmObg==", "dependencies": [ "@alloc/quick-lru", "@tailwindcss/node", @@ -2327,8 +2232,8 @@ "redent" ] }, - "@testing-library/react@16.2.0_@testing-library+dom@10.4.0_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-2cSskAvA1QNtKc8Y9VJQRv0tm3hLVgxRGDB+KYhIaPQJ1I+RHbhIXcM+zClKXzMes/wshsMVzf4B9vS4IZpqDQ==", + "@testing-library/react@16.3.0_@testing-library+dom@10.4.0_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==", "dependencies": [ "@babel/runtime", "@testing-library/dom", @@ -3688,6 +3593,12 @@ "tslib@2.8.1" ] }, + "@tybys/wasm-util@0.9.0": { + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dependencies": [ + "tslib@2.8.1" + ] + }, "@types/aria-query@5.0.4": { "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==" }, @@ -3701,8 +3612,8 @@ "@types/babel__traverse" ] }, - "@types/babel__generator@7.6.8": { - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "@types/babel__generator@7.27.0": { + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dependencies": [ "@babel/types" ] @@ -3720,8 +3631,8 @@ "@babel/types" ] }, - "@types/chrome@0.0.313": { - "integrity": "sha512-9R5T7gTaYZhkxlu+Ho4wk9FL+y/werWQY2yjGWSqCuiTsqS7nL/BE5UMTP6rU7J+oIG2FRKqrEycHhJATeltVA==", + "@types/chrome@0.0.318": { + "integrity": "sha512-rrtyYQ1t+g7EyG0FejE+UXQBjSGUHGh0RIdXwUT/laPo9T724NOIgXA94ns6ewmNauwijYa5ck3+dBxWnHcynQ==", "dependencies": [ "@types/filesystem", "@types/har-format" @@ -3771,8 +3682,8 @@ "@types/pbf" ] }, - "@types/node@22.13.17": { - "integrity": "sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g==", + "@types/node@22.15.3": { + "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", "dependencies": [ "undici-types" ] @@ -3780,14 +3691,14 @@ "@types/pbf@3.0.5": { "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==" }, - "@types/react-dom@19.0.4_@types+react@19.0.12": { - "integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==", + "@types/react-dom@19.1.3_@types+react@19.1.2": { + "integrity": "sha512-rJXC08OG0h3W6wDMFxQrZF00Kq6qQvw0djHRdzl3U5DnIERz0MRce3WVc7IS6JYBwtaP/DwYtRRjVlvivNveKg==", "dependencies": [ "@types/react" ] }, - "@types/react@19.0.12": { - "integrity": "sha512-V6Ar115dBDrjbtXSrS+/Oruobc+qVbbUxDFC1RSbRqLt5SYvxxyIDrSC85RWml54g+jfNeEMZhEj7wW07ONQhA==", + "@types/react@19.1.2": { + "integrity": "sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==", "dependencies": [ "csstype" ] @@ -3795,8 +3706,8 @@ "@types/resolve@1.20.2": { "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" }, - "@types/serviceworker@0.0.127": { - "integrity": "sha512-jj6drAuP9/KzIeuLKQyIFnmWF4cZMr3phuej3zfsilo7bwaAmDOq2L7Ns/3IjoLVRWpW5q0UBdpiyZAP8CQPzw==" + "@types/serviceworker@0.0.133": { + "integrity": "sha512-lEyAbLUMztFbps2GVZ5mKIXl5+BZiGfOOA8JxN6KTiT91Ct31lSAHISKUl2+iOwmrUwNvWeI9rbsFxFqDZCghQ==" }, "@types/supercluster@7.1.3": { "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", @@ -3807,8 +3718,8 @@ "@types/trusted-types@2.0.7": { "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" }, - "@types/validator@13.12.3": { - "integrity": "sha512-2ipwZ2NydGQJImne+FhNdhgRM37e9lCev99KnqkbFHd94Xn/mErARWI1RSLem1QA19ch5kOhzIZd7e8CA2FI8g==" + "@types/validator@13.15.0": { + "integrity": "sha512-nh7nrWhLr6CBq9ldtw0wx+z9wKnnv/uTVLA9g/3/TcOYxbpOSZE+MhKPmWqU+K0NvThjhv12uD8MuqijB0WzEA==" }, "@types/w3c-web-serial@1.0.8": { "integrity": "sha512-QQOT+bxQJhRGXoZDZGLs3ksLud1dMNnMiSQtBA0w8KXvLpXX4oM4TZb6J0GgJ8UbCaHo5s9/4VQT8uXy9JER2A==" @@ -3816,15 +3727,15 @@ "@types/web-bluetooth@0.0.21": { "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==" }, - "@vis.gl/react-mapbox@8.0.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-6WS+VOPzcgG0+Rsz5sPPyUwg/oNtbvV0nWnCaSm7tHGnylK8aDhZwXJnEjDeGlo/sh1h/PbCCgzUBBRt7u7rsg==", + "@vis.gl/react-mapbox@8.0.4_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-NFk0vsWcNzSs0YCsVdt2100Zli9QWR+pje8DacpLkkGEAXFaJsFtI1oKD0Hatiate4/iAIW39SQHhgfhbeEPfQ==", "dependencies": [ "react", "react-dom" ] }, - "@vis.gl/react-maplibre@8.0.2_maplibre-gl@5.3.0_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-2Vbkp0D6S1z97GadNyVRErslgr7IdI8ZmFpGsJz8x2TRpNTYUyHXHHeC5hzyLWHHz6KQhuUD/EQuJoy6GQ5TOQ==", + "@vis.gl/react-maplibre@8.0.4_maplibre-gl@5.4.0_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-HwZyfLjEu+y1mUFvwDAkVxinGm8fEegaWN+O8np/WZ2Sqe5Lv6OXFpV6GWz9LOEvBYMbGuGk1FQdejo+4HCJ5w==", "dependencies": [ "@maplibre/maplibre-gl-style-spec@19.3.3", "maplibre-gl", @@ -3835,8 +3746,8 @@ "maplibre-gl" ] }, - "@vitejs/plugin-react@4.3.4_vite@6.2.4__@types+node@22.13.17_@babel+core@7.26.10_@types+node@22.13.17": { - "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", + "@vitejs/plugin-react@4.4.1_vite@6.3.4__@types+node@22.15.3__picomatch@4.0.2_@babel+core@7.27.1_@types+node@22.15.3": { + "integrity": "sha512-IpEm5ZmeXAP/osiBXVVP5KjFMzbWOonMs0NaQQl+xYnUAcq4oHUBsF2+p4MgKWG4YMmFYJU8A6sxRPuowllm6w==", "dependencies": [ "@babel/core", "@babel/plugin-transform-react-jsx-self", @@ -3846,8 +3757,8 @@ "vite" ] }, - "@vitest/expect@3.1.1": { - "integrity": "sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==", + "@vitest/expect@3.1.2": { + "integrity": "sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==", "dependencies": [ "@vitest/spy", "@vitest/utils", @@ -3855,8 +3766,8 @@ "tinyrainbow" ] }, - "@vitest/mocker@3.1.1_vite@6.2.4__@types+node@22.13.17_@types+node@22.13.17": { - "integrity": "sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==", + "@vitest/mocker@3.1.2_vite@6.3.4__@types+node@22.15.3__picomatch@4.0.2_@types+node@22.15.3": { + "integrity": "sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==", "dependencies": [ "@vitest/spy", "estree-walker@3.0.3", @@ -3867,35 +3778,35 @@ "vite" ] }, - "@vitest/pretty-format@3.1.1": { - "integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==", + "@vitest/pretty-format@3.1.2": { + "integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", "dependencies": [ "tinyrainbow" ] }, - "@vitest/runner@3.1.1": { - "integrity": "sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==", + "@vitest/runner@3.1.2": { + "integrity": "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==", "dependencies": [ "@vitest/utils", "pathe" ] }, - "@vitest/snapshot@3.1.1": { - "integrity": "sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==", + "@vitest/snapshot@3.1.2": { + "integrity": "sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==", "dependencies": [ "@vitest/pretty-format", "magic-string@0.30.17", "pathe" ] }, - "@vitest/spy@3.1.1": { - "integrity": "sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==", + "@vitest/spy@3.1.2": { + "integrity": "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==", "dependencies": [ "tinyspy" ] }, - "@vitest/utils@3.1.1": { - "integrity": "sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==", + "@vitest/utils@3.1.2": { + "integrity": "sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==", "dependencies": [ "@vitest/pretty-format", "loupe", @@ -3967,7 +3878,7 @@ "asn1.js@4.10.1": { "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dependencies": [ - "bn.js@4.12.1", + "bn.js@4.12.2", "inherits", "minimalistic-assert" ] @@ -4016,7 +3927,7 @@ "possible-typed-array-names" ] }, - "babel-plugin-polyfill-corejs2@0.4.13_@babel+core@7.26.10": { + "babel-plugin-polyfill-corejs2@0.4.13_@babel+core@7.27.1": { "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", "dependencies": [ "@babel/compat-data", @@ -4025,7 +3936,7 @@ "semver" ] }, - "babel-plugin-polyfill-corejs3@0.11.1_@babel+core@7.26.10": { + "babel-plugin-polyfill-corejs3@0.11.1_@babel+core@7.27.1": { "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", "dependencies": [ "@babel/core", @@ -4033,7 +3944,7 @@ "core-js-compat" ] }, - "babel-plugin-polyfill-regenerator@0.6.4_@babel+core@7.26.10": { + "babel-plugin-polyfill-regenerator@0.6.4_@babel+core@7.27.1": { "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", "dependencies": [ "@babel/core", @@ -4046,14 +3957,14 @@ "base64-js@1.5.1": { "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, - "bignumber.js@9.1.2": { - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" + "bignumber.js@9.3.0": { + "integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==" }, - "bn.js@4.12.1": { - "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==" + "bn.js@4.12.2": { + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==" }, - "bn.js@5.2.1": { - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + "bn.js@5.2.2": { + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==" }, "brace-expansion@1.1.11": { "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", @@ -4108,7 +4019,7 @@ "browserify-rsa@4.1.1": { "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", "dependencies": [ - "bn.js@5.2.1", + "bn.js@5.2.2", "randombytes", "safe-buffer@5.2.1" ] @@ -4116,7 +4027,7 @@ "browserify-sign@4.2.3": { "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dependencies": [ - "bn.js@5.2.1", + "bn.js@5.2.2", "browserify-rsa", "create-hash", "create-hmac", @@ -4134,8 +4045,8 @@ "pako" ] }, - "browserslist@4.24.4": { - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "browserslist@4.24.5": { + "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", "dependencies": [ "caniuse-lite", "electron-to-chromium", @@ -4199,8 +4110,8 @@ "get-intrinsic" ] }, - "caniuse-lite@1.0.30001707": { - "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==" + "caniuse-lite@1.0.30001716": { + "integrity": "sha512-49/c1+x3Kwz7ZIWt+4DvK3aMJy9oYXXG6/97JKsnjdCk/6n9vVyWL8NAwVt95Lwt9eigI10Hl782kDfZUUlRXw==" }, "chai@5.2.0": { "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", @@ -4239,8 +4150,8 @@ "safe-buffer@5.2.1" ] }, - "class-validator@0.14.1": { - "integrity": "sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==", + "class-validator@0.14.2": { + "integrity": "sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==", "dependencies": [ "@types/validator", "libphonenumber-js", @@ -4256,13 +4167,13 @@ "clsx@2.1.1": { "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" }, - "cmdk@1.1.1_react@19.1.0_react-dom@19.1.0__react@19.1.0_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12": { + "cmdk@1.1.1_react@19.1.0_react-dom@19.1.0__react@19.1.0_@types+react@19.1.2_@types+react-dom@19.1.3__@types+react@19.1.2": { "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", "dependencies": [ - "@radix-ui/react-compose-refs@1.1.1_@types+react@19.0.12_react@19.1.0", + "@radix-ui/react-compose-refs", "@radix-ui/react-dialog", "@radix-ui/react-id", - "@radix-ui/react-primitive@2.0.2_@types+react@19.0.12_@types+react-dom@19.0.4__@types+react@19.0.12_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive", "react", "react-dom" ] @@ -4306,8 +4217,8 @@ "convert-source-map@2.0.0": { "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, - "core-js-compat@3.41.0": { - "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==", + "core-js-compat@3.42.0": { + "integrity": "sha512-bQasjMfyDGyaeWKBIu33lHh9qlSR0MFE/Nmc6nMjf/iU9b3rSMdAYz1Baxrv4lPdGUsTqZudHA4jIGSJy0SWZQ==", "dependencies": [ "browserslist" ] @@ -4321,7 +4232,7 @@ "create-ecdh@4.0.4": { "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dependencies": [ - "bn.js@4.12.1", + "bn.js@4.12.2", "elliptic" ] }, @@ -4455,8 +4366,8 @@ "minimalistic-assert" ] }, - "detect-libc@2.0.3": { - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==" + "detect-libc@2.0.4": { + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==" }, "detect-node-es@1.1.0": { "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" @@ -4464,7 +4375,7 @@ "diffie-hellman@5.0.3": { "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dependencies": [ - "bn.js@4.12.1", + "bn.js@4.12.2", "miller-rabin", "randombytes" ] @@ -4511,13 +4422,13 @@ ], "bin": true }, - "electron-to-chromium@1.5.129": { - "integrity": "sha512-JlXUemX4s0+9f8mLqib/bHH8gOHf5elKS6KeWG3sk3xozb/JTq/RLXIv8OKUWiK4Ah00Wm88EFj5PYkFr4RUPA==" + "electron-to-chromium@1.5.149": { + "integrity": "sha512-UyiO82eb9dVOx8YO3ajDf9jz2kKyt98DEITRdeLPstOEuTlLzDA4Gyq5K9he71TQziU5jUVu2OAu5N48HmQiyQ==" }, "elliptic@6.6.1": { "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "dependencies": [ - "bn.js@4.12.1", + "bn.js@4.12.2", "brorand", "hash.js", "hmac-drbg", @@ -4601,8 +4512,8 @@ "es-errors@1.3.0": { "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" }, - "es-module-lexer@1.6.0": { - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==" + "es-module-lexer@1.7.0": { + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==" }, "es-object-atoms@1.1.1": { "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", @@ -4627,8 +4538,8 @@ "is-symbol" ] }, - "esbuild@0.25.2": { - "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", + "esbuild@0.25.3": { + "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==", "optionalDependencies": [ "@esbuild/aix-ppc64", "@esbuild/android-arm", @@ -4712,8 +4623,8 @@ "fast-uri@3.0.6": { "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==" }, - "fdir@6.4.3_picomatch@4.0.2": { - "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "fdir@6.4.4_picomatch@4.0.2": { + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", "dependencies": [ "picomatch@4.0.2" ], @@ -4885,8 +4796,8 @@ ], "bin": true }, - "happy-dom@17.4.4": { - "integrity": "sha512-/Pb0ctk3HTZ5xEL3BZ0hK1AqDSAUuRQitOmROPHhfUYEWpmTImwfD8vFDGADmMAX0JYgbcgxWoLFKtsWhcpuVA==", + "happy-dom@17.4.6": { + "integrity": "sha512-OEV1hDe9i2rFr66+WZNiwy1S8rAJy6bRXmXql68YJDjdfHBRbN76om+qVh68vQACf6y5Bcr90e/oK53RQxsDdg==", "dependencies": [ "webidl-conversions@7.0.0", "whatwg-mimetype" @@ -5249,8 +5160,8 @@ "leven@3.1.0": { "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" }, - "libphonenumber-js@1.12.6": { - "integrity": "sha512-PJiS4ETaUfCOFLpmtKzAbqZQjCCKVu2OhTV4SVNNE7c2nu/dACvtCqj4L0i/KWNnIgRv7yrILvBj5Lonv5Ncxw==" + "libphonenumber-js@1.12.7": { + "integrity": "sha512-0nYZSNj/QEikyhcM5RZFXGlCB/mr4PVamnT1C2sKBnDDTYndrvbybYjvg+PMqAndQHlLbwQ3socolnL3WWTUFA==" }, "lightningcss-darwin-arm64@1.29.2": { "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==", @@ -5348,8 +5259,8 @@ "yallist@3.1.1" ] }, - "lucide-react@0.486.0_react@19.1.0": { - "integrity": "sha512-xWop/wMsC1ikiEVLZrxXjPKw4vU/eAip33G2mZHgbWnr4Nr5Rt4Vx4s/q1D3B/rQVbxjOuqASkEZcUxDEKzecw==", + "lucide-react@0.507.0_react@19.1.0": { + "integrity": "sha512-XfgE6gvAHwAtnbUvWiTTHx4S3VGR+cUJHEc0vrh9Ogu672I1Tue2+Cp/8JJqpytgcBHAB1FVI297W4XGNwc2dQ==", "dependencies": [ "react" ] @@ -5370,8 +5281,8 @@ "@jridgewell/sourcemap-codec" ] }, - "maplibre-gl@5.3.0": { - "integrity": "sha512-qru6B6jHlDPR4Q9/P4W1zEPbPofR4wwYbrrjiHKWI7yLtyXmpJ1/G1KaIYDr5uNdFbPZ7uiZAWdqtfdNLmIhGg==", + "maplibre-gl@5.4.0": { + "integrity": "sha512-ZVrtdFIhFAqt53H2k5Ssqn7QIKNI19fW+He5tr4loxZxWZffp1aZYY9ImNncAJaALU/NYlV6Eul7UVB56/N7WQ==", "dependencies": [ "@mapbox/geojson-rewind", "@mapbox/jsonlint-lines-primitives", @@ -5380,7 +5291,7 @@ "@mapbox/unitbezier", "@mapbox/vector-tile", "@mapbox/whoots-js", - "@maplibre/maplibre-gl-style-spec@23.1.0", + "@maplibre/maplibre-gl-style-spec@23.2.2", "@types/geojson", "@types/geojson-vt", "@types/mapbox__point-geometry", @@ -5418,7 +5329,7 @@ "miller-rabin@4.0.1": { "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dependencies": [ - "bn.js@4.12.1", + "bn.js@4.12.2", "brorand" ], "bin": true @@ -5699,7 +5610,7 @@ "public-encrypt@4.0.3": { "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dependencies": [ - "bn.js@4.12.1", + "bn.js@4.12.2", "browserify-rsa", "create-hash", "parse-asn1", @@ -5766,15 +5677,15 @@ "scheduler" ] }, - "react-error-boundary@5.0.0_react@19.1.0": { - "integrity": "sha512-tnjAxG+IkpLephNcePNA7v6F/QpWLH8He65+DmedchDwg162JZqx4NmbXj0mlAYVVEd81OW7aFhmbsScYfiAFQ==", + "react-error-boundary@6.0.0_react@19.1.0": { + "integrity": "sha512-gdlJjD7NWr0IfkPlaREN2d9uUZUlksrfOx7SX62VRerwXbMY6ftGCIZua1VG1aXFNOimhISsTq+Owp725b9SiA==", "dependencies": [ "@babel/runtime", "react" ] }, - "react-hook-form@7.55.0_react@19.1.0": { - "integrity": "sha512-XRnjsH3GVMQz1moZTW53MxfoWN7aDpUg/GpVNc4A3eXRVNdGXfbzJ4vM4aLQ8g6XCUh1nIbx70aaNCl7kxnjog==", + "react-hook-form@7.56.2_react@19.1.0": { + "integrity": "sha512-vpfuHuQMF/L6GpuQ4c3ZDo+pRYxIi40gQqsCmmfUBwm+oqvBhKhwghCuj2o00YCgSfU6bR9KC/xnQGWm3Gr08A==", "dependencies": [ "react" ] @@ -5782,8 +5693,8 @@ "react-is@17.0.2": { "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, - "react-map-gl@8.0.2_maplibre-gl@5.3.0_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-290CDxlvb9Fgbzvg2DgoMlAa5YjdHRZkJ9V0kAnxcD+F1fmYVegQDMevLJu5bcTZ0WKOzli3Os+rNtecLuNu7A==", + "react-map-gl@8.0.4_maplibre-gl@5.4.0_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-SHdpvFIvswsZBg6BCPcwY/nbKuCo3sJM1Cj7Sd+gA3gFRFOixD+KtZ2XSuUWq2WySL2emYEXEgrLZoXsV4Ut4Q==", "dependencies": [ "@vis.gl/react-mapbox", "@vis.gl/react-maplibre", @@ -5804,10 +5715,10 @@ "react-dom" ] }, - "react-refresh@0.14.2": { - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==" + "react-refresh@0.17.0": { + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==" }, - "react-remove-scroll-bar@2.3.8_@types+react@19.0.12_react@19.1.0": { + "react-remove-scroll-bar@2.3.8_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", "dependencies": [ "@types/react", @@ -5819,7 +5730,7 @@ "@types/react" ] }, - "react-remove-scroll@2.6.3_@types+react@19.0.12_react@19.1.0": { + "react-remove-scroll@2.6.3_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", "dependencies": [ "@types/react", @@ -5834,7 +5745,7 @@ "@types/react" ] }, - "react-style-singleton@2.2.3_@types+react@19.0.12_react@19.1.0": { + "react-style-singleton@2.2.3_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", "dependencies": [ "@types/react", @@ -5898,15 +5809,6 @@ "regenerate@1.4.2": { "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, - "regenerator-runtime@0.14.1": { - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "regenerator-transform@0.15.2": { - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dependencies": [ - "@babel/runtime" - ] - }, "regexp.prototype.flags@1.5.4": { "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dependencies": [ @@ -5980,8 +5882,8 @@ ], "bin": true }, - "rollup@4.38.0": { - "integrity": "sha512-5SsIRtJy9bf1ErAOiFMFzl64Ex9X5V7bnJ+WlFMb+zmP459OSWCEG7b0ERZ+PEU7xPt4OG3RHbrp1LJlXxYTrw==", + "rollup@4.40.1": { + "integrity": "sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==", "dependencies": [ "@types/estree@1.0.7" ], @@ -6150,8 +6052,8 @@ "siginfo@2.0.0": { "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==" }, - "simple-git-hooks@2.12.1": { - "integrity": "sha512-NB3V4XyCOrWTIhjh85DyEoVlM3adHWwqQXKYHmuegy/108bJPP6YxuPGm4ZKBq1+GVKRbKJuzNY//09cMJYp+A==", + "simple-git-hooks@2.13.0": { + "integrity": "sha512-N+goiLxlkHJlyaYEglFypzVNMaNplPAk5syu0+OPp/Bk6dwVoXF6FfOw2vO0Dp+JHsBaI+w6cm8TnFl2Hw6tDA==", "scripts": true, "bin": true }, @@ -6222,8 +6124,8 @@ "stackback@0.0.2": { "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==" }, - "std-env@3.8.1": { - "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==" + "std-env@3.9.0": { + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==" }, "ste-core@3.0.11": { "integrity": "sha512-ivkRENMh0mdGoPlZ4xVcEaC8rXQfTEfvonRw5m8VDKV7kgcbZbaNd1TnKl08wXbcLdT7okSc63HNP8cVhy95zg==" @@ -6350,17 +6252,17 @@ "tinyqueue@2.0.3" ] }, - "tailwind-merge@3.1.0": { - "integrity": "sha512-aV27Oj8B7U/tAOMhJsSGdWqelfmudnGMdXIlMnk1JfsjwSjts6o8HyfN7SFH3EztzH4YH8kk6GbLTHzITJO39Q==" + "tailwind-merge@3.2.0": { + "integrity": "sha512-FQT/OVqCD+7edmmJpsgCsY820RTD5AkBryuG5IUqR5YQZSdj5xlH5nLgH7YPths7WsLPSpSBNneJdM8aS8aeFA==" }, - "tailwindcss-animate@1.0.7_tailwindcss@4.1.0": { + "tailwindcss-animate@1.0.7_tailwindcss@4.1.5": { "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", "dependencies": [ "tailwindcss" ] }, - "tailwindcss@4.1.0": { - "integrity": "sha512-vBYstoFnvUZCDxaauNGQQEvJNQgCd1vSMDRYuZZMH1xRRcTboOk1rJrW5yFkEabU9X6Yx1C4LQ+QvPOvQj4Daw==" + "tailwindcss@4.1.5": { + "integrity": "sha512-nYtSPfWGDiWgCkwQG/m+aX83XCwf62sBgg3bIlNiiOcggnS1x3uVRDAuyelBFL+vJdOPPCGElxv9DjHJjRHiVA==" }, "tapable@2.2.1": { "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" @@ -6431,8 +6333,8 @@ "tinyexec@0.3.2": { "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==" }, - "tinyglobby@0.2.12_picomatch@4.0.2": { - "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "tinyglobby@0.2.13_picomatch@4.0.2": { + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", "dependencies": [ "fdir", "picomatch@4.0.2" @@ -6532,8 +6434,8 @@ "reflect.getprototypeof" ] }, - "typescript@5.8.2": { - "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "typescript@5.8.3": { + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "bin": true }, "typewise-core@1.2.0": { @@ -6554,8 +6456,8 @@ "which-boxed-primitive" ] }, - "undici-types@6.20.0": { - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + "undici-types@6.21.0": { + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" }, "unicode-canonical-property-names-ecmascript@2.0.1": { "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==" @@ -6594,7 +6496,7 @@ "upath@1.2.0": { "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" }, - "update-browserslist-db@1.1.3_browserslist@4.24.4": { + "update-browserslist-db@1.1.3_browserslist@4.24.5": { "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dependencies": [ "browserslist", @@ -6610,7 +6512,7 @@ "qs" ] }, - "use-callback-ref@1.3.3_@types+react@19.0.12_react@19.1.0": { + "use-callback-ref@1.3.3_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", "dependencies": [ "@types/react", @@ -6621,7 +6523,7 @@ "@types/react" ] }, - "use-sidecar@1.1.3_@types+react@19.0.12_react@19.1.0": { + "use-sidecar@1.1.3_@types+react@19.1.2_react@19.1.0": { "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", "dependencies": [ "@types/react", @@ -6649,8 +6551,8 @@ "validator@13.15.0": { "integrity": "sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==" }, - "vite-node@3.1.1_@types+node@22.13.17": { - "integrity": "sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==", + "vite-node@3.1.2_@types+node@22.15.3": { + "integrity": "sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA==", "dependencies": [ "cac", "debug", @@ -6660,7 +6562,7 @@ ], "bin": true }, - "vite-plugin-node-polyfills@0.23.0_vite@6.2.4__@types+node@22.13.17_@types+node@22.13.17": { + "vite-plugin-node-polyfills@0.23.0_vite@6.3.4__@types+node@22.15.3__picomatch@4.0.2_@types+node@22.15.3": { "integrity": "sha512-4n+Ys+2bKHQohPBKigFlndwWQ5fFKwaGY6muNDMTb0fSQLyBzS+jjUNRZG9sKF0S/Go4ApG6LFnUGopjkILg3w==", "dependencies": [ "@rollup/plugin-inject", @@ -6668,7 +6570,7 @@ "vite" ] }, - "vite-plugin-pwa@1.0.0_vite@6.2.4__@types+node@22.13.17_workbox-build@7.3.0__ajv@8.17.1__@babel+core@7.26.10__rollup@2.79.2_workbox-window@7.3.0_@types+node@22.13.17": { + "vite-plugin-pwa@1.0.0_vite@6.3.4__@types+node@22.15.3__picomatch@4.0.2_workbox-build@7.3.0__ajv@8.17.1__@babel+core@7.27.1__rollup@2.79.2_workbox-window@7.3.0_@types+node@22.15.3": { "integrity": "sha512-X77jo0AOd5OcxmWj3WnVti8n7Kw2tBgV1c8MCXFclrSlDV23ePzv2eTDIALXI2Qo6nJ5pZJeZAuX0AawvRfoeA==", "dependencies": [ "debug", @@ -6679,13 +6581,16 @@ "workbox-window" ] }, - "vite@6.2.4_@types+node@22.13.17": { - "integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==", + "vite@6.3.4_@types+node@22.15.3_picomatch@4.0.2": { + "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==", "dependencies": [ "@types/node", "esbuild", + "fdir", + "picomatch@4.0.2", "postcss", - "rollup@4.38.0" + "rollup@4.40.1", + "tinyglobby" ], "optionalDependencies": [ "fsevents" @@ -6695,8 +6600,8 @@ ], "bin": true }, - "vitest@3.1.1_@types+node@22.13.17_happy-dom@17.4.4_vite@6.2.4__@types+node@22.13.17": { - "integrity": "sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==", + "vitest@3.1.2_@types+node@22.15.3_happy-dom@17.4.6_vite@6.3.4__@types+node@22.15.3__picomatch@4.0.2": { + "integrity": "sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ==", "dependencies": [ "@types/node", "@vitest/expect", @@ -6715,6 +6620,7 @@ "std-env", "tinybench", "tinyexec", + "tinyglobby", "tinypool", "tinyrainbow", "vite", @@ -6832,7 +6738,7 @@ "workbox-core" ] }, - "workbox-build@7.3.0_ajv@8.17.1_@babel+core@7.26.10_rollup@2.79.2": { + "workbox-build@7.3.0_ajv@8.17.1_@babel+core@7.27.1_rollup@2.79.2": { "integrity": "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ==", "dependencies": [ "@apideck/better-ajv-errors", @@ -6974,14 +6880,14 @@ "yocto-queue@0.1.0": { "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" }, - "zod@3.24.2": { - "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==" + "zod@3.24.3": { + "integrity": "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==" }, "zone.js@0.8.29": { "integrity": "sha512-mla2acNCMkWXBD+c+yeUrBUrzOxYMNFdQ6FGfigGGtEVBPJx07BQeJekjt9DmH1FtZek4E9rE1eRR9qQpxACOQ==" }, - "zustand@5.0.3_@types+react@19.0.12_immer@10.1.1_react@19.1.0": { - "integrity": "sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==", + "zustand@5.0.4_@types+react@19.1.2_immer@10.1.1_react@19.1.0": { + "integrity": "sha512-39VFTN5InDtMd28ZhjLyuTnlytDr9HfwO512Ai4I8ZABCoyAj4F1+sr7sD1jP/+p7k77Iko0Pb5NhgBFDCX0kQ==", "dependencies": [ "@types/react", "immer", @@ -7003,71 +6909,71 @@ "npm:@jsr/meshtastic__transport-http@*", "npm:@jsr/meshtastic__transport-web-bluetooth@*", "npm:@jsr/meshtastic__transport-web-serial@*", - "npm:@noble/curves@^1.8.1", - "npm:@radix-ui/react-accordion@^1.2.3", - "npm:@radix-ui/react-checkbox@^1.1.4", - "npm:@radix-ui/react-dialog@^1.1.6", - "npm:@radix-ui/react-dropdown-menu@^2.1.6", - "npm:@radix-ui/react-label@^2.1.2", - "npm:@radix-ui/react-menubar@^1.1.6", - "npm:@radix-ui/react-popover@^1.1.6", - "npm:@radix-ui/react-scroll-area@^1.2.3", - "npm:@radix-ui/react-select@^2.1.6", - "npm:@radix-ui/react-separator@^1.1.2", + "npm:@noble/curves@^1.9.0", + "npm:@radix-ui/react-accordion@^1.2.8", + "npm:@radix-ui/react-checkbox@^1.2.3", + "npm:@radix-ui/react-dialog@^1.1.11", + "npm:@radix-ui/react-dropdown-menu@^2.1.12", + "npm:@radix-ui/react-label@^2.1.4", + "npm:@radix-ui/react-menubar@^1.1.12", + "npm:@radix-ui/react-popover@^1.1.11", + "npm:@radix-ui/react-scroll-area@^1.2.6", + "npm:@radix-ui/react-select@^2.2.2", + "npm:@radix-ui/react-separator@^1.1.4", "npm:@radix-ui/react-slider@^1.3.2", - "npm:@radix-ui/react-switch@^1.1.3", - "npm:@radix-ui/react-tabs@^1.1.3", - "npm:@radix-ui/react-toast@^1.2.6", - "npm:@radix-ui/react-tooltip@^1.1.8", - "npm:@tailwindcss/postcss@^4.1.0", + "npm:@radix-ui/react-switch@^1.2.2", + "npm:@radix-ui/react-tabs@^1.1.9", + "npm:@radix-ui/react-toast@^1.2.11", + "npm:@radix-ui/react-tooltip@^1.2.4", + "npm:@tailwindcss/postcss@^4.1.5", "npm:@testing-library/jest-dom@^6.6.3", - "npm:@testing-library/react@^16.2.0", + "npm:@testing-library/react@^16.3.0", "npm:@testing-library/user-event@^14.6.1", "npm:@turf/turf@^7.2.0", - "npm:@types/chrome@^0.0.313", + "npm:@types/chrome@^0.0.318", "npm:@types/js-cookie@^3.0.6", - "npm:@types/node@^22.13.17", - "npm:@types/react-dom@^19.0.4", - "npm:@types/react@^19.0.12", - "npm:@types/serviceworker@^0.0.127", + "npm:@types/node@^22.15.3", + "npm:@types/react-dom@^19.1.3", + "npm:@types/react@^19.1.2", + "npm:@types/serviceworker@^0.0.133", "npm:@types/w3c-web-serial@^1.0.8", "npm:@types/web-bluetooth@^0.0.21", - "npm:@vitejs/plugin-react@^4.3.4", + "npm:@vitejs/plugin-react@^4.4.1", "npm:autoprefixer@^10.4.21", "npm:base64-js@^1.5.1", - "npm:class-validator@~0.14.1", + "npm:class-validator@~0.14.2", "npm:class-variance-authority@~0.7.1", "npm:clsx@^2.1.1", "npm:cmdk@^1.1.1", "npm:crypto-random-string@5", "npm:gzipper@^8.2.1", - "npm:happy-dom@^17.4.4", + "npm:happy-dom@^17.4.6", "npm:idb-keyval@^6.2.1", "npm:immer@^10.1.1", "npm:js-cookie@^3.0.5", - "npm:lucide-react@0.486", - "npm:maplibre-gl@5.3.0", + "npm:lucide-react@0.507", + "npm:maplibre-gl@5.4.0", "npm:postcss@^8.5.3", "npm:react-dom@^19.1.0", - "npm:react-error-boundary@5", - "npm:react-hook-form@^7.55.0", - "npm:react-map-gl@8.0.2", + "npm:react-error-boundary@6", + "npm:react-hook-form@^7.56.2", + "npm:react-map-gl@8.0.4", "npm:react-qrcode-logo@3", "npm:react@^19.1.0", "npm:rfc4648@^1.5.4", - "npm:simple-git-hooks@^2.12.1", - "npm:tailwind-merge@^3.1.0", + "npm:simple-git-hooks@^2.13.0", + "npm:tailwind-merge@^3.2.0", "npm:tailwindcss-animate@^1.0.7", - "npm:tailwindcss@^4.1.0", + "npm:tailwindcss@^4.1.5", "npm:tar@^7.4.3", "npm:testing-library@^0.0.2", - "npm:typescript@^5.8.2", + "npm:typescript@^5.8.3", "npm:vite-plugin-node-polyfills@0.23", "npm:vite-plugin-pwa@1", - "npm:vite@^6.2.4", - "npm:vitest@^3.1.1", - "npm:zod@^3.24.2", - "npm:zustand@5.0.3" + "npm:vite@^6.3.4", + "npm:vitest@^3.1.2", + "npm:zod@^3.24.3", + "npm:zustand@5.0.4" ] } } diff --git a/package.json b/package.json index a8f7b756..09aa80c6 100644 --- a/package.json +++ b/package.json @@ -40,25 +40,25 @@ "@meshtastic/transport-web-bluetooth": "npm:@jsr/meshtastic__transport-web-bluetooth", "@meshtastic/transport-web-serial": "npm:@jsr/meshtastic__transport-web-serial", "@bufbuild/protobuf": "^2.2.5", - "@noble/curves": "^1.8.1", - "@radix-ui/react-accordion": "^1.2.3", - "@radix-ui/react-checkbox": "^1.1.4", - "@radix-ui/react-dialog": "^1.1.6", - "@radix-ui/react-dropdown-menu": "^2.1.6", - "@radix-ui/react-label": "^2.1.2", - "@radix-ui/react-menubar": "^1.1.6", - "@radix-ui/react-popover": "^1.1.6", - "@radix-ui/react-scroll-area": "^1.2.3", - "@radix-ui/react-select": "^2.1.6", - "@radix-ui/react-separator": "^1.1.2", + "@noble/curves": "^1.9.0", + "@radix-ui/react-accordion": "^1.2.8", + "@radix-ui/react-checkbox": "^1.2.3", + "@radix-ui/react-dialog": "^1.1.11", + "@radix-ui/react-dropdown-menu": "^2.1.12", + "@radix-ui/react-label": "^2.1.4", + "@radix-ui/react-menubar": "^1.1.12", + "@radix-ui/react-popover": "^1.1.11", + "@radix-ui/react-scroll-area": "^1.2.6", + "@radix-ui/react-select": "^2.2.2", + "@radix-ui/react-separator": "^1.1.4", "@radix-ui/react-slider": "^1.3.2", - "@radix-ui/react-switch": "^1.1.3", - "@radix-ui/react-tabs": "^1.1.3", - "@radix-ui/react-toast": "^1.2.6", - "@radix-ui/react-tooltip": "^1.1.8", + "@radix-ui/react-switch": "^1.2.2", + "@radix-ui/react-tabs": "^1.1.9", + "@radix-ui/react-toast": "^1.2.11", + "@radix-ui/react-tooltip": "^1.2.4", "@turf/turf": "^7.2.0", "base64-js": "^1.5.1", - "class-validator": "^0.14.1", + "class-validator": "^0.14.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -66,46 +66,46 @@ "idb-keyval": "^6.2.1", "immer": "^10.1.1", "js-cookie": "^3.0.5", - "lucide-react": "^0.486.0", - "maplibre-gl": "5.3.0", + "lucide-react": "^0.507.0", + "maplibre-gl": "5.4.0", "react": "^19.1.0", "react-dom": "^19.1.0", - "react-error-boundary": "^5.0.0", - "react-hook-form": "^7.55.0", - "react-map-gl": "8.0.2", + "react-error-boundary": "^6.0.0", + "react-hook-form": "^7.56.2", + "react-map-gl": "8.0.4", "react-qrcode-logo": "^3.0.0", "rfc4648": "^1.5.4", "vite-plugin-node-polyfills": "^0.23.0", - "zod": "^3.24.2", - "zustand": "5.0.3" + "zod": "^3.24.3", + "zustand": "5.0.4" }, "devDependencies": { - "@tailwindcss/postcss": "^4.1.0", + "@tailwindcss/postcss": "^4.1.5", "@testing-library/jest-dom": "^6.6.3", - "@testing-library/react": "^16.2.0", + "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^14.6.1", - "@types/chrome": "^0.0.313", + "@types/chrome": "^0.0.318", "@types/js-cookie": "^3.0.6", - "@types/node": "^22.13.17", - "@types/react": "^19.0.12", - "@types/react-dom": "^19.0.4", - "@types/serviceworker": "^0.0.127", + "@types/node": "^22.15.3", + "@types/react": "^19.1.2", + "@types/react-dom": "^19.1.3", + "@types/serviceworker": "^0.0.133", "@types/w3c-web-serial": "^1.0.8", "@types/web-bluetooth": "^0.0.21", - "@vitejs/plugin-react": "^4.3.4", + "@vitejs/plugin-react": "^4.4.1", "autoprefixer": "^10.4.21", "gzipper": "^8.2.1", - "happy-dom": "^17.4.4", + "happy-dom": "^17.4.6", "postcss": "^8.5.3", - "simple-git-hooks": "^2.12.1", - "tailwind-merge": "^3.1.0", - "tailwindcss": "^4.1.0", + "simple-git-hooks": "^2.13.0", + "tailwind-merge": "^3.2.0", + "tailwindcss": "^4.1.5", "tailwindcss-animate": "^1.0.7", "tar": "^7.4.3", "testing-library": "^0.0.2", - "typescript": "^5.8.2", - "vite": "^6.2.4", - "vitest": "^3.1.1", + "typescript": "^5.8.3", + "vite": "^6.3.4", + "vitest": "^3.1.2", "vite-plugin-pwa": "^1.0.0" } } diff --git a/src/App.tsx b/src/App.tsx index db735aef..3c29125a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -16,7 +16,6 @@ import { CommandPalette } from "@components/CommandPalette/index.tsx"; import { SidebarProvider } from "@core/stores/sidebarStore.tsx"; import { useTheme } from "@core/hooks/useTheme.ts"; - export const App = (): JSX.Element => { const { getDevice } = useDeviceStore(); const { selectedDevice, setConnectDialogOpen, connectDialogOpen } = @@ -25,7 +24,7 @@ export const App = (): JSX.Element => { const device = getDevice(selectedDevice); // Sets up light/dark mode based on user preferences or system settings - useTheme() + useTheme(); return ( @@ -37,28 +36,33 @@ export const App = (): JSX.Element => { /> -
+
- {device ? ( -
- - - - - - -
- ) : ( - <> - -
- - )} + {device + ? ( +
+ + + + + + +
+ ) + : ( + <> + +
+ + )}
- + ); }; diff --git a/src/__mocks__/components/UI/Button.tsx b/src/__mocks__/components/UI/Button.tsx index 5b12fa35..9fcd10f1 100644 --- a/src/__mocks__/components/UI/Button.tsx +++ b/src/__mocks__/components/UI/Button.tsx @@ -1,13 +1,13 @@ -import { vi } from 'vitest' +import { vi } from "vitest"; -vi.mock('@components/UI/Button.tsx', () => ({ +vi.mock("@components/UI/Button.tsx", () => ({ Button: ({ children, name, disabled, onClick }: { - children: React.ReactNode, - variant: string, - name: string, - disabled?: boolean, - onClick: () => void - }) => + children: React.ReactNode; + variant: string; + name: string; + disabled?: boolean; + onClick: () => void; + }) => ( -})); \ No newline at end of file + ), +})); diff --git a/src/__mocks__/components/UI/Checkbox.tsx b/src/__mocks__/components/UI/Checkbox.tsx index 52215ec9..363c4bb0 100644 --- a/src/__mocks__/components/UI/Checkbox.tsx +++ b/src/__mocks__/components/UI/Checkbox.tsx @@ -1,6 +1,19 @@ -import { vi } from 'vitest' +import { vi } from "vitest"; -vi.mock('@components/UI/Checkbox.tsx', () => ({ - Checkbox: ({ id, checked, onChange }: { id: string, checked: boolean, onChange: () => void }) => - -})); \ No newline at end of file +vi.mock("@components/UI/Checkbox.tsx", () => ({ + Checkbox: ( + { id, checked, onChange }: { + id: string; + checked: boolean; + onChange: () => void; + }, + ) => ( + + ), +})); diff --git a/src/__mocks__/components/UI/Dialog/Dialog.tsx b/src/__mocks__/components/UI/Dialog/Dialog.tsx index 99ad3a0e..958b7b4c 100644 --- a/src/__mocks__/components/UI/Dialog/Dialog.tsx +++ b/src/__mocks__/components/UI/Dialog/Dialog.tsx @@ -1,43 +1,45 @@ -import React from 'react'; +import React from "react"; export const Dialog = ({ children, open }: { - children: React.ReactNode, - open: boolean, - onOpenChange?: (open: boolean) => void + children: React.ReactNode; + open: boolean; + onOpenChange?: (open: boolean) => void; }) => open ?
{children}
: null; export const DialogContent = ({ children, - className + className, }: { - children: React.ReactNode, - className?: string + children: React.ReactNode; + className?: string; }) =>
{children}
; export const DialogHeader = ({ - children + children, }: { - children: React.ReactNode + children: React.ReactNode; }) =>
{children}
; export const DialogTitle = ({ - children + children, }: { - children: React.ReactNode + children: React.ReactNode; }) =>
{children}
; export const DialogDescription = ({ children, - className + className, }: { - children: React.ReactNode, - className?: string -}) =>
{children}
; + children: React.ReactNode; + className?: string; +}) => ( +
{children}
+); export const DialogFooter = ({ children, - className + className, }: { - children: React.ReactNode, - className?: string -}) =>
{children}
; \ No newline at end of file + children: React.ReactNode; + className?: string; +}) =>
{children}
; diff --git a/src/__mocks__/components/UI/Label.tsx b/src/__mocks__/components/UI/Label.tsx index be626fab..f233b844 100644 --- a/src/__mocks__/components/UI/Label.tsx +++ b/src/__mocks__/components/UI/Label.tsx @@ -1,6 +1,15 @@ -import { vi } from 'vitest' +import { vi } from "vitest"; -vi.mock('@components/UI/Label.tsx', () => ({ - Label: ({ children, htmlFor, className }: { children: React.ReactNode, htmlFor: string, className?: string }) => - -})); \ No newline at end of file +vi.mock("@components/UI/Label.tsx", () => ({ + Label: ( + { children, htmlFor, className }: { + children: React.ReactNode; + htmlFor: string; + className?: string; + }, + ) => ( + + ), +})); diff --git a/src/__mocks__/components/UI/Link.tsx b/src/__mocks__/components/UI/Link.tsx index ec607e85..bfbe9352 100644 --- a/src/__mocks__/components/UI/Link.tsx +++ b/src/__mocks__/components/UI/Link.tsx @@ -1,7 +1,11 @@ import { vi } from "vitest"; -vi.mock('@components/UI/Typography/Link.tsx', () => ({ - Link: ({ children, href, className }: { children: React.ReactNode, href: string, className?: string }) => - {children} +vi.mock("@components/UI/Typography/Link.tsx", () => ({ + Link: ( + { children, href, className }: { + children: React.ReactNode; + href: string; + className?: string; + }, + ) => {children}, })); - diff --git a/src/components/BatteryStatus.tsx b/src/components/BatteryStatus.tsx index bd6022c9..c615feff 100644 --- a/src/components/BatteryStatus.tsx +++ b/src/components/BatteryStatus.tsx @@ -1,10 +1,10 @@ -import React from 'react'; +import React from "react"; import { - PlugZapIcon, BatteryFullIcon, - BatteryMediumIcon, BatteryLowIcon, -} from 'lucide-react'; + BatteryMediumIcon, + PlugZapIcon, +} from "lucide-react"; import { Subtle } from "@components/UI/Typography/Subtle.tsx"; interface DeviceMetrics { @@ -25,50 +25,52 @@ interface BatteryStateConfig { const batteryStates: BatteryStateConfig[] = [ { - condition: level => level > 100, + condition: (level) => level > 100, Icon: PlugZapIcon, - className: 'text-gray-500', - text: () => 'Plugged in', + className: "text-gray-500", + text: () => "Plugged in", }, { - condition: level => level > 80, + condition: (level) => level > 80, Icon: BatteryFullIcon, - className: 'text-green-500', - text: level => `${level}% charging`, + className: "text-green-500", + text: (level) => `${level}% charging`, }, { - condition: level => level > 20, + condition: (level) => level > 20, Icon: BatteryMediumIcon, - className: 'text-yellow-500', - text: level => `${level}% charging`, + className: "text-yellow-500", + text: (level) => `${level}% charging`, }, { condition: () => true, Icon: BatteryLowIcon, - className: 'text-red-500', - text: level => `${level}% charging`, + className: "text-red-500", + text: (level) => `${level}% charging`, }, ]; const getBatteryState = (level: number) => { - return batteryStates.find(state => state.condition(level)); + return batteryStates.find((state) => state.condition(level)); }; - const BatteryStatus: React.FC = ({ deviceMetrics }) => { - if (deviceMetrics?.batteryLevel === undefined || deviceMetrics?.batteryLevel === null) { + if ( + deviceMetrics?.batteryLevel === undefined || + deviceMetrics?.batteryLevel === null + ) { return null; } const { batteryLevel, voltage } = deviceMetrics; - const currentState = getBatteryState(batteryLevel) ?? batteryStates[batteryStates.length - 1]; - + const currentState = getBatteryState(batteryLevel) ?? + batteryStates[batteryStates.length - 1]; const BatteryIcon = currentState.Icon; const iconClassName = currentState.className; const statusText = currentState.text(batteryLevel); - const voltageTitle = `${voltage?.toPrecision(3) ?? 'Unknown'} volts`; + const voltageTitle = `${voltage?.toPrecision(3) ?? "Unknown"} volts`; return (
= ({ deviceMetrics }) => { ); }; -export default BatteryStatus; \ No newline at end of file +export default BatteryStatus; diff --git a/src/components/CommandPalette/index.tsx b/src/components/CommandPalette/index.tsx index 11612984..6d366700 100644 --- a/src/components/CommandPalette/index.tsx +++ b/src/components/CommandPalette/index.tsx @@ -17,8 +17,10 @@ import { FactoryIcon, LayersIcon, LinkIcon, + type LucideIcon, MapIcon, MessageSquareIcon, + Pin, PlusIcon, PowerIcon, QrCodeIcon, @@ -27,8 +29,6 @@ import { SmartphoneIcon, TrashIcon, UsersIcon, - Pin, - type LucideIcon, } from "lucide-react"; import { useEffect } from "react"; import { Avatar } from "@components/UI/Avatar.tsx"; @@ -61,7 +61,9 @@ export const CommandPalette = () => { } = useAppStore(); const { getDevices } = useDeviceStore(); const { setDialogOpen, setActivePage, getNode, connection } = useDevice(); - const { pinnedItems, togglePinnedItem } = usePinnedItems({ storageName: 'pinnedCommandMenuGroups' }); + const { pinnedItems, togglePinnedItem } = usePinnedItems({ + storageName: "pinnedCommandMenuGroups", + }); const groups: Group[] = [ { @@ -114,15 +116,12 @@ export const CommandPalette = () => { label: "Switch Node", icon: ArrowLeftRightIcon, subItems: getDevices().map((device) => ({ - label: - getNode(device.hardware.myNodeNum)?.user?.longName ?? + label: getNode(device.hardware.myNodeNum)?.user?.longName ?? device.hardware.myNodeNum.toString(), icon: ( ), action() { @@ -248,7 +247,10 @@ export const CommandPalette = () => { }, [setCommandPaletteOpen]); return ( - + No results found. @@ -262,13 +264,11 @@ export const CommandPalette = () => { type="button" onClick={() => togglePinnedItem(group.label)} className={cn( - "transition-all duration-300 scale-100 cursor-pointer p-2 focus:*:data-label:opacity-100" + "transition-all duration-300 scale-100 cursor-pointer p-2 focus:*:data-label:opacity-100", )} - aria-description={ - pinnedItems.includes(group.label) - ? "Unpin command group" - : "Pin command group" - } + aria-description={pinnedItems.includes(group.label) + ? "Unpin command group" + : "Pin command group"} > { "transition-opacity", pinnedItems.includes(group.label) ? "opacity-100 text-red-500" - : "opacity-40 hover:opacity-70" + : "opacity-40 hover:opacity-70", )} /> diff --git a/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx b/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx index 67873be0..a938c21f 100644 --- a/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx +++ b/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx @@ -1,16 +1,16 @@ -import { render, screen, fireEvent } from '@testing-library/react'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { fireEvent, render, screen } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; // Ensure the path is correct for import import { useMessageStore } from "../../../core/stores/messageStore/index.ts"; import { DeleteMessagesDialog } from "@components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx"; -vi.mock('@core/stores/messageStore', () => ({ +vi.mock("@core/stores/messageStore", () => ({ useMessageStore: vi.fn(() => ({ deleteAllMessages: vi.fn(), })), })); -describe('DeleteMessagesDialog', () => { +describe("DeleteMessagesDialog", () => { const mockOnOpenChange = vi.fn(); const mockClearAllMessages = vi.fn(); @@ -20,50 +20,61 @@ describe('DeleteMessagesDialog', () => { const mockedUseMessageStore = vi.mocked(useMessageStore); mockedUseMessageStore.mockImplementation(() => ({ - deleteAllMessages: mockClearAllMessages + deleteAllMessages: mockClearAllMessages, })); mockedUseMessageStore.mockClear(); - }); - it('calls onOpenChange with false when the close button (X) is clicked', () => { - render(); - const closeButton = screen.queryByTestId('dialog-close-button'); + it("calls onOpenChange with false when the close button (X) is clicked", () => { + render( + , + ); + const closeButton = screen.queryByTestId("dialog-close-button"); if (!closeButton) { - throw new Error("Dialog close button with data-testid='dialog-close-button' not found. Did you add it to the component?"); + throw new Error( + "Dialog close button with data-testid='dialog-close-button' not found. Did you add it to the component?", + ); } fireEvent.click(closeButton); expect(mockOnOpenChange).toHaveBeenCalledTimes(1); expect(mockOnOpenChange).toHaveBeenCalledWith(false); }); - - - it('renders the dialog when open is true', () => { - render(); - expect(screen.getByText('Clear All Messages')).toBeInTheDocument(); - expect(screen.getByText(/This action will clear all message history./)).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'Dismiss' })).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'Clear Messages' })).toBeInTheDocument(); + it("renders the dialog when open is true", () => { + render( + , + ); + expect(screen.getByText("Clear All Messages")).toBeInTheDocument(); + expect(screen.getByText(/This action will clear all message history./)) + .toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Dismiss" })).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Clear Messages" })) + .toBeInTheDocument(); }); - it('does not render the dialog when open is false', () => { - render(); - expect(screen.queryByText('Clear All Messages')).toBeNull(); + it("does not render the dialog when open is false", () => { + render( + , + ); + expect(screen.queryByText("Clear All Messages")).toBeNull(); }); - it('calls onOpenChange with false when the dismiss button is clicked', () => { - render(); - fireEvent.click(screen.getByRole('button', { name: 'Dismiss' })); + it("calls onOpenChange with false when the dismiss button is clicked", () => { + render( + , + ); + fireEvent.click(screen.getByRole("button", { name: "Dismiss" })); expect(mockOnOpenChange).toHaveBeenCalledTimes(1); // Add count check expect(mockOnOpenChange).toHaveBeenCalledWith(false); }); - it('calls deleteAllMessages and onOpenChange with false when the clear messages button is clicked', () => { - render(); - fireEvent.click(screen.getByRole('button', { name: 'Clear Messages' })); + it("calls deleteAllMessages and onOpenChange with false when the clear messages button is clicked", () => { + render( + , + ); + fireEvent.click(screen.getByRole("button", { name: "Clear Messages" })); expect(mockClearAllMessages).toHaveBeenCalledTimes(1); expect(mockOnOpenChange).toHaveBeenCalledTimes(1); // Add count check expect(mockOnOpenChange).toHaveBeenCalledWith(false); }); -}); \ No newline at end of file +}); diff --git a/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx b/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx index 47fe0b92..562a522e 100644 --- a/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx +++ b/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx @@ -1,4 +1,3 @@ - import { Button } from "@components/UI/Button.tsx"; import { Dialog, diff --git a/src/components/Dialog/DeviceNameDialog.tsx b/src/components/Dialog/DeviceNameDialog.tsx index c41c81ba..7fbe310d 100644 --- a/src/components/Dialog/DeviceNameDialog.tsx +++ b/src/components/Dialog/DeviceNameDialog.tsx @@ -44,8 +44,14 @@ export const DeviceNameDialog = ({ values: defaultValues, }); - const { currentLength: currentLongNameLength } = validateMaxByteLength(getValues('longName'), MAX_LONG_NAME_BYTE_LENGTH); - const { currentLength: currentShortNameLength } = validateMaxByteLength(getValues('shortName'), MAX_SHORT_NAME_BYTE_LENGTH); + const { currentLength: currentLongNameLength } = validateMaxByteLength( + getValues("longName"), + MAX_LONG_NAME_BYTE_LENGTH, + ); + const { currentLength: currentShortNameLength } = validateMaxByteLength( + getValues("shortName"), + MAX_SHORT_NAME_BYTE_LENGTH, + ); const onSubmit = handleSubmit((data) => { connection?.setOwner( @@ -83,7 +89,7 @@ export const DeviceNameDialog = ({ label: "Long Name", type: "text", properties: { - className: 'text-slate-900 dark:text-slate-200', + className: "text-slate-900 dark:text-slate-200", fieldLength: { currentValueLength: currentLongNameLength ?? 0, max: MAX_LONG_NAME_BYTE_LENGTH, @@ -113,11 +119,13 @@ export const DeviceNameDialog = ({
- + ); -}; \ No newline at end of file +}; diff --git a/src/components/Dialog/DialogManager.tsx b/src/components/Dialog/DialogManager.tsx index c7cb7605..acd1c9ea 100644 --- a/src/components/Dialog/DialogManager.tsx +++ b/src/components/Dialog/DialogManager.tsx @@ -12,7 +12,6 @@ import { RefreshKeysDialog } from "@components/Dialog/RefreshKeysDialog/RefreshK import { RebootOTADialog } from "@components/Dialog/RebootOTADialog.tsx"; import { DeleteMessagesDialog } from "@components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx"; - export const DialogManager = () => { const { channels, config, dialog, setDialogOpen } = useDevice(); return ( diff --git a/src/components/Dialog/ImportDialog.tsx b/src/components/Dialog/ImportDialog.tsx index 242502cd..cb6a5389 100644 --- a/src/components/Dialog/ImportDialog.tsx +++ b/src/components/Dialog/ImportDialog.tsx @@ -51,7 +51,7 @@ export const ImportDialog = ({ const paddedString = encodedChannelConfig .padEnd( encodedChannelConfig.length + - ((4 - (encodedChannelConfig.length % 4)) % 4), + ((4 - (encodedChannelConfig.length % 4)) % 4), "=", ) .replace(/-/g, "+") diff --git a/src/components/Dialog/LocationResponseDialog.tsx b/src/components/Dialog/LocationResponseDialog.tsx index 4625fa87..a338e865 100644 --- a/src/components/Dialog/LocationResponseDialog.tsx +++ b/src/components/Dialog/LocationResponseDialog.tsx @@ -43,8 +43,9 @@ export const LocationResponseDialog = ({ Coordinates:{" "} diff --git a/src/components/Dialog/NewDeviceDialog.tsx b/src/components/Dialog/NewDeviceDialog.tsx index b9fc6b1c..2fbbe92f 100644 --- a/src/components/Dialog/NewDeviceDialog.tsx +++ b/src/components/Dialog/NewDeviceDialog.tsx @@ -90,8 +90,8 @@ const ErrorMessage = ({ missingFeatures }: FeatureErrorProps) => { {browserFeatures.length > 0 && ( <> This connection type requires{" "} - {formatFeatureList(browserFeatures)}. Please use a - supported browser, like Chrome or Edge. + {formatFeatureList(browserFeatures)}. Please use a supported + browser, like Chrome or Edge. )} {needsSecureContext && ( @@ -114,11 +114,9 @@ export const NewDeviceDialog = ({ open, onOpenChange, }: NewDeviceProps) => { - const [connectionInProgress, setConnectionInProgress] = - useState(false); + const [connectionInProgress, setConnectionInProgress] = useState(false); const { unsupported } = useBrowserFeatureDetection(); - const tabs: TabManifest[] = [ { label: "HTTP", @@ -160,7 +158,11 @@ export const NewDeviceDialog = ({ {tab.isDisabled ? : null} - onOpenChange(false)} setConnectionInProgress={setConnectionInProgress} connectionInProgress={connectionInProgress} /> + onOpenChange(false)} + setConnectionInProgress={setConnectionInProgress} + connectionInProgress={connectionInProgress} + /> ))} diff --git a/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.test.tsx b/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.test.tsx index 2b2edc23..e1f3ca78 100644 --- a/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.test.tsx +++ b/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.test.tsx @@ -1,4 +1,4 @@ -import { describe, it, vi, expect, beforeEach } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { render, screen } from "@testing-library/react"; import { NodeDetailsDialog } from "@components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx"; import { useDevice } from "@core/stores/deviceStore.ts"; @@ -11,7 +11,6 @@ vi.mock("@core/stores/appStore"); const mockUseDevice = vi.mocked(useDevice); const mockUseAppStore = vi.mocked(useAppStore); - describe("NodeDetailsDialog", () => { const mockDevice = { num: 1234, @@ -54,30 +53,33 @@ describe("NodeDetailsDialog", () => { }); it("renders node details correctly", () => { - render( { }} />); + render( {}} />); - expect(screen.getByText(/Node Details for Test Node \(TN\)/i)).toBeInTheDocument(); + expect(screen.getByText(/Node Details for Test Node \(TN\)/i)) + .toBeInTheDocument(); expect(screen.getByText("Node Number: 1234")).toBeInTheDocument(); expect(screen.getByText(/Node Hex: !/i)).toBeInTheDocument(); expect(screen.getByText(/Last Heard:/i)).toBeInTheDocument(); expect(screen.getByText(/Coordinates:/i)).toBeInTheDocument(); - const link = screen.getByRole('link', { name: /^45, -75$/ }); + const link = screen.getByRole("link", { name: /^45, -75$/ }); expect(link).toBeInTheDocument(); - expect(link).toHaveAttribute('href', expect.stringContaining('openstreetmap.org')); + expect(link).toHaveAttribute( + "href", + expect.stringContaining("openstreetmap.org"), + ); expect(screen.getByText(/Altitude: 200m/i)).toBeInTheDocument(); - expect(screen.getByText(/Air TX utilization: 50.12%/i)).toBeInTheDocument(); - expect(screen.getByText(/Channel utilization: 75.46%/i)).toBeInTheDocument(); + expect(screen.getByText(/Channel utilization: 75.46%/i)) + .toBeInTheDocument(); expect(screen.getByText(/Battery level: 88.79%/i)).toBeInTheDocument(); expect(screen.getByText(/Voltage: 4.20V/i)).toBeInTheDocument(); expect(screen.getByText(/Uptime:/i)).toBeInTheDocument(); expect(screen.getByText(/All Raw Metrics:/i)).toBeInTheDocument(); - }); it("renders null if device is not found", () => { @@ -99,7 +101,9 @@ describe("NodeDetailsDialog", () => { }, }); - const { container } = render( { }} />); + const { container } = render( + {}} />, + ); expect(container.firstChild).toBeNull(); expect(screen.queryByText(/Node Details for/i)).not.toBeInTheDocument(); @@ -110,7 +114,7 @@ describe("NodeDetailsDialog", () => { mockUseDevice.mockReturnValue({ getNode: () => nodeWithoutPosition }); mockUseAppStore.mockReturnValue({ nodeNumDetails: 1234 }); - render( { }} />); + render( {}} />); expect(screen.queryByText(/Coordinates:/i)).not.toBeInTheDocument(); expect(screen.queryByText(/Altitude:/i)).not.toBeInTheDocument(); @@ -122,7 +126,7 @@ describe("NodeDetailsDialog", () => { mockUseDevice.mockReturnValue({ getNode: () => nodeWithoutMetrics }); mockUseAppStore.mockReturnValue({ nodeNumDetails: 1234 }); - render( { }} />); + render( {}} />); expect(screen.queryByText(/Device Metrics:/i)).not.toBeInTheDocument(); expect(screen.queryByText(/Air TX utilization:/i)).not.toBeInTheDocument(); @@ -134,9 +138,8 @@ describe("NodeDetailsDialog", () => { mockUseDevice.mockReturnValue({ getNode: () => nodeNeverHeard }); mockUseAppStore.mockReturnValue({ nodeNumDetails: 1234 }); - render( { }} />); + render( {}} />); expect(screen.getByText(/Last Heard: Never/i)).toBeInTheDocument(); }); - -}); \ No newline at end of file +}); diff --git a/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx b/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx index 9001c5f1..a185bdcf 100644 --- a/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx +++ b/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx @@ -65,7 +65,7 @@ export const NodeDetailsDialog = ({ return ( - + @@ -78,9 +78,8 @@ export const NodeDetailsDialog = ({ )} -
diff --git a/src/components/Dialog/NodeOptionsDialog.tsx b/src/components/Dialog/NodeOptionsDialog.tsx index dcf20f00..4379e589 100644 --- a/src/components/Dialog/NodeOptionsDialog.tsx +++ b/src/components/Dialog/NodeOptionsDialog.tsx @@ -13,7 +13,10 @@ import { numberToHexUnpadded } from "@noble/curves/abstract/utils"; import { TrashIcon } from "lucide-react"; import { Button } from "../UI/Button.tsx"; -import { MessageType, useMessageStore } from "../../core/stores/messageStore/index.ts"; +import { + MessageType, + useMessageStore, +} from "../../core/stores/messageStore/index.ts"; export interface NodeOptionsDialogProps { node: Protobuf.Mesh.NodeInfo | undefined; diff --git a/src/components/Dialog/PkiRegenerateDialog.tsx b/src/components/Dialog/PkiRegenerateDialog.tsx index b0a0df16..58fb7208 100644 --- a/src/components/Dialog/PkiRegenerateDialog.tsx +++ b/src/components/Dialog/PkiRegenerateDialog.tsx @@ -14,7 +14,7 @@ export interface PkiRegenerateDialogProps { title: string; description: string; button: string; - } + }; open: boolean; onOpenChange: () => void; onSubmit: () => void; diff --git a/src/components/Dialog/QRDialog.tsx b/src/components/Dialog/QRDialog.tsx index 6eb86356..0dc67fb7 100644 --- a/src/components/Dialog/QRDialog.tsx +++ b/src/components/Dialog/QRDialog.tsx @@ -79,8 +79,8 @@ export const QRDialog = ({ {channel.settings?.name.length ? channel.settings.name : channel.role === Protobuf.Channel.Channel_Role.PRIMARY - ? "Primary" - : `Channel: ${channel.index}`} + ? "Primary" + : `Channel: ${channel.index}`}
@@ -101,4 +104,3 @@ export const RebootOTADialog = ({ open, onOpenChange }: RebootOTADialogProps) => ); }; - diff --git a/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx b/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx index bf379436..2b3c557b 100644 --- a/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx +++ b/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx @@ -3,7 +3,7 @@ import { DeviceContext, useDeviceStore } from "@core/stores/deviceStore.ts"; import { RefreshKeysDialog } from "./RefreshKeysDialog.tsx"; import { useMessageStore } from "../../../core/stores/messageStore/index.ts"; import { useRefreshKeysDialog } from "./useRefreshKeysDialog.ts"; -import { expect, test, vi, beforeEach, afterEach } from 'vitest'; +import { afterEach, beforeEach, expect, test, vi } from "vitest"; import { Protobuf } from "@meshtastic/core"; vi.mock("@core/stores/messageStore"); @@ -12,7 +12,9 @@ vi.mock("./useRefreshKeysDialog"); const mockUseMessageStore = vi.mocked(useMessageStore); const mockUseRefreshKeysDialog = vi.mocked(useRefreshKeysDialog); -const getInitialState = () => useDeviceStore.getInitialState?.() ?? { devices: new Map(), remoteDevices: new Map() }; +const getInitialState = () => + useDeviceStore.getInitialState?.() ?? + { devices: new Map(), remoteDevices: new Map() }; beforeEach(() => { useDeviceStore.setState(getInitialState(), true); @@ -39,17 +41,19 @@ test("renders dialog when there is a node error for the active chat", () => { longName: "Problem Node Long", shortName: "ProbNode", isLicensed: false, - macaddr: new Uint8Array(0) + macaddr: new Uint8Array(0), }, lastHeard: Date.now() / 1000, - snr: 10 + snr: 10, } as Protobuf.Mesh.NodeInfo); deviceStore.setNodeError(activeChatNum, "PKI_MISMATCH"); const updatedDeviceState = useDeviceStore.getState().getDevice(deviceId); if (!updatedDeviceState) { - throw new Error("Failed to get updated device state from store for provider"); + throw new Error( + "Failed to get updated device state from store for provider", + ); } mockUseMessageStore.mockReturnValue({ activeChat: activeChatNum }); @@ -63,12 +67,18 @@ test("renders dialog when there is a node error for the active chat", () => { render( - + , ); - expect(screen.getByText(/Keys Mismatch - Problem Node Long/)).toBeInTheDocument(); - expect(screen.getByText(/Your node is unable to send a direct message to node: Problem Node Long \(ProbNode\)/)).toBeInTheDocument(); - expect(screen.getByRole("button", { name: "Request New Keys" })).toBeInTheDocument(); + expect(screen.getByText(/Keys Mismatch - Problem Node Long/)) + .toBeInTheDocument(); + expect( + screen.getByText( + /Your node is unable to send a direct message to node: Problem Node Long \(ProbNode\)/, + ), + ).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Request New Keys" })) + .toBeInTheDocument(); expect(screen.getByRole("button", { name: "Dismiss" })).toBeInTheDocument(); }); @@ -90,7 +100,7 @@ test("does not render dialog if no error exists for active chat", () => { const { container } = render( - + , ); expect(container.firstChild).toBeNull(); diff --git a/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx b/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx index 98625ceb..2f0986af 100644 --- a/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx +++ b/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx @@ -16,7 +16,9 @@ export interface RefreshKeysDialogProps { onOpenChange: (open: boolean) => void; } -export const RefreshKeysDialog = ({ open, onOpenChange }: RefreshKeysDialogProps) => { +export const RefreshKeysDialog = ( + { open, onOpenChange }: RefreshKeysDialogProps, +) => { const { activeChat } = useMessageStore(); const { nodeErrors, getNode } = useDevice(); const { handleCloseDialog, handleNodeRemove } = useRefreshKeysDialog(); @@ -31,8 +33,12 @@ export const RefreshKeysDialog = ({ open, onOpenChange }: RefreshKeysDialogProps const text = { title: `Keys Mismatch - ${nodeWithError?.user?.longName ?? ""}`, - description: `Your node is unable to send a direct message to node: ${nodeWithError?.user?.longName ?? ""} (${nodeWithError?.user?.shortName ?? ""}). This is due to the remote node's current public key does not match the previously stored key for this node.`, - } + description: `Your node is unable to send a direct message to node: ${ + nodeWithError?.user?.longName ?? "" + } (${ + nodeWithError?.user?.shortName ?? "" + }). This is due to the remote node's current public key does not match the previously stored key for this node.`, + }; return ( @@ -44,7 +50,10 @@ export const RefreshKeysDialog = ({ open, onOpenChange }: RefreshKeysDialogProps
  • - +
    @@ -70,6 +79,6 @@ export const RefreshKeysDialog = ({ open, onOpenChange }: RefreshKeysDialogProps
{/* */}
-
+ ); }; diff --git a/src/components/Dialog/RefreshKeysDialog/useRefreshKeysDialog.test.ts b/src/components/Dialog/RefreshKeysDialog/useRefreshKeysDialog.test.ts index b50eaee6..4e10a7b5 100644 --- a/src/components/Dialog/RefreshKeysDialog/useRefreshKeysDialog.test.ts +++ b/src/components/Dialog/RefreshKeysDialog/useRefreshKeysDialog.test.ts @@ -1,4 +1,4 @@ -import { renderHook, act } from "@testing-library/react"; +import { act, renderHook } from "@testing-library/react"; import { useRefreshKeysDialog } from "./useRefreshKeysDialog.ts"; import { beforeEach, describe, expect, it, Mock, vi } from "vitest"; import { useDevice } from "@core/stores/deviceStore.ts"; @@ -38,7 +38,7 @@ describe("useRefreshKeysDialog Hook", () => { }); vi.mocked(useMessageStore).mockReturnValue({ - activeChat: "chat-123" + activeChat: "chat-123", }); }); @@ -46,7 +46,9 @@ describe("useRefreshKeysDialog Hook", () => { getNodeErrorMock.mockReturnValue({ node: "node-abc" }); const { result } = renderHook(() => useRefreshKeysDialog()); - act(() => { result.current.handleNodeRemove(); }); + act(() => { + result.current.handleNodeRemove(); + }); expect(getNodeErrorMock).toHaveBeenCalledTimes(1); expect(getNodeErrorMock).toHaveBeenCalledWith("chat-123"); @@ -60,7 +62,9 @@ describe("useRefreshKeysDialog Hook", () => { it("handleNodeRemove should do nothing if there is no error", () => { const { result } = renderHook(() => useRefreshKeysDialog()); - act(() => { result.current.handleNodeRemove(); }); + act(() => { + result.current.handleNodeRemove(); + }); expect(getNodeErrorMock).toHaveBeenCalledTimes(1); expect(getNodeErrorMock).toHaveBeenCalledWith("chat-123"); @@ -79,4 +83,4 @@ describe("useRefreshKeysDialog Hook", () => { expect(setDialogOpenMock).toHaveBeenCalledTimes(1); expect(setDialogOpenMock).toHaveBeenCalledWith("refreshKeys", false); }); -}); \ No newline at end of file +}); diff --git a/src/components/Dialog/RefreshKeysDialog/useRefreshKeysDialog.ts b/src/components/Dialog/RefreshKeysDialog/useRefreshKeysDialog.ts index ba4f6740..ac27b1d8 100644 --- a/src/components/Dialog/RefreshKeysDialog/useRefreshKeysDialog.ts +++ b/src/components/Dialog/RefreshKeysDialog/useRefreshKeysDialog.ts @@ -3,11 +3,12 @@ import { useDevice } from "@core/stores/deviceStore.ts"; import { useMessageStore } from "@core/stores/messageStore/index.ts"; export function useRefreshKeysDialog() { - const { removeNode, setDialogOpen, clearNodeError, getNodeError } = useDevice(); + const { removeNode, setDialogOpen, clearNodeError, getNodeError } = + useDevice(); const { activeChat } = useMessageStore(); const handleCloseDialog = useCallback(() => { - setDialogOpen('refreshKeys', false); + setDialogOpen("refreshKeys", false); }, [setDialogOpen]); const handleNodeRemove = useCallback(() => { @@ -22,6 +23,6 @@ export function useRefreshKeysDialog() { return { handleCloseDialog, - handleNodeRemove + handleNodeRemove, }; -} \ No newline at end of file +} diff --git a/src/components/Dialog/TracerouteResponseDialog.tsx b/src/components/Dialog/TracerouteResponseDialog.tsx index 3ce35765..7895c326 100644 --- a/src/components/Dialog/TracerouteResponseDialog.tsx +++ b/src/components/Dialog/TracerouteResponseDialog.tsx @@ -26,8 +26,8 @@ export const TracerouteResponseDialog = ({ const { getNode } = useDevice(); const route: number[] = traceroute?.data.route ?? []; const routeBack: number[] = traceroute?.data.routeBack ?? []; - const snrTowards = (traceroute?.data.snrTowards ?? []).map(snr => snr / 4); - const snrBack = (traceroute?.data.snrBack ?? []).map(snr => snr / 4); + const snrTowards = (traceroute?.data.snrTowards ?? []).map((snr) => snr / 4); + const snrBack = (traceroute?.data.snrBack ?? []).map((snr) => snr / 4); const from = getNode(traceroute?.from ?? 0); const longName = from?.user?.longName ?? (from ? `!${numberToHexUnpadded(from?.num)}` : "Unknown"); diff --git a/src/components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.test.tsx b/src/components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.test.tsx index c6c8ff29..68f0ffe9 100644 --- a/src/components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.test.tsx +++ b/src/components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.test.tsx @@ -1,6 +1,6 @@ // deno-lint-ignore-file -import { render, screen, fireEvent } from "@testing-library/react"; -import { describe, it, expect, vi } from "vitest"; +import { fireEvent, render, screen } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; import { UnsafeRolesDialog } from "@components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.tsx"; import { eventBus } from "@core/utils/eventBus.ts"; import { DeviceWrapper } from "@app/DeviceWrapper.tsx"; @@ -10,41 +10,58 @@ describe("UnsafeRolesDialog", () => { setDialogOpen: vi.fn(), }; - const renderWithDeviceContext = (ui: any) => { + const renderWithDeviceContext = (ui: React.ReactNode) => { return render( {ui} - +
, ); }; it("renders the dialog when open is true", () => { - renderWithDeviceContext(); + renderWithDeviceContext( + , + ); - const dialog = screen.getByRole('dialog'); + const dialog = screen.getByRole("dialog"); expect(dialog).toBeInTheDocument(); expect(screen.getByText(/I have read the/i)).toBeInTheDocument(); - expect(screen.getByText(/understand the implications/i)).toBeInTheDocument(); + expect(screen.getByText(/understand the implications/i)) + .toBeInTheDocument(); - const links = screen.getAllByRole('link'); + const links = screen.getAllByRole("link"); expect(links).toHaveLength(2); - expect(links[0]).toHaveTextContent('Device Role Documentation'); - expect(links[1]).toHaveTextContent('Choosing The Right Device Role'); + expect(links[0]).toHaveTextContent("Device Role Documentation"); + expect(links[1]).toHaveTextContent("Choosing The Right Device Role"); }); it("displays the correct links", () => { - renderWithDeviceContext(); + renderWithDeviceContext( + , + ); - const docLink = screen.getByRole("link", { name: /Device Role Documentation/i }); - const blogLink = screen.getByRole("link", { name: /Choosing The Right Device Role/i }); + const docLink = screen.getByRole("link", { + name: /Device Role Documentation/i, + }); + const blogLink = screen.getByRole("link", { + name: /Choosing The Right Device Role/i, + }); - expect(docLink).toHaveAttribute("href", "https://meshtastic.org/docs/configuration/radio/device/"); - expect(blogLink).toHaveAttribute("href", "https://meshtastic.org/blog/choosing-the-right-device-role/"); + expect(docLink).toHaveAttribute( + "href", + "https://meshtastic.org/docs/configuration/radio/device/", + ); + expect(blogLink).toHaveAttribute( + "href", + "https://meshtastic.org/blog/choosing-the-right-device-role/", + ); }); it("does not allow confirmation until checkbox is checked", () => { - renderWithDeviceContext(); + renderWithDeviceContext( + , + ); const confirmButton = screen.getByRole("button", { name: /confirm/i }); @@ -58,27 +75,37 @@ describe("UnsafeRolesDialog", () => { it("emits the correct event when closing via close button", () => { const eventSpy = vi.spyOn(eventBus, "emit"); - renderWithDeviceContext(); + renderWithDeviceContext( + , + ); const dismissButton = screen.getByRole("button", { name: /close/i }); fireEvent.click(dismissButton); - expect(eventSpy).toHaveBeenCalledWith("dialog:unsafeRoles", { action: "dismiss" }); + expect(eventSpy).toHaveBeenCalledWith("dialog:unsafeRoles", { + action: "dismiss", + }); }); it("emits the correct event when dismissing", () => { const eventSpy = vi.spyOn(eventBus, "emit"); - renderWithDeviceContext(); + renderWithDeviceContext( + , + ); const dismissButton = screen.getByRole("button", { name: /dismiss/i }); fireEvent.click(dismissButton); - expect(eventSpy).toHaveBeenCalledWith("dialog:unsafeRoles", { action: "dismiss" }); + expect(eventSpy).toHaveBeenCalledWith("dialog:unsafeRoles", { + action: "dismiss", + }); }); it("emits the correct event when confirming", () => { const eventSpy = vi.spyOn(eventBus, "emit"); - renderWithDeviceContext(); + renderWithDeviceContext( + , + ); const checkbox = screen.getByRole("checkbox"); const confirmButton = screen.getByRole("button", { name: /confirm/i }); @@ -86,6 +113,8 @@ describe("UnsafeRolesDialog", () => { fireEvent.click(checkbox); fireEvent.click(confirmButton); - expect(eventSpy).toHaveBeenCalledWith("dialog:unsafeRoles", { action: "confirm" }); + expect(eventSpy).toHaveBeenCalledWith("dialog:unsafeRoles", { + action: "confirm", + }); }); }); diff --git a/src/components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.tsx b/src/components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.tsx index d3dc02dd..b828a2ad 100644 --- a/src/components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.tsx +++ b/src/components/Dialog/UnsafeRolesDialog/UnsafeRolesDialog.tsx @@ -19,29 +19,40 @@ export interface RouterRoleDialogProps { onOpenChange: (open: boolean) => void; } -export const UnsafeRolesDialog = ({ open, onOpenChange }: RouterRoleDialogProps) => { +export const UnsafeRolesDialog = ( + { open, onOpenChange }: RouterRoleDialogProps, +) => { const [confirmState, setConfirmState] = useState(false); const { setDialogOpen } = useDevice(); - const deviceRoleLink = "https://meshtastic.org/docs/configuration/radio/device/"; - const choosingTheRightDeviceRoleLink = "https://meshtastic.org/blog/choosing-the-right-device-role/"; + const deviceRoleLink = + "https://meshtastic.org/docs/configuration/radio/device/"; + const choosingTheRightDeviceRoleLink = + "https://meshtastic.org/blog/choosing-the-right-device-role/"; - const handleCloseDialog = (action: 'confirm' | 'dismiss') => { - setDialogOpen('unsafeRoles', false); + const handleCloseDialog = (action: "confirm" | "dismiss") => { + setDialogOpen("unsafeRoles", false); setConfirmState(false); - eventBus.emit('dialog:unsafeRoles', { action }); - } + eventBus.emit("dialog:unsafeRoles", { action }); + }; return ( - handleCloseDialog('dismiss')} /> + handleCloseDialog("dismiss")} /> Are you sure? - I have read the Device Role Documentation{" "} - and the blog post about Choosing The Right Device Role and understand the implications of changing the role. + I have read the{" "} + + Device Role Documentation + {" "} + and the blog post about{" "} + + Choosing The Right Device Role + {" "} + and understand the implications of changing the role.
handleCloseDialog('dismiss')}> Dismiss + onClick={() => handleCloseDialog("dismiss")} + > + Dismiss -
+ ); }; diff --git a/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.test.tsx b/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.test.tsx index 2661874f..cd51f590 100644 --- a/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.test.tsx +++ b/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.test.tsx @@ -1,9 +1,12 @@ -import { describe, it, expect, vi, beforeEach, afterEach, Mock } from 'vitest'; -import { renderHook } from '@testing-library/react'; -import { useUnsafeRolesDialog, UNSAFE_ROLES } from "@components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.ts"; +import { afterEach, beforeEach, describe, expect, it, Mock, vi } from "vitest"; +import { renderHook } from "@testing-library/react"; +import { + UNSAFE_ROLES, + useUnsafeRolesDialog, +} from "@components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.ts"; import { eventBus } from "@core/utils/eventBus.ts"; -vi.mock('@core/utils/eventBus', () => ({ +vi.mock("@core/utils/eventBus", () => ({ eventBus: { on: vi.fn(), off: vi.fn(), @@ -15,13 +18,13 @@ const mockDevice = { setDialogOpen: vi.fn(), }; -vi.mock('@core/stores/deviceStore', () => ({ +vi.mock("@core/stores/deviceStore", () => ({ useDevice: () => ({ setDialogOpen: mockDevice.setDialogOpen, }), })); -describe('useUnsafeRolesDialog', () => { +describe("useUnsafeRolesDialog", () => { beforeEach(() => { vi.resetAllMocks(); }); @@ -34,84 +37,115 @@ describe('useUnsafeRolesDialog', () => { return renderHook(() => useUnsafeRolesDialog()); }; - describe('handleCloseDialog', () => { - it('should call setDialogOpen with correct parameters when dialog is closed', () => { + describe("handleCloseDialog", () => { + it("should call setDialogOpen with correct parameters when dialog is closed", () => { const { result } = renderUnsafeRolesHook(); result.current.handleCloseDialog(); - expect(mockDevice.setDialogOpen).toHaveBeenCalledWith('unsafeRoles', false); + expect(mockDevice.setDialogOpen).toHaveBeenCalledWith( + "unsafeRoles", + false, + ); }); }); - describe('validateRoleSelection', () => { - it('should resolve with true for safe roles without opening dialog', async () => { + describe("validateRoleSelection", () => { + it("should resolve with true for safe roles without opening dialog", async () => { const { result } = renderUnsafeRolesHook(); - const safeRole = 'SAFE_ROLE'; + const safeRole = "SAFE_ROLE"; - const validationResult = await result.current.validateRoleSelection(safeRole); + const validationResult = await result.current.validateRoleSelection( + safeRole, + ); expect(validationResult).toBe(true); expect(mockDevice.setDialogOpen).not.toHaveBeenCalled(); }); - it('should open dialog for unsafe roles and resolve with true when confirmed', async () => { + it("should open dialog for unsafe roles and resolve with true when confirmed", async () => { const { result } = renderUnsafeRolesHook(); - const validationPromise = result.current.validateRoleSelection(UNSAFE_ROLES[0]); + const validationPromise = result.current.validateRoleSelection( + UNSAFE_ROLES[0], + ); - expect(mockDevice.setDialogOpen).toHaveBeenCalledWith('unsafeRoles', true); - expect(eventBus.on).toHaveBeenCalledWith('dialog:unsafeRoles', expect.any(Function)); + expect(mockDevice.setDialogOpen).toHaveBeenCalledWith( + "unsafeRoles", + true, + ); + expect(eventBus.on).toHaveBeenCalledWith( + "dialog:unsafeRoles", + expect.any(Function), + ); const onHandler = (eventBus.on as Mock).mock.calls[0][1]; - onHandler({ action: 'confirm' }); + onHandler({ action: "confirm" }); const validationResult = await validationPromise; expect(validationResult).toBe(true); - expect(eventBus.off).toHaveBeenCalledWith('dialog:unsafeRoles', onHandler); + expect(eventBus.off).toHaveBeenCalledWith( + "dialog:unsafeRoles", + onHandler, + ); }); - it('should resolve with false when user dismisses the dialog', async () => { + it("should resolve with false when user dismisses the dialog", async () => { const { result } = renderUnsafeRolesHook(); - const validationPromise = result.current.validateRoleSelection(UNSAFE_ROLES[0]); + const validationPromise = result.current.validateRoleSelection( + UNSAFE_ROLES[0], + ); const onHandler = (eventBus.on as Mock).mock.calls[0][1]; - onHandler({ action: 'dismiss' }); + onHandler({ action: "dismiss" }); const validationResult = await validationPromise; expect(validationResult).toBe(false); - expect(eventBus.off).toHaveBeenCalledWith('dialog:unsafeRoles', onHandler); + expect(eventBus.off).toHaveBeenCalledWith( + "dialog:unsafeRoles", + onHandler, + ); }); - it('should clean up event listener after response', async () => { + it("should clean up event listener after response", async () => { const { result } = renderUnsafeRolesHook(); - const validationPromise = result.current.validateRoleSelection(UNSAFE_ROLES[1]); + const validationPromise = result.current.validateRoleSelection( + UNSAFE_ROLES[1], + ); const onHandler = (eventBus.on as Mock).mock.calls[0][1]; - onHandler({ action: 'confirm' }); + onHandler({ action: "confirm" }); await validationPromise; - expect(eventBus.off).toHaveBeenCalledWith('dialog:unsafeRoles', onHandler); + expect(eventBus.off).toHaveBeenCalledWith( + "dialog:unsafeRoles", + onHandler, + ); }); }); - it('should work with all unsafe roles', async () => { + it("should work with all unsafe roles", async () => { const { result } = renderUnsafeRolesHook(); for (const unsafeRole of UNSAFE_ROLES) { mockDevice.setDialogOpen.mockClear(); (eventBus.on as Mock).mockClear(); - const validationPromise = result.current.validateRoleSelection(unsafeRole); + const validationPromise = result.current.validateRoleSelection( + unsafeRole, + ); - expect(mockDevice.setDialogOpen).toHaveBeenCalledWith('unsafeRoles', true); + expect(mockDevice.setDialogOpen).toHaveBeenCalledWith( + "unsafeRoles", + true, + ); const onHandler = (eventBus.on as Mock).mock.calls[0][1]; - onHandler({ action: 'confirm' }); + onHandler({ action: "confirm" }); const validationResult = await validationPromise; expect(validationResult).toBe(true); } }); -}); \ No newline at end of file +}); diff --git a/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.ts b/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.ts index 5d417704..cbce3bb7 100644 --- a/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.ts +++ b/src/components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.ts @@ -21,7 +21,9 @@ export const useUnsafeRolesDialog = () => { setDialogOpen("unsafeRoles", true); return new Promise((resolve) => { - const handleResponse = ({ action }: { action: "confirm" | "dismiss" }) => { + const handleResponse = ( + { action }: { action: "confirm" | "dismiss" }, + ) => { eventBus.off("dialog:unsafeRoles", handleResponse); resolve(action === "confirm"); }; @@ -29,7 +31,7 @@ export const useUnsafeRolesDialog = () => { eventBus.on("dialog:unsafeRoles", handleResponse); }); }, - [setDialogOpen] + [setDialogOpen], ); return { diff --git a/src/components/Form/DynamicForm.tsx b/src/components/Form/DynamicForm.tsx index 5522ec4f..dfdf1694 100644 --- a/src/components/Form/DynamicForm.tsx +++ b/src/components/Form/DynamicForm.tsx @@ -15,7 +15,6 @@ import { } from "react-hook-form"; import { Heading } from "@components/UI/Typography/Heading.tsx"; - interface DisabledBy { fieldName: Path; selector?: number; @@ -124,7 +123,9 @@ export function DynamicForm({ })} ))} - {hasSubmitButton && } + {hasSubmitButton && ( + + )} ); } diff --git a/src/components/Form/FormInput.tsx b/src/components/Form/FormInput.tsx index 8a2015bc..c0af74ae 100644 --- a/src/components/Form/FormInput.tsx +++ b/src/components/Form/FormInput.tsx @@ -5,8 +5,7 @@ import type { import { Input } from "@components/UI/Input.tsx"; import type { ChangeEventHandler } from "react"; import { useState } from "react"; -import { useController, type FieldValues } from "react-hook-form"; -import { cn } from "@core/utils/cn.ts"; +import { type FieldValues, useController } from "react-hook-form"; export interface InputFieldProps extends BaseFormBuilderProps { type: "text" | "number" | "password"; @@ -22,7 +21,7 @@ export interface InputFieldProps extends BaseFormBuilderProps { max?: number; currentValueLength?: number; showCharacterCount?: boolean; - }, + }; showPasswordToggle?: boolean; showCopyButton?: boolean; }; @@ -34,7 +33,9 @@ export function GenericInput({ field, }: GenericFormElementProps>) { const { fieldLength, ...restProperties } = field.properties || {}; - const [currentLength, setCurrentLength] = useState(fieldLength?.currentValueLength || 0); + const [currentLength, setCurrentLength] = useState( + fieldLength?.currentValueLength || 0, + ); const { field: controllerField } = useController({ name: field.name, @@ -44,27 +45,36 @@ export function GenericInput({ const handleInputChange = (e: React.ChangeEvent) => { const newValue = e.target.value; - if (field.properties?.fieldLength?.max && newValue.length > field.properties?.fieldLength?.max) { + if ( + field.properties?.fieldLength?.max && + newValue.length > field.properties?.fieldLength?.max + ) { return; } setCurrentLength(newValue.length); if (field.inputChange) field.inputChange(e); - controllerField.onChange(field.type === "number" ? Number.parseFloat(newValue).toString() : newValue); + controllerField.onChange( + field.type === "number" + ? Number.parseFloat(newValue).toString() + : newValue, + ); }; - return (
({ ))} ); -} \ No newline at end of file +} diff --git a/src/components/Form/FormPasswordGenerator.tsx b/src/components/Form/FormPasswordGenerator.tsx index f1d0b9f4..8cb92e07 100644 --- a/src/components/Form/FormPasswordGenerator.tsx +++ b/src/components/Form/FormPasswordGenerator.tsx @@ -31,7 +31,7 @@ export function PasswordGenerator({ field, disabled, }: GenericFormElementProps>) { - const { isVisible } = usePasswordVisibilityToggle() + const { isVisible } = usePasswordVisibilityToggle(); return ( extends BaseFormBuilderProps { type: "select"; @@ -46,7 +46,8 @@ export function SelectInput({ control, }); - const { enumValue, formatEnumName, ...remainingProperties } = field.properties; + const { enumValue, formatEnumName, ...remainingProperties } = + field.properties; const valueToKeyMap: Record = {}; const optionsEnumValues: [string, number][] = []; diff --git a/src/components/Form/FormWrapper.tsx b/src/components/Form/FormWrapper.tsx index c9a4da94..91635b8b 100644 --- a/src/components/Form/FormWrapper.tsx +++ b/src/components/Form/FormWrapper.tsx @@ -24,7 +24,9 @@ export const FieldWrapper = ({
-

{description}

+

+ {description} +

diff --git a/src/components/PageComponents/Channel.tsx b/src/components/PageComponents/Channel.tsx index 282e8aec..9968bf02 100644 --- a/src/components/PageComponents/Channel.tsx +++ b/src/components/PageComponents/Channel.tsx @@ -99,8 +99,12 @@ export const Channel = ({ channel }: SettingsPanelProps) => { psk: pass, moduleSettings: { ...channel?.settings?.moduleSettings, - positionPrecision: channel?.settings?.moduleSettings?.positionPrecision === undefined ? 10 : channel?.settings?.moduleSettings?.positionPrecision, - } + positionPrecision: + channel?.settings?.moduleSettings?.positionPrecision === + undefined + ? 10 + : channel?.settings?.moduleSettings?.positionPrecision, + }, }, }, }} @@ -125,7 +129,7 @@ export const Channel = ({ channel }: SettingsPanelProps) => { { type: "passwordGenerator", name: "settings.psk", - id: 'channel-psk', + id: "channel-psk", label: "Pre-Shared Key", description: "Supported PSK lengths: 256-bit, 128-bit, 8-bit, Empty (0-bit)", @@ -212,7 +216,8 @@ export const Channel = ({ channel }: SettingsPanelProps) => { text={{ button: "Regenerate", title: "Regenerate Pre-Shared Key?", - description: "Are you sure you want to regenerate the pre-shared key?", + description: + "Are you sure you want to regenerate the pre-shared key?", }} open={preSharedDialogOpen} onOpenChange={() => setPreSharedDialogOpen(false)} diff --git a/src/components/PageComponents/Config/Device/Device.test.tsx b/src/components/PageComponents/Config/Device/Device.test.tsx index 90bbbffc..538f6a5d 100644 --- a/src/components/PageComponents/Config/Device/Device.test.tsx +++ b/src/components/PageComponents/Config/Device/Device.test.tsx @@ -1,21 +1,21 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { render, screen, fireEvent, waitFor } from '@testing-library/react'; -import { Device } from '@components/PageComponents/Config/Device/index.tsx'; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { fireEvent, render, screen, waitFor } from "@testing-library/react"; +import { Device } from "@components/PageComponents/Config/Device/index.tsx"; import { useDevice } from "@core/stores/deviceStore.ts"; import { useUnsafeRolesDialog } from "@components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.ts"; import { Protobuf } from "@meshtastic/core"; -vi.mock('@core/stores/deviceStore.ts', () => ({ - useDevice: vi.fn() +vi.mock("@core/stores/deviceStore.ts", () => ({ + useDevice: vi.fn(), })); -vi.mock('@components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.ts', () => ({ - useUnsafeRolesDialog: vi.fn() +vi.mock("@components/Dialog/UnsafeRolesDialog/useUnsafeRolesDialog.ts", () => ({ + useUnsafeRolesDialog: vi.fn(), })); // Mock the DynamicForm component since we're testing the Device component, // not the DynamicForm implementation -vi.mock('@components/Form/DynamicForm', () => ({ +vi.mock("@components/Form/DynamicForm", () => ({ DynamicForm: vi.fn(({ onSubmit }) => { // Render a simplified version of the form for testing return ( @@ -28,13 +28,16 @@ vi.mock('@components/Form/DynamicForm', () => ({ onSubmit(mockData); }} > - {Object.entries(Protobuf.Config.Config_DeviceConfig_Role).map(([key, value]) => ( + {Object.entries(Protobuf.Config.Config_DeviceConfig_Role).map(( + [key, value], + ) => ( ))} -
); - }) + }), })); -describe('Device component', () => { +describe("Device component", () => { const setWorkingConfigMock = vi.fn(); const validateRoleSelectionMock = vi.fn(); const mockDeviceConfig = { @@ -63,17 +66,17 @@ describe('Device component', () => { vi.resetAllMocks(); // Mock the useDevice hook - (useDevice as any).mockReturnValue({ + useDevice.mockReturnValue({ config: { - device: mockDeviceConfig + device: mockDeviceConfig, }, - setWorkingConfig: setWorkingConfigMock + setWorkingConfig: setWorkingConfigMock, }); // Mock the useUnsafeRolesDialog hook validateRoleSelectionMock.mockResolvedValue(true); - (useUnsafeRolesDialog as any).mockReturnValue({ - validateRoleSelection: validateRoleSelectionMock + useUnsafeRolesDialog.mockReturnValue({ + validateRoleSelection: validateRoleSelectionMock, }); }); @@ -81,49 +84,48 @@ describe('Device component', () => { vi.clearAllMocks(); }); - it('should render the Device form', () => { + it("should render the Device form", () => { render(); - expect(screen.getByTestId('dynamic-form')).toBeInTheDocument(); + expect(screen.getByTestId("dynamic-form")).toBeInTheDocument(); }); - it('should use the validateRoleSelection from the unsafe roles hook', () => { + it("should use the validateRoleSelection from the unsafe roles hook", () => { render(); expect(useUnsafeRolesDialog).toHaveBeenCalled(); }); - it('should call setWorkingConfig when form is submitted', async () => { + it("should call setWorkingConfig when form is submitted", async () => { render(); - fireEvent.click(screen.getByTestId('submit-button')); + fireEvent.click(screen.getByTestId("submit-button")); await waitFor(() => { expect(setWorkingConfigMock).toHaveBeenCalledWith( expect.objectContaining({ payloadVariant: { case: "device", - value: expect.objectContaining({ role: "CLIENT" }) - } - }) + value: expect.objectContaining({ role: "CLIENT" }), + }, + }), ); }); }); - - it('should create config with proper structure', async () => { + it("should create config with proper structure", async () => { render(); // Simulate form submission - fireEvent.click(screen.getByTestId('submit-button')); + fireEvent.click(screen.getByTestId("submit-button")); await waitFor(() => { expect(setWorkingConfigMock).toHaveBeenCalledWith( expect.objectContaining({ payloadVariant: { case: "device", - value: expect.any(Object) - } - }) + value: expect.any(Object), + }, + }), ); }); }); -}); \ No newline at end of file +}); diff --git a/src/components/PageComponents/Config/Device/index.tsx b/src/components/PageComponents/Config/Device/index.tsx index 95498f2d..a04f4c19 100644 --- a/src/components/PageComponents/Config/Device/index.tsx +++ b/src/components/PageComponents/Config/Device/index.tsx @@ -16,7 +16,7 @@ export const Device = () => { case: "device", value: data, }, - }) + }), ); }; return ( @@ -83,16 +83,16 @@ export const Device = () => { description: "Disable triple click", }, { - type: 'text', - name: 'tzdef', - label: 'POSIX Timezone', - description: 'The POSIX timezone string for the device', + type: "text", + name: "tzdef", + label: "POSIX Timezone", + description: "The POSIX timezone string for the device", properties: { fieldLength: { max: 64, currentValueLength: config.device?.tzdef?.length, showCharacterCount: true, - } + }, }, }, { diff --git a/src/components/PageComponents/Config/Network/Network.test.tsx b/src/components/PageComponents/Config/Network/Network.test.tsx index 14f54e1c..c15ec1ab 100644 --- a/src/components/PageComponents/Config/Network/Network.test.tsx +++ b/src/components/PageComponents/Config/Network/Network.test.tsx @@ -1,131 +1,24 @@ -// import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -// import { render, screen, fireEvent, waitFor } from '@testing-library/react'; -// import { Network } from '@components/PageComponents/Config/Network/index.tsx'; -// import { useDevice } from "@core/stores/deviceStore.ts"; -// import { Protobuf } from "@meshtastic/core"; - -// vi.mock('@core/stores/deviceStore', () => ({ -// useDevice: vi.fn() -// })); - -// vi.mock('@components/Form/DynamicForm', () => ({ -// DynamicForm: vi.fn(({ onSubmit }) => { -// return ( -//
-// -// -//
-// ); -// }) -// })); - -// describe('Network component', () => { -// const setWorkingConfigMock = vi.fn(); -// const mockDeviceConfig = { -// role: "CLIENT", -// buttonGpio: 0, -// buzzerGpio: 0, -// rebroadcastMode: "ALL", -// nodeInfoBroadcastSecs: 300, -// doubleTapAsButtonPress: false, -// disableTripleClick: false, -// ledHeartbeatDisabled: false, -// }; - -// beforeEach(() => { -// vi.resetAllMocks(); - -// (useDevice as any).mockReturnValue({ -// config: { -// device: mockDeviceConfig -// }, -// setWorkingConfig: setWorkingConfigMock -// }); - -// }); - -// afterEach(() => { -// vi.clearAllMocks(); -// }); - -// it('should render the Network form', () => { -// render(); -// expect(screen.getByTestId('dynamic-form')).toBeInTheDocument(); -// }); - -// it('should call setWorkingConfig when form is submitted', async () => { -// render(); - -// fireEvent.click(screen.getByTestId('submit-button')); - -// await waitFor(() => { -// expect(setWorkingConfigMock).toHaveBeenCalledWith( -// expect.objectContaining({ -// payloadVariant: { -// case: "device", -// value: expect.objectContaining({ role: "CLIENT" }) -// } -// }) -// ); -// }); -// }); - - -// it('should create config with proper structure', async () => { -// render(); - -// // Simulate form submission -// fireEvent.click(screen.getByTestId('submit-button')); - -// await waitFor(() => { -// expect(setWorkingConfigMock).toHaveBeenCalledWith( -// expect.objectContaining({ -// payloadVariant: { -// case: "network", -// value: expect.any(Object) -// } -// }) -// ); -// }); -// }); -// }); - -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { render, screen, fireEvent, waitFor } from '@testing-library/react'; -import { Network } from '@components/PageComponents/Config/Network/index.tsx'; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { fireEvent, render, screen, waitFor } from "@testing-library/react"; +import { Network } from "@components/PageComponents/Config/Network/index.tsx"; import { useDevice } from "@core/stores/deviceStore.ts"; import { Protobuf } from "@meshtastic/core"; -vi.mock('@core/stores/deviceStore', () => ({ - useDevice: vi.fn() +vi.mock("@core/stores/deviceStore", () => ({ + useDevice: vi.fn(), })); -vi.mock('@components/Form/DynamicForm', async () => { - const React = await import('react'); +vi.mock("@components/Form/DynamicForm", async () => { + const React = await import("react"); const { useState } = React; return { - DynamicForm: ({ onSubmit, defaultValues }: any) => { - const [wifiEnabled, setWifiEnabled] = useState(defaultValues.wifiEnabled ?? false); - const [ssid, setSsid] = useState(defaultValues.wifiSsid ?? ''); - const [psk, setPsk] = useState(defaultValues.wifiPsk ?? ''); + DynamicForm: ({ onSubmit, defaultValues }) => { + const [wifiEnabled, setWifiEnabled] = useState( + defaultValues.wifiEnabled ?? false, + ); + const [ssid, setSsid] = useState(defaultValues.wifiSsid ?? ""); + const [psk, setPsk] = useState(defaultValues.wifiPsk ?? ""); return (
{ }, }; }); -; -describe('Network component', () => { +describe("Network component", () => { const setWorkingConfigMock = vi.fn(); const mockNetworkConfig = { wifiEnabled: false, - wifiSsid: '', - wifiPsk: '', - ntpServer: '', + wifiSsid: "", + wifiPsk: "", + ntpServer: "", ethEnabled: false, addressMode: Protobuf.Config.Config_NetworkConfig_AddressMode.DHCP, ipv4Config: { @@ -185,17 +77,17 @@ describe('Network component', () => { }, enabledProtocols: Protobuf.Config.Config_NetworkConfig_ProtocolFlags.NO_BROADCAST, - rsyslogServer: '', + rsyslogServer: "", }; beforeEach(() => { vi.resetAllMocks(); - (useDevice as any).mockReturnValue({ + useDevice.mockReturnValue({ config: { - network: mockNetworkConfig + network: mockNetworkConfig, }, - setWorkingConfig: setWorkingConfigMock + setWorkingConfig: setWorkingConfigMock, }); }); @@ -203,21 +95,21 @@ describe('Network component', () => { vi.clearAllMocks(); }); - it('should render the Network form', () => { + it("should render the Network form", () => { render(); - expect(screen.getByTestId('dynamic-form')).toBeInTheDocument(); + expect(screen.getByTestId("dynamic-form")).toBeInTheDocument(); }); - it('should disable SSID and PSK fields when wifi is off', () => { + it("should disable SSID and PSK fields when wifi is off", () => { render(); expect(screen.getByLabelText("SSID")).toBeDisabled(); expect(screen.getByLabelText("PSK")).toBeDisabled(); }); - it('should enable SSID and PSK when wifi is toggled on', async () => { + it("should enable SSID and PSK when wifi is toggled on", async () => { render(); const toggle = screen.getByLabelText("WiFi Enabled"); - screen.debug() + screen.debug(); fireEvent.click(toggle); // turns wifiEnabled = true @@ -227,7 +119,7 @@ describe('Network component', () => { }); }); - it('should call setWorkingConfig with the right structure on submit', async () => { + it("should call setWorkingConfig with the right structure on submit", async () => { render(); fireEvent.click(screen.getByTestId("submit-button")); @@ -239,28 +131,28 @@ describe('Network component', () => { case: "network", value: expect.objectContaining({ wifiEnabled: false, - wifiSsid: '', - wifiPsk: '', - ntpServer: '', + wifiSsid: "", + wifiPsk: "", + ntpServer: "", ethEnabled: false, - rsyslogServer: '', - }) - } - }) + rsyslogServer: "", + }), + }, + }), ); }); }); - it('should submit valid data after enabling wifi and entering SSID and PSK', async () => { + it("should submit valid data after enabling wifi and entering SSID and PSK", async () => { render(); fireEvent.click(screen.getByLabelText("WiFi Enabled")); fireEvent.change(screen.getByLabelText("SSID"), { - target: { value: "MySSID" } + target: { value: "MySSID" }, }); fireEvent.change(screen.getByLabelText("PSK"), { - target: { value: "MySecretPSK" } + target: { value: "MySecretPSK" }, }); fireEvent.click(screen.getByTestId("submit-button")); @@ -273,10 +165,10 @@ describe('Network component', () => { value: expect.objectContaining({ wifiEnabled: true, wifiSsid: "MySSID", - wifiPsk: "MySecretPSK" - }) - } - }) + wifiPsk: "MySecretPSK", + }), + }, + }), ); }); }); diff --git a/src/components/PageComponents/Config/Network/index.tsx b/src/components/PageComponents/Config/Network/index.tsx index cae121d6..defbba97 100644 --- a/src/components/PageComponents/Config/Network/index.tsx +++ b/src/components/PageComponents/Config/Network/index.tsx @@ -1,4 +1,7 @@ -import { NetworkValidationSchema, type NetworkValidation } from "@app/validation/config/network.ts"; +import { + type NetworkValidation, + NetworkValidationSchema, +} from "@app/validation/config/network.ts"; import { create } from "@bufbuild/protobuf"; import { DynamicForm } from "@components/Form/DynamicForm.tsx"; import { useDevice } from "@core/stores/deviceStore.ts"; @@ -55,8 +58,8 @@ export const Network = () => { ), dns: convertIntToIpAddress(config.network?.ipv4Config?.dns ?? 0), }, - enabledProtocols: config.network?.enabledProtocols ?? Protobuf.Config.Config_NetworkConfig_ProtocolFlags.NO_BROADCAST - + enabledProtocols: config.network?.enabledProtocols ?? + Protobuf.Config.Config_NetworkConfig_ProtocolFlags.NO_BROADCAST, }} fieldGroups={[ { @@ -183,10 +186,9 @@ export const Network = () => { name: "enabledProtocols", label: "Mesh via UDP", properties: { - enumValue: - Protobuf.Config.Config_NetworkConfig_ProtocolFlags, + enumValue: Protobuf.Config.Config_NetworkConfig_ProtocolFlags, formatEnumName: true, - } + }, }, ], }, diff --git a/src/components/PageComponents/Config/Position.tsx b/src/components/PageComponents/Config/Position.tsx index 0d3bf853..3792b9e8 100644 --- a/src/components/PageComponents/Config/Position.tsx +++ b/src/components/PageComponents/Config/Position.tsx @@ -74,7 +74,7 @@ export const Position = () => { name: "positionFlags", value: activeFlags, isChecked: (name: string) => - activeFlags?.includes(name as FlagName) ?? false, + activeFlags?.includes(name as FlagName) ?? false, onValueChange: onPositonFlagChange, label: "Position Flags", placeholder: "Select position flags...", diff --git a/src/components/PageComponents/Config/Security/Security.tsx b/src/components/PageComponents/Config/Security/Security.tsx index 6c6b880a..6b06ba2e 100644 --- a/src/components/PageComponents/Config/Security/Security.tsx +++ b/src/components/PageComponents/Config/Security/Security.tsx @@ -1,16 +1,12 @@ import { PkiRegenerateDialog } from "@components/Dialog/PkiRegenerateDialog.tsx"; import { DynamicForm } from "@components/Form/DynamicForm.tsx"; import { useAppStore } from "@core/stores/appStore.ts"; -import { - getX25519PrivateKey, - getX25519PublicKey, -} from "@core/utils/x25519.ts"; +import { getX25519PrivateKey, getX25519PublicKey } from "@core/utils/x25519.ts"; import type { SecurityValidation } from "@app/validation/config/security.ts"; import { create } from "@bufbuild/protobuf"; import { useDevice } from "@core/stores/deviceStore.ts"; import { Protobuf } from "@meshtastic/core"; import { fromByteArray, toByteArray } from "base64-js"; -import { Eye, EyeOff } from "lucide-react"; import { useReducer } from "react"; import { securityReducer } from "@components/PageComponents/Config/Security/securityReducer.tsx"; @@ -58,7 +54,8 @@ export const Security = () => { if (input.length % 4 !== 0) { addError( fieldName, - `${fieldName === "privateKey" ? "Private" : "Admin" + `${ + fieldName === "privateKey" ? "Private" : "Admin" } Key is required to be a 256 bit pre-shared key (PSK)`, ); return; @@ -73,7 +70,8 @@ export const Security = () => { console.error(e); addError( fieldName, - `Invalid ${fieldName === "privateKey" ? "Private" : "Admin" + `Invalid ${ + fieldName === "privateKey" ? "Private" : "Admin" } Key format`, ); } @@ -242,7 +240,7 @@ export const Security = () => { ? getErrorMessage("adminKey") : "", inputChange: adminKeyInputChangeEvent, - selectChange: () => { }, + selectChange: () => {}, bits: [{ text: "256 bit", value: "32", key: "bit256" }], devicePSKBitCount: state.privateKeyBitCount, hide: !state.adminKeyVisible, diff --git a/src/components/PageComponents/Connect/BLE.tsx b/src/components/PageComponents/Connect/BLE.tsx index 4e639855..24a2a4c8 100644 --- a/src/components/PageComponents/Connect/BLE.tsx +++ b/src/components/PageComponents/Connect/BLE.tsx @@ -9,10 +9,12 @@ import { BleConnection, ServiceUuid } from "@meshtastic/js"; import { useCallback, useEffect, useState } from "react"; import { useMessageStore } from "../../../core/stores/messageStore/index.ts"; -export const BLE = ({ setConnectionInProgress, closeDialog }: TabElementProps) => { +export const BLE = ( + { setConnectionInProgress, closeDialog }: TabElementProps, +) => { const [bleDevices, setBleDevices] = useState([]); const { addDevice } = useDeviceStore(); - const messageStore = useMessageStore() + const messageStore = useMessageStore(); const { setSelectedDevice } = useAppStore(); const updateBleDeviceList = useCallback(async (): Promise => { @@ -59,8 +61,6 @@ export const BLE = ({ setConnectionInProgress, closeDialog }: TabElementProps) =
); -}; \ No newline at end of file +}; diff --git a/src/components/PageComponents/Connect/HTTP.test.tsx b/src/components/PageComponents/Connect/HTTP.test.tsx index 244b71e2..6ae11735 100644 --- a/src/components/PageComponents/Connect/HTTP.test.tsx +++ b/src/components/PageComponents/Connect/HTTP.test.tsx @@ -1,15 +1,17 @@ -import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { HTTP } from "@components/PageComponents/Connect/HTTP.tsx"; import { MeshDevice } from "@meshtastic/core"; import { TransportHTTP } from "@meshtastic/transport-http"; -import { vi, describe, it, expect } from "vitest"; +import { describe, expect, it, vi } from "vitest"; vi.mock("@core/stores/appStore.ts", () => ({ useAppStore: vi.fn(() => ({ setSelectedDevice: vi.fn() })), })); vi.mock("@core/stores/deviceStore.ts", () => ({ - useDeviceStore: vi.fn(() => ({ addDevice: vi.fn(() => ({ addConnection: vi.fn() })) })), + useDeviceStore: vi.fn(() => ({ + addDevice: vi.fn(() => ({ addConnection: vi.fn() })), + })), })); vi.mock("@core/utils/randId.ts", () => ({ @@ -28,13 +30,13 @@ vi.mock("@meshtastic/core", () => ({ })), })); - describe("HTTP Component", () => { it("renders correctly", () => { render(); expect(screen.getByText("IP Address/Hostname")).toBeInTheDocument(); expect(screen.getByRole("textbox")).toBeInTheDocument(); - expect(screen.getByPlaceholderText("000.000.000.000 / meshtastic.local")).toBeInTheDocument(); + expect(screen.getByPlaceholderText("000.000.000.000 / meshtastic.local")) + .toBeInTheDocument(); expect(screen.getByText("Use HTTPS")).toBeInTheDocument(); expect(screen.getByRole("button", { name: "Connect" })).toBeInTheDocument(); }); @@ -42,8 +44,9 @@ describe("HTTP Component", () => { it("allows input field to be updated", () => { render(); const inputField = screen.getByRole("textbox"); - fireEvent.change(inputField, { target: { value: 'meshtastic.local' } }) - expect(screen.getByPlaceholderText("000.000.000.000 / meshtastic.local")).toBeInTheDocument(); + fireEvent.change(inputField, { target: { value: "meshtastic.local" } }); + expect(screen.getByPlaceholderText("000.000.000.000 / meshtastic.local")) + .toBeInTheDocument(); }); it("toggles HTTPS switch and updates prefix", () => { @@ -52,10 +55,10 @@ describe("HTTP Component", () => { const switchInput = screen.getByRole("switch"); expect(screen.getByText("http://")).toBeInTheDocument(); - fireEvent.click(switchInput) + fireEvent.click(switchInput); expect(screen.getByText("https://")).toBeInTheDocument(); - fireEvent.click(switchInput) + fireEvent.click(switchInput); expect(switchInput).not.toBeChecked(); expect(screen.getByText("http://")).toBeInTheDocument(); }); @@ -89,8 +92,7 @@ describe("HTTP Component", () => { expect(MeshDevice).toBeCalled(); }); } catch (e) { - console.error(e) + console.error(e); } }); }); - diff --git a/src/components/PageComponents/Connect/HTTP.tsx b/src/components/PageComponents/Connect/HTTP.tsx index c50c94b5..9d62462c 100644 --- a/src/components/PageComponents/Connect/HTTP.tsx +++ b/src/components/PageComponents/Connect/HTTP.tsx @@ -11,7 +11,7 @@ import { randId } from "@core/utils/randId.ts"; import { MeshDevice } from "@meshtastic/core"; import { TransportHTTP } from "@meshtastic/transport-http"; import { useState } from "react"; -import { useForm, useController } from "react-hook-form"; +import { useController, useForm } from "react-hook-form"; import { AlertTriangle } from "lucide-react"; import { useMessageStore } from "../../../core/stores/messageStore/index.ts"; @@ -20,7 +20,10 @@ interface FormData { tls: boolean; } -export const HTTP = ({ closeDialog, setConnectionInProgress, connectionInProgress }: TabElementProps) => { +export const HTTP = ( + { closeDialog, setConnectionInProgress, connectionInProgress }: + TabElementProps, +) => { const isURLHTTPS = location.protocol === "https:"; const { addDevice } = useDeviceStore(); @@ -30,8 +33,8 @@ export const HTTP = ({ closeDialog, setConnectionInProgress, connectionInProgres const { control, handleSubmit, register } = useForm({ defaultValues: { ip: ["client.meshtastic.org", "localhost"].includes( - globalThis.location.hostname, - ) + globalThis.location.hostname, + ) ? "meshtastic.local" : globalThis.location.host, tls: isURLHTTPS ? true : false, @@ -42,7 +45,9 @@ export const HTTP = ({ closeDialog, setConnectionInProgress, connectionInProgres field: { value: tlsValue, onChange: setTLS }, } = useController({ name: "tls", control }); - const [connectionError, setConnectionError] = useState<{ host: string; secure: boolean } | null>(null); + const [connectionError, setConnectionError] = useState< + { host: string; secure: boolean } | null + >(null); const onSubmit = handleSubmit(async (data) => { setConnectionInProgress(true); @@ -91,21 +96,31 @@ export const HTTP = ({ closeDialog, setConnectionInProgress, connectionInProgres {connectionError && (
- +

Connection Failed

- Could not connect to the device. {connectionError.secure && "If using HTTPS, you may need to accept a self-signed certificate first. "} + Could not connect to the device. {connectionError.secure && + "If using HTTPS, you may need to accept a self-signed certificate first. "} Please open{" "} - {`${connectionError.secure ? "https" : "http"}://${connectionError.host}`} + {`${ + connectionError.secure ? "https" : "http" + }://${connectionError.host}`} {" "} - in a new tab{connectionError.secure ? ", accept any TLS warnings if prompted, then try again" : ""}.{" "} + in a new tab{connectionError.secure + ? ", accept any TLS warnings if prompted, then try again" + : ""}.{" "} ); -}; \ No newline at end of file +}; diff --git a/src/components/PageComponents/Connect/Serial.tsx b/src/components/PageComponents/Connect/Serial.tsx index b9cd7dd5..abb490c4 100644 --- a/src/components/PageComponents/Connect/Serial.tsx +++ b/src/components/PageComponents/Connect/Serial.tsx @@ -10,10 +10,12 @@ import { TransportWebSerial } from "@meshtastic/transport-web-serial"; import { useCallback, useEffect, useState } from "react"; import { useMessageStore } from "../../../core/stores/messageStore/index.ts"; -export const Serial = ({ setConnectionInProgress, closeDialog }: TabElementProps) => { +export const Serial = ( + { setConnectionInProgress, closeDialog }: TabElementProps, +) => { const [serialPorts, setSerialPorts] = useState([]); const { addDevice } = useDeviceStore(); - const messageStore = useMessageStore() + const messageStore = useMessageStore(); const { setSelectedDevice } = useAppStore(); const updateSerialPortList = useCallback(async () => { @@ -58,8 +60,9 @@ export const Serial = ({ setConnectionInProgress, closeDialog }: TabElementProps await onConnect(port); }} > - {`# ${index} - ${usbVendorId ?? "UNK"} - ${usbProductId ?? "UNK" - }`} + {`# ${index} - ${usbVendorId ?? "UNK"} - ${ + usbProductId ?? "UNK" + }`} ); })} diff --git a/src/components/PageComponents/Map/NodeDetail.tsx b/src/components/PageComponents/Map/NodeDetail.tsx index aa260e3d..91efd128 100644 --- a/src/components/PageComponents/Map/NodeDetail.tsx +++ b/src/components/PageComponents/Map/NodeDetail.tsx @@ -23,7 +23,10 @@ import { TooltipTrigger, } from "@radix-ui/react-tooltip"; import { useDevice } from "@core/stores/deviceStore.ts"; -import { MessageType, useMessageStore } from "../../../core/stores/messageStore/index.ts"; +import { + MessageType, + useMessageStore, +} from "../../../core/stores/messageStore/index.ts"; import BatteryStatus from "@components/BatteryStatus.tsx"; export interface NodeDetailProps { @@ -51,10 +54,12 @@ export const NodeDetail = ({ node }: NodeDetailProps) => {

-
{ - // Required to prevent DM tooltip auto-appearing on creation - e.stopPropagation(); - }}> +
{ + // Required to prevent DM tooltip auto-appearing on creation + e.stopPropagation(); + }} + > {node.user?.publicKey && node.user?.publicKey.length > 0 ? ( { {!!node.deviceMetrics?.airUtilTx && (
Airtime Util
- {node.deviceMetrics?.airUtilTx.toPrecision(3)}% + + {node.deviceMetrics?.airUtilTx.toPrecision(3)}% +
)}
diff --git a/src/components/PageComponents/Messages/ChannelChat.tsx b/src/components/PageComponents/Messages/ChannelChat.tsx index 51bbd4db..dde43126 100644 --- a/src/components/PageComponents/Messages/ChannelChat.tsx +++ b/src/components/PageComponents/Messages/ChannelChat.tsx @@ -19,7 +19,7 @@ export const ChannelChat = ({ messages = [] }: ChannelChatProps) => { const scrollContainerRef = useRef(null); const userScrolledUpRef = useRef(false); - const scrollToBottom = useCallback((behavior: ScrollBehavior = 'smooth') => { + const scrollToBottom = useCallback((behavior: ScrollBehavior = "smooth") => { requestAnimationFrame(() => { messagesEndRef.current?.scrollIntoView({ behavior }); }); @@ -28,10 +28,12 @@ export const ChannelChat = ({ messages = [] }: ChannelChatProps) => { useEffect(() => { const scrollContainer = scrollContainerRef.current; if (!scrollContainer) return; - const isScrolledToBottom = scrollContainer.scrollHeight - scrollContainer.scrollTop - scrollContainer.clientHeight <= 10; + const isScrolledToBottom = + scrollContainer.scrollHeight - scrollContainer.scrollTop - + scrollContainer.clientHeight <= 10; if (isScrolledToBottom || !userScrolledUpRef.current) { - scrollToBottom('smooth'); + scrollToBottom("smooth"); } }, [messages, scrollToBottom]); @@ -39,12 +41,16 @@ export const ChannelChat = ({ messages = [] }: ChannelChatProps) => { const scrollContainer = scrollContainerRef.current; const handleScroll = () => { if (!scrollContainer) return; - const isAtBottom = scrollContainer.scrollHeight - scrollContainer.scrollTop - scrollContainer.clientHeight <= 10; + const isAtBottom = + scrollContainer.scrollHeight - scrollContainer.scrollTop - + scrollContainer.clientHeight <= 10; userScrolledUpRef.current = !isAtBottom; }; - scrollContainer?.addEventListener('scroll', handleScroll, { passive: true }); + scrollContainer?.addEventListener("scroll", handleScroll, { + passive: true, + }); return () => { - scrollContainer?.removeEventListener('scroll', handleScroll); + scrollContainer?.removeEventListener("scroll", handleScroll); }; }, []); @@ -74,4 +80,4 @@ export const ChannelChat = ({ messages = [] }: ChannelChatProps) => {
); -}; \ No newline at end of file +}; diff --git a/src/components/PageComponents/Messages/MessageActionsMenu.tsx b/src/components/PageComponents/Messages/MessageActionsMenu.tsx index 9f575798..777128aa 100644 --- a/src/components/PageComponents/Messages/MessageActionsMenu.tsx +++ b/src/components/PageComponents/Messages/MessageActionsMenu.tsx @@ -6,7 +6,7 @@ import { TooltipTrigger, } from "@components/UI/Tooltip.tsx"; import { cn } from "@core/utils/cn.ts"; -import { SmilePlus, Reply } from "lucide-react"; +import { Reply, SmilePlus } from "lucide-react"; interface MessageActionsMenuProps { onAddReaction?: () => void; @@ -15,7 +15,7 @@ interface MessageActionsMenuProps { export const MessageActionsMenu = ({ onAddReaction, - onReply + onReply, }: MessageActionsMenuProps) => { const hoverIconBarClass = cn( "absolute top-2 right-2", @@ -25,7 +25,7 @@ export const MessageActionsMenu = ({ "rounded-md shadow-sm p-1", "opacity-0 group-hover:opacity-100", "transition-opacity duration-100 ease-in-out", - "z-10" + "z-10", ); const hoverIconButtonClass = cn( @@ -33,13 +33,16 @@ export const MessageActionsMenu = ({ "text-gray-500 dark:text-gray-400", "hover:text-gray-700 dark:hover:text-gray-300", "hover:bg-gray-100 dark:hover:bg-zinc-700", - "cursor-pointer" + "cursor-pointer", ); const iconSizeClass = "size-4"; return ( -
e.stopPropagation()}> +
e.stopPropagation()} + > @@ -47,7 +50,7 @@ export const MessageActionsMenu = ({ type="button" aria-label="Add Reaction" onClick={(e) => { - e.stopPropagation() + e.stopPropagation(); if (onAddReaction) { onAddReaction(); } @@ -69,7 +72,7 @@ export const MessageActionsMenu = ({ type="button" aria-label="Reply" onClick={(e) => { - e.stopPropagation() + e.stopPropagation(); if (onReply) { onReply(); } @@ -85,7 +88,6 @@ export const MessageActionsMenu = ({ -
); -}; \ No newline at end of file +}; diff --git a/src/components/PageComponents/Messages/MessageInput.test.tsx b/src/components/PageComponents/Messages/MessageInput.test.tsx index 97eb7542..2c88c1cc 100644 --- a/src/components/PageComponents/Messages/MessageInput.test.tsx +++ b/src/components/PageComponents/Messages/MessageInput.test.tsx @@ -1,18 +1,34 @@ -import { render, screen, fireEvent, waitFor, act } from '@testing-library/react'; -import { vi, describe, it, expect, beforeEach } from 'vitest'; -import { MessageInput, MessageInputProps } from './MessageInput.tsx'; -import { Types } from '@meshtastic/core'; - -vi.mock('@components/UI/Button.tsx', () => ({ - Button: vi.fn(({ type, className, children, onClick, onSubmit, variant, ...rest }) => ( - )), })); -vi.mock('@components/UI/Input.tsx', () => ({ - Input: vi.fn(({ autoFocus, minLength, name, placeholder, value, onChange }) => ( +vi.mock("@components/UI/Input.tsx", () => ({ + Input: vi.fn(( + { autoFocus, minLength, name, placeholder, value, onChange }, + ) => ( ({ +vi.mock("@core/stores/messageStore", () => ({ useMessageStore: vi.fn(() => ({ setDraft: mockSetDraft, getDraft: mockGetDraft, clearDraft: mockClearDraft, })), MessageState: { - Ack: 'ack', - Waiting: 'waiting', - Failed: 'failed', + Ack: "ack", + Waiting: "waiting", + Failed: "failed", }, MessageType: { - Direct: 'direct', - Broadcast: 'broadcast', + Direct: "direct", + Broadcast: "broadcast", }, })); -vi.mock('lucide-react', () => ({ +vi.mock("lucide-react", () => ({ SendIcon: vi.fn(() => ), })); -describe('MessageInput', () => { +describe("MessageInput", () => { const mockOnSend = vi.fn(); const defaultProps: MessageInputProps = { onSend: mockOnSend, @@ -61,56 +77,62 @@ describe('MessageInput', () => { beforeEach(() => { vi.clearAllMocks(); - mockGetDraft.mockReturnValue(''); + mockGetDraft.mockReturnValue(""); }); const renderComponent = (props: Partial = {}) => { render(); }; - it('should render the input field, byte counter, and send button', () => { + it("should render the input field, byte counter, and send button", () => { renderComponent(); - expect(screen.getByPlaceholderText('Enter Message')).toBeInTheDocument(); - expect(screen.getByTestId('byte-counter')).toBeInTheDocument(); - expect(screen.getByRole('button')).toBeInTheDocument(); - expect(screen.getByTestId('send-icon')).toBeInTheDocument(); + expect(screen.getByPlaceholderText("Enter Message")).toBeInTheDocument(); + expect(screen.getByTestId("byte-counter")).toBeInTheDocument(); + expect(screen.getByRole("button")).toBeInTheDocument(); + expect(screen.getByTestId("send-icon")).toBeInTheDocument(); }); - it('should initialize with the draft from the store', () => { - const initialDraft = 'Existing draft message'; + it("should initialize with the draft from the store", () => { + const initialDraft = "Existing draft message"; mockGetDraft.mockImplementation((key) => { - return key === defaultProps.to ? initialDraft : ''; + return key === defaultProps.to ? initialDraft : ""; }); renderComponent(); - const inputElement = screen.getByPlaceholderText('Enter Message') as HTMLInputElement; + const inputElement = screen.getByPlaceholderText( + "Enter Message", + ) as HTMLInputElement; expect(inputElement.value).toBe(initialDraft); expect(mockGetDraft).toHaveBeenCalledWith(defaultProps.to); const expectedBytes = new Blob([initialDraft]).size; - expect(screen.getByTestId('byte-counter')).toHaveTextContent(`${expectedBytes}/${defaultProps.maxBytes}`); + expect(screen.getByTestId("byte-counter")).toHaveTextContent( + `${expectedBytes}/${defaultProps.maxBytes}`, + ); }); - it('should update input value, byte counter, and call setDraft on change within limits', () => { + it("should update input value, byte counter, and call setDraft on change within limits", () => { renderComponent(); - const inputElement = screen.getByPlaceholderText('Enter Message'); - const testMessage = 'Hello there!'; + const inputElement = screen.getByPlaceholderText("Enter Message"); + const testMessage = "Hello there!"; const expectedBytes = new Blob([testMessage]).size; fireEvent.change(inputElement, { target: { value: testMessage } }); expect((inputElement as HTMLInputElement).value).toBe(testMessage); - expect(screen.getByTestId('byte-counter')).toHaveTextContent(`${expectedBytes}/${defaultProps.maxBytes}`); + expect(screen.getByTestId("byte-counter")).toHaveTextContent( + `${expectedBytes}/${defaultProps.maxBytes}`, + ); expect(mockSetDraft).toHaveBeenCalledTimes(1); expect(mockSetDraft).toHaveBeenCalledWith(defaultProps.to, testMessage); }); - it('should NOT update input value or call setDraft if maxBytes is exceeded', () => { + it("should NOT update input value or call setDraft if maxBytes is exceeded", () => { const smallMaxBytes = 5; renderComponent({ maxBytes: smallMaxBytes }); - const inputElement = screen.getByPlaceholderText('Enter Message'); - const initialValue = '12345'; - const excessiveValue = '123456'; + const inputElement = screen.getByPlaceholderText("Enter Message"); + const initialValue = "12345"; + const excessiveValue = "123456"; fireEvent.change(inputElement, { target: { value: initialValue } }); expect((inputElement as HTMLInputElement).value).toBe(initialValue); @@ -120,15 +142,17 @@ describe('MessageInput', () => { fireEvent.change(inputElement, { target: { value: excessiveValue } }); expect((inputElement as HTMLInputElement).value).toBe(initialValue); - expect(screen.getByTestId('byte-counter')).toHaveTextContent(`${smallMaxBytes}/${smallMaxBytes}`); + expect(screen.getByTestId("byte-counter")).toHaveTextContent( + `${smallMaxBytes}/${smallMaxBytes}`, + ); expect(mockSetDraft).not.toHaveBeenCalled(); }); - it('should call onSend, clear input, reset byte counter, and call clearDraft on valid submit', async () => { + it("should call onSend, clear input, reset byte counter, and call clearDraft on valid submit", async () => { renderComponent(); - const inputElement = screen.getByPlaceholderText('Enter Message'); - const formElement = screen.getByRole('form'); - const testMessage = 'Send this message'; + const inputElement = screen.getByPlaceholderText("Enter Message"); + const formElement = screen.getByRole("form"); + const testMessage = "Send this message"; fireEvent.change(inputElement, { target: { value: testMessage } }); fireEvent.submit(formElement); @@ -136,21 +160,25 @@ describe('MessageInput', () => { await waitFor(() => { expect(mockOnSend).toHaveBeenCalledTimes(1); expect(mockOnSend).toHaveBeenCalledWith(testMessage); - expect((inputElement as HTMLInputElement).value).toBe(''); - expect(screen.getByTestId('byte-counter')).toHaveTextContent(`0/${defaultProps.maxBytes}`); + expect((inputElement as HTMLInputElement).value).toBe(""); + expect(screen.getByTestId("byte-counter")).toHaveTextContent( + `0/${defaultProps.maxBytes}`, + ); expect(mockClearDraft).toHaveBeenCalledTimes(1); expect(mockClearDraft).toHaveBeenCalledWith(defaultProps.to); }); }); - it('should trim whitespace before calling onSend', async () => { + it("should trim whitespace before calling onSend", async () => { renderComponent(); - const inputElement = screen.getByPlaceholderText('Enter Message'); - const formElement = screen.getByRole('form'); - const testMessageWithWhitespace = ' Trim me! '; - const expectedTrimmedMessage = 'Trim me!'; + const inputElement = screen.getByPlaceholderText("Enter Message"); + const formElement = screen.getByRole("form"); + const testMessageWithWhitespace = " Trim me! "; + const expectedTrimmedMessage = "Trim me!"; - fireEvent.change(inputElement, { target: { value: testMessageWithWhitespace } }); + fireEvent.change(inputElement, { + target: { value: testMessageWithWhitespace }, + }); fireEvent.submit(formElement); await waitFor(() => { @@ -160,28 +188,28 @@ describe('MessageInput', () => { }); }); - it('should not call onSend or clearDraft if input is empty on submit', async () => { + it("should not call onSend or clearDraft if input is empty on submit", async () => { renderComponent(); - const inputElement = screen.getByPlaceholderText('Enter Message'); - const formElement = screen.getByRole('form'); + const inputElement = screen.getByPlaceholderText("Enter Message"); + const formElement = screen.getByRole("form"); - expect((inputElement as HTMLInputElement).value).toBe(''); + expect((inputElement as HTMLInputElement).value).toBe(""); fireEvent.submit(formElement); await act(async () => { - await new Promise(resolve => setTimeout(resolve, 50)); + await new Promise((resolve) => setTimeout(resolve, 50)); }); expect(mockOnSend).not.toHaveBeenCalled(); expect(mockClearDraft).not.toHaveBeenCalled(); }); - it('should not call onSend or clearDraft if input contains only whitespace on submit', async () => { + it("should not call onSend or clearDraft if input contains only whitespace on submit", async () => { renderComponent(); - const inputElement = screen.getByTestId('message-input-field'); - const formElement = screen.getByRole('form'); - const whitespaceMessage = ' \t '; + const inputElement = screen.getByTestId("message-input-field"); + const formElement = screen.getByRole("form"); + const whitespaceMessage = " \t "; fireEvent.change(inputElement, { target: { value: whitespaceMessage } }); expect((inputElement as HTMLInputElement).value).toBe(whitespaceMessage); @@ -189,7 +217,7 @@ describe('MessageInput', () => { fireEvent.submit(formElement); await act(async () => { - await new Promise(resolve => setTimeout(resolve, 50)); + await new Promise((resolve) => setTimeout(resolve, 50)); }); expect(mockOnSend).not.toHaveBeenCalled(); @@ -198,18 +226,22 @@ describe('MessageInput', () => { expect((inputElement as HTMLInputElement).value).toBe(whitespaceMessage); }); - it('should work with broadcast destination for drafts', () => { - const broadcastDest: Types.Destination = 'broadcast'; - mockGetDraft.mockImplementation((key) => key === broadcastDest ? 'Broadcast draft' : ''); + it("should work with broadcast destination for drafts", () => { + const broadcastDest: Types.Destination = "broadcast"; + mockGetDraft.mockImplementation((key) => + key === broadcastDest ? "Broadcast draft" : "" + ); renderComponent({ to: broadcastDest }); expect(mockGetDraft).toHaveBeenCalledWith(broadcastDest); - expect((screen.getByPlaceholderText('Enter Message') as HTMLInputElement).value).toBe('Broadcast draft'); + expect( + (screen.getByPlaceholderText("Enter Message") as HTMLInputElement).value, + ).toBe("Broadcast draft"); - const inputElement = screen.getByPlaceholderText('Enter Message'); - const formElement = screen.getByRole('form'); - const newMessage = 'New broadcast msg'; + const inputElement = screen.getByPlaceholderText("Enter Message"); + const formElement = screen.getByRole("form"); + const newMessage = "New broadcast msg"; fireEvent.change(inputElement, { target: { value: newMessage } }); expect(mockSetDraft).toHaveBeenCalledWith(broadcastDest, newMessage); @@ -219,4 +251,4 @@ describe('MessageInput', () => { expect(mockOnSend).toHaveBeenCalledWith(newMessage); expect(mockClearDraft).toHaveBeenCalledWith(broadcastDest); }); -}); \ No newline at end of file +}); diff --git a/src/components/PageComponents/Messages/MessageInput.tsx b/src/components/PageComponents/Messages/MessageInput.tsx index c229d8aa..9505a8d4 100644 --- a/src/components/PageComponents/Messages/MessageInput.tsx +++ b/src/components/PageComponents/Messages/MessageInput.tsx @@ -22,7 +22,9 @@ export const MessageInput = ({ const initialDraft = getDraft(to); const [localDraft, setLocalDraft] = useState(initialDraft); - const [messageBytes, setMessageBytes] = useState(() => calculateBytes(initialDraft)); + const [messageBytes, setMessageBytes] = useState(() => + calculateBytes(initialDraft) + ); const handleInputChange = (e: React.ChangeEvent) => { const newValue = e.target.value; @@ -63,7 +65,10 @@ export const MessageInput = ({ /> -
); -}; \ No newline at end of file +}; diff --git a/src/components/PageComponents/Messages/MessageItem.tsx b/src/components/PageComponents/Messages/MessageItem.tsx index ff696007..d90579e8 100644 --- a/src/components/PageComponents/Messages/MessageItem.tsx +++ b/src/components/PageComponents/Messages/MessageItem.tsx @@ -11,7 +11,10 @@ import { Avatar } from "@components/UI/Avatar.tsx"; import { AlertCircle, CheckCircle2, CircleEllipsis } from "lucide-react"; import type { LucideIcon } from "lucide-react"; import { ReactNode, useMemo } from "react"; -import { MessageState, useMessageStore } from "@core/stores/messageStore/index.ts"; +import { + MessageState, + useMessageStore, +} from "@core/stores/messageStore/index.ts"; import { Protobuf, Types } from "@meshtastic/js"; import { Message } from "@core/stores/messageStore/types.ts"; // import { MessageActionsMenu } from "@components/PageComponents/Messages/MessageActionsMenu.tsx"; // Uncomment if needed later @@ -24,17 +27,42 @@ interface MessageStatusInfo { } const MESSAGE_STATUS_MAP: Record = { - [MessageState.Ack]: { displayText: "Message delivered", icon: CheckCircle2, ariaLabel: "Message delivered", iconClassName: "text-green-500" }, - [MessageState.Waiting]: { displayText: "Waiting for delivery", icon: CircleEllipsis, ariaLabel: "Sending message", iconClassName: "text-slate-400" }, - [MessageState.Failed]: { displayText: "Delivery failed", icon: AlertCircle, ariaLabel: "Message delivery failed", iconClassName: "text-red-500 dark:text-red-400" }, + [MessageState.Ack]: { + displayText: "Message delivered", + icon: CheckCircle2, + ariaLabel: "Message delivered", + iconClassName: "text-green-500", + }, + [MessageState.Waiting]: { + displayText: "Waiting for delivery", + icon: CircleEllipsis, + ariaLabel: "Sending message", + iconClassName: "text-slate-400", + }, + [MessageState.Failed]: { + displayText: "Delivery failed", + icon: AlertCircle, + ariaLabel: "Message delivery failed", + iconClassName: "text-red-500 dark:text-red-400", + }, }; -const UNKNOWN_STATUS: MessageStatusInfo = { displayText: "Unknown state", icon: AlertCircle, ariaLabel: "Message status unknown", iconClassName: "text-red-500 dark:text-red-400" }; +const UNKNOWN_STATUS: MessageStatusInfo = { + displayText: "Unknown state", + icon: AlertCircle, + ariaLabel: "Message status unknown", + iconClassName: "text-red-500 dark:text-red-400", +}; const getMessageStatusInfo = (state: MessageState): MessageStatusInfo => MESSAGE_STATUS_MAP[state] ?? UNKNOWN_STATUS; -const StatusTooltip = ({ statusInfo, children }: { statusInfo: MessageStatusInfo; children: ReactNode }) => ( +const StatusTooltip = ( + { statusInfo, children }: { + statusInfo: MessageStatusInfo; + children: ReactNode; + }, +) => ( {children} @@ -52,18 +80,17 @@ interface MessageItemProps { export const MessageItem = ({ message }: MessageItemProps) => { const { getNode } = useDevice(); - const { getMyNodeNum } = useMessageStore() + const { getMyNodeNum } = useMessageStore(); const messageUser: Protobuf.Mesh.NodeInfo | null | undefined = useMemo(() => { return message.from != null ? getNode(message.from) : null; }, [getNode, message.from]); - const myNodeNum = useMemo(() => getMyNodeNum(), [getMyNodeNum]); const { displayName, shortName } = useMemo(() => { - const userIdHex = message.from.toString(16).toUpperCase().padStart(2, '0'); + const userIdHex = message.from.toString(16).toUpperCase().padStart(2, "0"); const last4 = userIdHex.slice(-4); - const fallbackName = `Meshtastic ${last4}` + const fallbackName = `Meshtastic ${last4}`; const longName = messageUser?.user?.longName; const derivedShortName = messageUser?.user?.shortName || fallbackName; const derivedDisplayName = longName || derivedShortName; @@ -73,22 +100,35 @@ export const MessageItem = ({ message }: MessageItemProps) => { const messageStatusInfo = getMessageStatusInfo(message.state); const StatusIconComponent = messageStatusInfo.icon; - const messageDate = useMemo(() => message.date ? new Date(message.date) : null, [message.date]); - const locale = 'en-US'; // TODO: Make dynamic via props or context - - const formattedTime = useMemo(() => - messageDate?.toLocaleTimeString(locale, { hour: 'numeric', minute: '2-digit', hour12: true }) ?? '', - [messageDate, locale]); + const messageDate = useMemo( + () => message.date ? new Date(message.date) : null, + [message.date], + ); + const locale = "en-US"; // TODO: Make dynamic via props or context + + const formattedTime = useMemo( + () => + messageDate?.toLocaleTimeString(locale, { + hour: "numeric", + minute: "2-digit", + hour12: true, + }) ?? "", + [messageDate, locale], + ); - const fullDateTime = useMemo(() => - messageDate?.toLocaleString(locale, { dateStyle: 'medium', timeStyle: 'short' }) ?? '', - [messageDate, locale]); + const fullDateTime = useMemo( + () => + messageDate?.toLocaleString(locale, { + dateStyle: "medium", + timeStyle: "short", + }) ?? "", + [messageDate, locale], + ); const isSender = myNodeNum !== undefined && message.from === myNodeNum; const isOnPrimaryChannel = message.channel === Types.ChannelNumber.Primary; // Use the enum const shouldShowStatusIcon = isSender && isOnPrimaryChannel; - const messageItemWrapperClass = cn( "group w-full py-2 relative list-none", "rounded-md", @@ -97,7 +137,6 @@ export const MessageItem = ({ message }: MessageItemProps) => { ); const dateTextStyle = "text-xs text-slate-500 dark:text-slate-400"; - return (
  • @@ -109,7 +148,10 @@ export const MessageItem = ({ message }: MessageItemProps) => { {displayName} {messageDate && ( -
  • {/* Actions Menu Placeholder */} - {/*
    + { + /*
    console.log("Reply")} /> -
    */} +
    */ + } ); -}; \ No newline at end of file +}; diff --git a/src/components/PageComponents/Messages/TraceRoute.test.tsx b/src/components/PageComponents/Messages/TraceRoute.test.tsx index 39443acb..c3b8591c 100644 --- a/src/components/PageComponents/Messages/TraceRoute.test.tsx +++ b/src/components/PageComponents/Messages/TraceRoute.test.tsx @@ -1,4 +1,4 @@ -import { describe, it, expect, vi, beforeEach } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { render, screen } from "@testing-library/react"; import { TraceRoute } from "@components/PageComponents/Messages/TraceRoute.tsx"; import { useDevice } from "@core/stores/deviceStore.ts"; @@ -34,11 +34,11 @@ describe("TraceRoute", () => { it("renders the route to destination with SNR values", () => { render( + />, ); expect(screen.getAllByText("Source Node")).toHaveLength(1); @@ -56,13 +56,13 @@ describe("TraceRoute", () => { it("renders the route back when provided", () => { render( + />, ); expect(screen.getByText("Route back:")).toBeInTheDocument(); @@ -79,16 +79,15 @@ describe("TraceRoute", () => { expect(screen.getByText("↓ 15dB")).toBeInTheDocument(); expect(screen.getByText("↓ 25dB")).toBeInTheDocument(); - }); it("renders '??' for missing SNR values", () => { render( + />, ); expect(screen.getByText("Node A")).toBeInTheDocument(); @@ -102,11 +101,11 @@ describe("TraceRoute", () => { to={{ user: { longName: "Dest" } } as unknown} route={[99]} snrTowards={[5, 15]} - /> + />, ); expect(screen.getByText(/^!63$/)).toBeInTheDocument(); expect(screen.getByText("↓ 5dB")).toBeInTheDocument(); expect(screen.getByText("↓ 15dB")).toBeInTheDocument(); }); -}); \ No newline at end of file +}); diff --git a/src/components/PageComponents/Messages/TraceRoute.tsx b/src/components/PageComponents/Messages/TraceRoute.tsx index e67baacc..21cb4eba 100644 --- a/src/components/PageComponents/Messages/TraceRoute.tsx +++ b/src/components/PageComponents/Messages/TraceRoute.tsx @@ -19,17 +19,24 @@ interface RoutePathProps { snr?: number[]; } -const RoutePath = ({ title, startNode, endNode, path, snr }: RoutePathProps) => { +const RoutePath = ( + { title, startNode, endNode, path, snr }: RoutePathProps, +) => { const { getNode } = useDevice(); return ( - +

    {title}

    {startNode?.user?.longName}

    ↓ {snr?.[0] ?? "??"}dB

    {path.map((hop, i) => ( -

    {getNode(hop)?.user?.longName ?? `!${numberToHexUnpadded(hop)}`}

    +

    + {getNode(hop)?.user?.longName ?? `!${numberToHexUnpadded(hop)}`} +

    ↓ {snr?.[i + 1] ?? "??"}dB

    ))} diff --git a/src/components/PageLayout.tsx b/src/components/PageLayout.tsx index 40ae524e..5d2d9167 100644 --- a/src/components/PageLayout.tsx +++ b/src/components/PageLayout.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React from "react"; import { cn } from "@core/utils/cn.ts"; import { type LucideIcon } from "lucide-react"; import Footer from "@components/UI/Footer.tsx"; @@ -39,7 +39,7 @@ export const PageLayout = ({ leftBarClassName, rightBarClassName, topBarClassName, - contentClassName + contentClassName, }: PageLayoutProps) => { return ( @@ -49,7 +49,7 @@ export const PageLayout = ({
    ); -}; \ No newline at end of file +}; diff --git a/src/components/UI/Button.tsx b/src/components/UI/Button.tsx index 4aa95488..ef5ab101 100644 --- a/src/components/UI/Button.tsx +++ b/src/components/UI/Button.tsx @@ -39,8 +39,9 @@ const buttonVariants = cva( export type ButtonVariant = VariantProps["variant"]; export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { + extends + React.ButtonHTMLAttributes, + VariantProps { icon?: React.ReactNode; iconAlignment?: "left" | "right"; } @@ -65,7 +66,7 @@ const Button = React.forwardRef( className={cn( buttonVariants({ variant, size, className }), { "cursor-not-allowed": disabled }, - "inline-flex items-center" + "inline-flex items-center", )} ref={ref} disabled={disabled} @@ -85,4 +86,4 @@ const Button = React.forwardRef( ); Button.displayName = "Button"; -export { Button, buttonVariants }; \ No newline at end of file +export { Button, buttonVariants }; diff --git a/src/components/UI/Checkbox/Checkbox.test.tsx b/src/components/UI/Checkbox/Checkbox.test.tsx index 4b909f2c..7e5ba73d 100644 --- a/src/components/UI/Checkbox/Checkbox.test.tsx +++ b/src/components/UI/Checkbox/Checkbox.test.tsx @@ -1,113 +1,130 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { render, screen, fireEvent, cleanup } from '@testing-library/react'; -import { Checkbox } from '@components/UI/Checkbox/index.tsx'; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { cleanup, fireEvent, render, screen } from "@testing-library/react"; +import { Checkbox } from "@components/UI/Checkbox/index.tsx"; import React from "react"; -vi.mock('@components/UI/Label.tsx', () => ({ - Label: ({ children, className, htmlFor, id }: { children: React.ReactNode; className: string; htmlFor: string; id: string }) => ( -