├── src ├── vite-env.d.ts ├── assets │ ├── demo.png │ ├── sources │ │ ├── window.svg │ │ ├── brush.svg │ │ ├── media.svg │ │ ├── default.svg │ │ ├── camera.svg │ │ ├── image.svg │ │ ├── microphone.svg │ │ ├── slideshow.svg │ │ ├── scene.svg │ │ ├── text.svg │ │ ├── gamepad.svg │ │ ├── group.svg │ │ ├── globe.svg │ │ └── windowaudio.svg │ └── react.svg ├── main.tsx ├── components │ ├── Preview.tsx │ ├── RecordButton.css │ ├── Sources.tsx │ ├── OutputList.css │ ├── ConnectionStringInput.css │ ├── StatusBar.css │ ├── Scene.tsx │ ├── OBSDebugger.css │ ├── OBSDebugger.tsx │ ├── OutputList.tsx │ ├── ConnectionStringInput.tsx │ ├── Scene.css │ ├── MediaItem.tsx │ ├── StatusBar.tsx │ └── RecordButton.tsx ├── utils │ ├── sources.ts │ └── scene.ts ├── types │ └── obs.ts ├── obs.ts ├── index.css ├── App.css ├── App.tsx └── store │ └── obsStore.ts ├── vite.config.ts ├── worker └── index.ts ├── index.html ├── wrangler.jsonc ├── .gitignore ├── README.md ├── tsconfig.node.json ├── tsconfig.app.json ├── eslint.config.js ├── tsconfig.json ├── package.json ├── public └── vite.svg └── pnpm-lock.yaml /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/assets/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/source-record-ui/HEAD/src/assets/demo.png -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './index.css' 4 | import App from './App.tsx' 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | ) 9 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | import { cloudflare } from "@cloudflare/vite-plugin"; 5 | 6 | // https://vite.dev/config/ 7 | export default defineConfig({ 8 | plugins: [react(), cloudflare()], 9 | }) 10 | -------------------------------------------------------------------------------- /src/components/Preview.tsx: -------------------------------------------------------------------------------- 1 | import { useOBSStore } from "../store/obsStore"; 2 | 3 | export function Preview({ sourceName }: { sourceName: string }) { 4 | const previews = useOBSStore((state) => state.scenePreviews); 5 | return ( 6 | {`${sourceName} 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /worker/index.ts: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | fetch(request) { 4 | // tHis file only exists to throw a 404, which causes it to fallback to static file via the `"not_found_handling": "single-page-application"` setting. 5 | // I've done is so I can host a static app in a worker instead of using cloudflare pages. 6 | return new Response(null, { status: 404 }); 7 | }, 8 | } satisfies ExportedHandler; 9 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | OBS Source Record UI 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/utils/sources.ts: -------------------------------------------------------------------------------- 1 | import { Source } from "../store/obsStore"; 2 | 3 | export function uniqueSceneSources(sceneSources: Record) { 4 | const flattenedSceneSources = Object.values(sceneSources).flat(); 5 | const uniqueSceneSources = flattenedSceneSources.filter( 6 | (source, index, self) => 7 | index === self.findIndex((t) => t.sourceUuid === source.sourceUuid) 8 | ); 9 | return uniqueSceneSources; 10 | } 11 | -------------------------------------------------------------------------------- /wrangler.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/wrangler/config-schema.json", 3 | "name": "source-record-ui", 4 | "main": "worker/index.ts", 5 | "compatibility_date": "2025-06-17", 6 | "assets": { 7 | "not_found_handling": "single-page-application" 8 | }, 9 | "observability": { 10 | "enabled": true 11 | }, 12 | "routes": [ 13 | { 14 | "pattern": "obs.wesbos.com", 15 | "custom_domain": true 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/assets/sources/window.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/sources/brush.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/sources/media.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | /.pnp 4 | .pnp.js 5 | 6 | # Testing 7 | /coverage 8 | 9 | # Production 10 | /build 11 | /dist 12 | 13 | # Misc 14 | .DS_Store 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | .env 20 | 21 | # Logs 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | # Editor directories and files 27 | .idea 28 | .vscode 29 | *.suo 30 | *.ntvs* 31 | *.njsproj 32 | *.sln 33 | *.sw? 34 | 35 | # TypeScript 36 | *.tsbuildinfo 37 | 38 | # Sample 39 | my-react-app/ 40 | 41 | .wrangler 42 | -------------------------------------------------------------------------------- /src/assets/sources/default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/sources/camera.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OBS Source Record UI 2 | 3 | Available at [obs.wesbos.com](https://obs.wesbos.com) 4 | 5 | ![](./src/assets/demo.png) 6 | 7 | OBS source record is great, but the UI for adding filters makes it hard to see what you are really recording. 8 | 9 | This project aims to provide: 10 | 11 | 1. a clear UI for what you are recording - including a realtime stream of all scenes. 12 | 2. an easy way to toggle filters on and off 13 | 3. buttons to start + stop recording 14 | 4. automatic renaming of the files - they should match up to the name of the scene and not overlap others. 15 | 16 | ## Dev 17 | 18 | `npm install` then `npm run dev`. 19 | -------------------------------------------------------------------------------- /src/components/RecordButton.css: -------------------------------------------------------------------------------- 1 | .record-buttons { 2 | display: flex; 3 | gap: 0.5rem; 4 | } 5 | 6 | .record-button { 7 | padding: 0.5rem 1rem; 8 | border: none; 9 | border-radius: 4px; 10 | font-weight: 500; 11 | cursor: pointer; 12 | transition: all 0.2s; 13 | } 14 | 15 | .record-button.start { 16 | background: #f44336; 17 | color: white; 18 | } 19 | 20 | .record-button.start:hover { 21 | background: #d32f2f; 22 | } 23 | 24 | .record-button.stop { 25 | background: #333; 26 | color: white; 27 | } 28 | 29 | .record-button.stop:hover { 30 | background: #444; 31 | } 32 | 33 | .record-button:disabled { 34 | opacity: 0.5; 35 | cursor: not-allowed; 36 | } 37 | -------------------------------------------------------------------------------- /src/types/obs.ts: -------------------------------------------------------------------------------- 1 | export interface SceneItem { 2 | sceneName: string; 3 | sceneIndex: number; 4 | } 5 | 6 | export interface SceneListResponse { 7 | currentProgramSceneName: string; 8 | currentProgramSceneUuid: string; 9 | currentPreviewSceneName: string; 10 | currentPreviewSceneUuid: string; 11 | scenes: SceneItem[]; 12 | } 13 | 14 | export interface Filter { 15 | filterEnabled: boolean; 16 | filterIndex: number; 17 | filterKind: string; 18 | filterName: string; 19 | filterSettings: Record; 20 | } 21 | 22 | export interface SourceFilterListResponse { 23 | filters: Filter[]; 24 | } 25 | 26 | export interface SourceScreenshotResponse { 27 | imageData: string; 28 | imageFormat: string; 29 | } 30 | -------------------------------------------------------------------------------- /src/assets/sources/image.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "verbatimModuleSyntax": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "erasableSyntaxOnly": true, 21 | "noFallthroughCasesInSwitch": true, 22 | "noUncheckedSideEffectImports": true 23 | }, 24 | "include": ["vite.config.ts"] 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "verbatimModuleSyntax": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "erasableSyntaxOnly": true, 23 | "noFallthroughCasesInSwitch": true, 24 | "noUncheckedSideEffectImports": true 25 | }, 26 | "include": ["src"] 27 | } 28 | -------------------------------------------------------------------------------- /src/assets/sources/microphone.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true, 22 | 23 | /* Additional Options */ 24 | "esModuleInterop": true, 25 | "allowSyntheticDefaultImports": true, 26 | "forceConsistentCasingInFileNames": true, 27 | "moduleDetection": "force" 28 | }, 29 | "include": ["src"], 30 | "references": [{ "path": "./tsconfig.node.json" }] 31 | } 32 | -------------------------------------------------------------------------------- /src/components/Sources.tsx: -------------------------------------------------------------------------------- 1 | import { useOBSStore } from "../store/obsStore"; 2 | import { uniqueSceneSources } from "../utils/sources"; 3 | import { MediaItem } from "./MediaItem"; 4 | 5 | function useSceneSources() { 6 | // grab all scene sources from the store 7 | const sceneSources = useOBSStore((state) => state.sceneSources); 8 | // flatten the scene sources 9 | return uniqueSceneSources(sceneSources); 10 | } 11 | 12 | export function Sources() { 13 | const sceneSources = useSceneSources(); 14 | console.log(sceneSources); 15 | return ( 16 |
17 |

Sources

18 | {sceneSources.map((source) => ( 19 | 25 | ))} 26 |
27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /src/assets/sources/slideshow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/obs.ts: -------------------------------------------------------------------------------- 1 | import OBSWebSocket, { EventSubscription } from 'obs-websocket-js'; 2 | 3 | let obs: OBSWebSocket | null = null; 4 | let isConnected = false; 5 | let connectPromise: Promise | null = null; 6 | 7 | export function getOBS(): OBSWebSocket { 8 | if (!obs) { 9 | obs = new OBSWebSocket(); 10 | } 11 | return obs; 12 | } 13 | 14 | export async function connectOBS(connectionString: string, password?: string): Promise { 15 | if (isConnected && obs) { 16 | return obs; 17 | } 18 | if (connectPromise) { 19 | return connectPromise; 20 | } 21 | obs = getOBS(); 22 | connectPromise = obs.connect(connectionString, password, { 23 | eventSubscriptions: EventSubscription.All | EventSubscription.InputVolumeMeters, 24 | rpcVersion: 1 25 | }) 26 | .then(() => { 27 | isConnected = true; 28 | return obs!; 29 | }) 30 | .catch((err) => { 31 | isConnected = false; 32 | connectPromise = null; 33 | throw err; 34 | }); 35 | return connectPromise; 36 | } 37 | -------------------------------------------------------------------------------- /src/assets/sources/scene.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: black; 8 | background-color: white; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | a { 17 | font-weight: 500; 18 | color: #646cff; 19 | text-decoration: inherit; 20 | } 21 | a:hover { 22 | color: #535bf2; 23 | } 24 | 25 | body { 26 | margin: 0; 27 | place-items: center; 28 | min-width: 320px; 29 | min-height: 100vh; 30 | } 31 | 32 | h1 { 33 | font-size: 3.2em; 34 | line-height: 1.1; 35 | } 36 | 37 | button { 38 | border-radius: 8px; 39 | border: 1px solid transparent; 40 | padding: 0.6em 1.2em; 41 | font-size: 1em; 42 | font-weight: 500; 43 | font-family: inherit; 44 | background-color: #1a1a1a; 45 | cursor: pointer; 46 | transition: border-color 0.25s; 47 | } 48 | button:hover { 49 | border-color: #646cff; 50 | } 51 | 52 | button:focus, 53 | button:focus-visible { 54 | outline: 4px auto -webkit-focus-ring-color; 55 | } 56 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obs-source-record-ui", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "npm run build && vite preview", 11 | "deploy": "npm run build && wrangler deploy", 12 | "cf-typegen": "wrangler types" 13 | }, 14 | "dependencies": { 15 | "@cloudflare/vite-plugin": "^1.7.5", 16 | "@redux-devtools/extension": "^3.3.0", 17 | "obs-websocket-js": "^5.0.6", 18 | "react": "^19.1.0", 19 | "react-dom": "^19.1.0", 20 | "wrangler": "^4.36.0", 21 | "zustand": "^5.0.5", 22 | "zustand-devtools": "^1.1.0" 23 | }, 24 | "devDependencies": { 25 | "@eslint/js": "^9.25.0", 26 | "@types/node": "^22.15.21", 27 | "@types/react": "^19.1.2", 28 | "@types/react-dom": "^19.1.2", 29 | "@vitejs/plugin-react": "^4.4.1", 30 | "eslint": "^9.25.0", 31 | "eslint-plugin-react-hooks": "^5.2.0", 32 | "eslint-plugin-react-refresh": "^0.4.19", 33 | "globals": "^16.0.0", 34 | "typescript": "~5.8.3", 35 | "typescript-eslint": "^8.30.1", 36 | "vite": "^6.3.5" 37 | }, 38 | "packageManager": "pnpm@9.10.0+sha1.216899f511c8dfde183c7cb50b69009c779534a8" 39 | } 40 | -------------------------------------------------------------------------------- /src/assets/sources/text.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/components/OutputList.css: -------------------------------------------------------------------------------- 1 | .output-list { 2 | background: #1a1a1a; 3 | border-radius: 8px; 4 | padding: 1rem; 5 | margin: 1rem 0; 6 | } 7 | 8 | .output-list h2 { 9 | margin: 0 0 1rem 0; 10 | color: #fff; 11 | font-size: 1.25rem; 12 | } 13 | 14 | .output-grid { 15 | display: grid; 16 | grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 17 | gap: 1rem; 18 | } 19 | 20 | .output-item { 21 | background: #2a2a2a; 22 | border-radius: 4px; 23 | padding: 0.75rem; 24 | transition: opacity 0.2s; 25 | } 26 | 27 | .output-item.inactive { 28 | opacity: 0.5; 29 | } 30 | 31 | .output-header { 32 | display: flex; 33 | justify-content: space-between; 34 | align-items: center; 35 | margin-bottom: 0.5rem; 36 | } 37 | 38 | .output-title { 39 | display: flex; 40 | align-items: center; 41 | gap: 0.5rem; 42 | } 43 | 44 | .output-name { 45 | font-weight: 500; 46 | color: #fff; 47 | } 48 | 49 | .output-type { 50 | color: #888; 51 | font-size: 0.875rem; 52 | } 53 | 54 | .output-details { 55 | color: #aaa; 56 | font-size: 0.875rem; 57 | display: flex; 58 | flex-direction: column; 59 | gap: 0.25rem; 60 | } 61 | 62 | .active-indicator { 63 | width: 8px; 64 | height: 8px; 65 | background: #f44336; 66 | border-radius: 50%; 67 | display: inline-block; 68 | } 69 | -------------------------------------------------------------------------------- /src/components/ConnectionStringInput.css: -------------------------------------------------------------------------------- 1 | .connection-string-container { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | height: 100vh; 6 | background-color: #f0f0f0; 7 | flex-direction: column; 8 | img { 9 | max-width: 500px; 10 | width: 100%; 11 | margin-bottom: 2rem; 12 | } 13 | } 14 | 15 | .connection-string-container form { 16 | display: flex; 17 | flex-direction: column; 18 | gap: 1rem; 19 | padding: 2rem; 20 | background-color: white; 21 | border-radius: 8px; 22 | box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); 23 | margin-bottom: 2rem; 24 | } 25 | 26 | .connection-string-container input { 27 | padding: 0.5rem; 28 | border: 1px solid #ccc; 29 | border-radius: 4px; 30 | } 31 | 32 | .connection-string-container button { 33 | padding: 0.5rem 1rem; 34 | background-color: #007bff; 35 | color: white; 36 | border: none; 37 | border-radius: 4px; 38 | cursor: pointer; 39 | } 40 | 41 | .connection-string-container button:hover { 42 | background-color: #0056b3; 43 | } 44 | 45 | .instructions { 46 | text-align: left; 47 | background-color: white; 48 | padding: 2rem; 49 | border-radius: 8px; 50 | box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); 51 | } 52 | 53 | .instructions h3 { 54 | margin-top: 0; 55 | } 56 | 57 | .instructions ol { 58 | padding-left: 1.5rem; 59 | } 60 | -------------------------------------------------------------------------------- /src/components/StatusBar.css: -------------------------------------------------------------------------------- 1 | .status-bar { 2 | display: flex; 3 | align-items: center; 4 | gap: 1rem; 5 | padding: 0.5rem 1rem; 6 | background: #1a1a1a; 7 | border-bottom: 1px solid #333; 8 | } 9 | 10 | .status-item { 11 | display: flex; 12 | align-items: center; 13 | gap: 0.5rem; 14 | position: relative; 15 | } 16 | 17 | .status-icon { 18 | width: 8px; 19 | height: 8px; 20 | border-radius: 50%; 21 | background: #666; 22 | } 23 | 24 | .status-icon.active { 25 | background: #f44336; 26 | } 27 | 28 | .status-icon.connection.active { 29 | background: #4caf50; 30 | } 31 | 32 | .status-icon.stream.active { 33 | background: #2196f3; 34 | } 35 | 36 | .status-icon.virtual-cam.active { 37 | background: #9c27b0; 38 | } 39 | 40 | .status-label { 41 | color: #fff; 42 | font-size: 0.875rem; 43 | } 44 | 45 | .record-details { 46 | display: flex; 47 | align-items: center; 48 | gap: 1rem; 49 | margin-left: 0.5rem; 50 | color: #aaa; 51 | font-size: 0.75rem; 52 | } 53 | 54 | .record-time { 55 | font-family: monospace; 56 | } 57 | 58 | .record-size { 59 | color: #888; 60 | } 61 | 62 | .edit-connection-button { 63 | margin-left: 0.5rem; 64 | padding: 0.2rem 0.5rem; 65 | background-color: #007bff; 66 | color: white; 67 | border: none; 68 | border-radius: 4px; 69 | cursor: pointer; 70 | } 71 | 72 | .edit-connection-button:hover { 73 | background-color: #0056b3; 74 | } 75 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/sources/gamepad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/Scene.tsx: -------------------------------------------------------------------------------- 1 | import { useOBSStore } from "../store/obsStore"; 2 | import "./Scene.css"; 3 | import { getOBS } from "../obs"; 4 | import { MediaItem } from "./MediaItem"; 5 | 6 | interface SceneProps { 7 | sceneName: string; 8 | } 9 | 10 | export function Filters({ sourceName }: { sourceName: string }) { 11 | const obs = getOBS(); 12 | const sceneFilters = useOBSStore(state => state.sceneFilters); 13 | const filters = sceneFilters[sourceName] || []; 14 | return ( 15 |
    16 | {filters.map((filter) => ( 17 |
  • 18 | {filter.filterName} 19 | 33 | {/*
    {JSON.stringify(filter, null, 2)}
    */} 34 |
  • 35 | ))} 36 |
37 | ); 38 | } 39 | 40 | export function Scene({ sceneName }: SceneProps) { 41 | return ; 42 | } 43 | 44 | // Re-export utilities for backwards compatibility 45 | export { getSourceIcon } from "../utils/scene"; 46 | export type { InputKind } from "../utils/scene"; 47 | export { Preview } from "./Preview"; 48 | -------------------------------------------------------------------------------- /src/components/OBSDebugger.css: -------------------------------------------------------------------------------- 1 | .obs-debugger { 2 | background: #1a1a1a; 3 | border-radius: 8px; 4 | padding: 1rem; 5 | margin: 1rem 0; 6 | } 7 | 8 | .obs-debugger h2 { 9 | margin: 0 0 1rem 0; 10 | color: #fff; 11 | font-size: 1.25rem; 12 | } 13 | 14 | .obs-debugger h3 { 15 | margin: 1rem 0 0.5rem 0; 16 | color: #fff; 17 | font-size: 1rem; 18 | } 19 | 20 | .debug-buttons { 21 | display: flex; 22 | flex-wrap: wrap; 23 | gap: 0.5rem; 24 | } 25 | 26 | .debug-buttons button { 27 | background: #333; 28 | color: #fff; 29 | border: none; 30 | padding: 0.5rem 1rem; 31 | border-radius: 4px; 32 | cursor: pointer; 33 | font-size: 0.875rem; 34 | transition: background-color 0.2s; 35 | } 36 | 37 | .debug-buttons button:hover { 38 | background: #444; 39 | } 40 | 41 | .debug-buttons button:active { 42 | background: #555; 43 | } 44 | 45 | .debugger-error { 46 | background: #1a1a1a; 47 | color: #f44336; 48 | padding: 1rem; 49 | border-radius: 8px; 50 | border: 1px solid #f44336; 51 | margin: 1rem 0; 52 | } 53 | 54 | .output-list { 55 | margin-top: 1rem; 56 | display: flex; 57 | flex-direction: column; 58 | gap: 0.5rem; 59 | } 60 | 61 | .output-item { 62 | background: #2a2a2a; 63 | border-radius: 4px; 64 | padding: 0.75rem; 65 | } 66 | 67 | .output-header { 68 | display: flex; 69 | justify-content: space-between; 70 | align-items: center; 71 | margin-bottom: 0.5rem; 72 | } 73 | 74 | .output-name { 75 | font-weight: 500; 76 | color: #fff; 77 | } 78 | 79 | .output-type { 80 | color: #888; 81 | font-size: 0.875rem; 82 | } 83 | 84 | .output-details { 85 | color: #aaa; 86 | font-size: 0.875rem; 87 | display: flex; 88 | flex-direction: column; 89 | gap: 0.25rem; 90 | } 91 | -------------------------------------------------------------------------------- /src/assets/sources/group.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/utils/scene.ts: -------------------------------------------------------------------------------- 1 | // Import source icons 2 | import brushIcon from "../assets/sources/brush.svg"; 3 | import cameraIcon from "../assets/sources/camera.svg"; 4 | import defaultIcon from "../assets/sources/default.svg"; 5 | import globeIcon from "../assets/sources/globe.svg"; 6 | import imageIcon from "../assets/sources/image.svg"; 7 | import mediaIcon from "../assets/sources/media.svg"; 8 | import microphoneIcon from "../assets/sources/microphone.svg"; 9 | import slideshowIcon from "../assets/sources/slideshow.svg"; 10 | import textIcon from "../assets/sources/text.svg"; 11 | import windowIcon from "../assets/sources/window.svg"; 12 | import windowaudioIcon from "../assets/sources/windowaudio.svg"; 13 | 14 | export type InputKind = 'image_source' | 'color_source_v3' | 'slideshow_v2' | 'av_capture_input_v2' | 'macos-avcapture' | 'macos-avcapture-fast' | 'screen_capture' | 'sck_audio_capture' | 'display_capture' | 'window_capture' | 'coreaudio_input_capture' | 'coreaudio_output_capture' | 'syphon-input' | 'browser_source' | 'ffmpeg_source' | 'text_ft2_source_v2'; 15 | 16 | // Function to get the appropriate icon for a source type 17 | export function getSourceIcon(inputKind: InputKind): string { 18 | const iconMap: Record = { 19 | image_source: imageIcon, 20 | color_source_v3: brushIcon, 21 | slideshow_v2: slideshowIcon, 22 | av_capture_input_v2: cameraIcon, 23 | "macos-avcapture": cameraIcon, 24 | "macos-avcapture-fast": cameraIcon, 25 | screen_capture: windowIcon, 26 | sck_audio_capture: microphoneIcon, 27 | display_capture: windowIcon, 28 | window_capture: windowIcon, 29 | coreaudio_input_capture: microphoneIcon, 30 | coreaudio_output_capture: windowaudioIcon, 31 | "syphon-input": windowIcon, 32 | browser_source: globeIcon, 33 | ffmpeg_source: mediaIcon, 34 | text_ft2_source_v2: textIcon, 35 | }; 36 | 37 | return iconMap[inputKind] || defaultIcon; 38 | } 39 | -------------------------------------------------------------------------------- /src/components/OBSDebugger.tsx: -------------------------------------------------------------------------------- 1 | import { useOBSStore } from '../store/obsStore'; 2 | import { getOBS } from '../obs'; 3 | import './OBSDebugger.css'; 4 | 5 | export function OBSDebugger() { 6 | const isConnected = useOBSStore(state => state.isConnected); 7 | 8 | const makeCall = async (method: string, params?: Record) => { 9 | try { 10 | const obs = getOBS(); 11 | const response = await obs.call(method, params); 12 | console.log(`OBS Call: ${method}`, response); 13 | } catch (error) { 14 | console.error(`Error calling ${method}:`, error); 15 | } 16 | }; 17 | 18 | if (!isConnected) { 19 | return
Not connected to OBS
; 20 | } 21 | 22 | return ( 23 |
24 |

OBS Debugger

25 |
26 | 32 | 35 | 38 | 41 | 44 | 47 | 50 | 53 |
54 |
55 | ); 56 | } 57 | -------------------------------------------------------------------------------- /src/components/OutputList.tsx: -------------------------------------------------------------------------------- 1 | import { useOBSStore } from '../store/obsStore'; 2 | import './OutputList.css'; 3 | 4 | interface OutputFlags { 5 | OBS_OUTPUT_VIDEO: boolean; 6 | OBS_OUTPUT_AUDIO: boolean; 7 | OBS_OUTPUT_ENCODED: boolean; 8 | OBS_OUTPUT_MULTI_TRACK: boolean; 9 | OBS_OUTPUT_SERVICE: boolean; 10 | } 11 | 12 | interface OutputProps { 13 | outputName: string; 14 | outputType: string; 15 | outputWidth: number; 16 | outputHeight: number; 17 | outputFlags: OutputFlags; 18 | outputActive: boolean; 19 | } 20 | 21 | export function Output({ output }: { output: OutputProps }) { 22 | const renderFlags = (flags: OutputFlags) => { 23 | return Object.entries(flags) 24 | .filter(([_, value]) => value) 25 | .map(([key]) => key.replace('OBS_OUTPUT_', '')) 26 | .join(', '); 27 | }; 28 | 29 | return ( 30 |
31 |
32 |
33 | {output.outputName} 34 | {output.outputActive && } 35 |
36 | {output.outputType} 37 |
38 |
39 |
Dimensions: {output.outputWidth}x{output.outputHeight}
40 |
Flags: {renderFlags(output.outputFlags)}
41 |
42 |
43 | ); 44 | } 45 | 46 | export function OutputList() { 47 | const outputs = useOBSStore(state => state.outputs); 48 | 49 | if (outputs.length === 0) { 50 | return null; 51 | } 52 | 53 | return ( 54 |
55 |

OBS Outputs

56 |
57 | {outputs.map((output) => ( 58 | 59 | ))} 60 |
61 |
62 | ); 63 | } 64 | -------------------------------------------------------------------------------- /src/components/ConnectionStringInput.tsx: -------------------------------------------------------------------------------- 1 | 2 | import React, { useState } from 'react'; 3 | import Demo from '../assets/demo.png'; 4 | 5 | interface ConnectionStringInputProps { 6 | onConnect: (connectionString: string, password?: string) => void; 7 | initialConnectionString?: string; 8 | error?: string | null; 9 | } 10 | 11 | export function ConnectionStringInput({ onConnect, initialConnectionString = '', error }: ConnectionStringInputProps) { 12 | const [connectionString, setConnectionString] = useState(initialConnectionString); 13 | const [password, setPassword] = useState(localStorage.getItem('obsPassword') || ''); 14 | 15 | const handleSubmit = (e: React.FormEvent) => { 16 | e.preventDefault(); 17 | localStorage.setItem('obsPassword', password); 18 | onConnect(connectionString, password); 19 | }; 20 | 21 | return ( 22 |
23 | OBS Source Record UI 24 |
25 |

Enter OBS WebSocket Connection String

26 | {error &&
{error}
} 27 | setConnectionString(e.target.value)} 31 | placeholder="ws://127.0.0.1:4455" 32 | /> 33 | setPassword(e.target.value)} 37 | placeholder="Password (optional)" 38 | /> 39 | 40 |
41 |
42 |

How to Enable the WebSocket Server in OBS:

43 |
    44 |
  1. Open OBS.
  2. 45 |
  3. Click "Tools" from the menu, then "WebSocket Server Settings".
  4. 46 |
  5. Check "Enable WebSocket Server".
  6. 47 |
  7. Optionally, set a custom port and password.
  8. 48 |
49 |
50 |
51 | ); 52 | } 53 | -------------------------------------------------------------------------------- /src/assets/sources/globe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/sources/windowaudio.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/components/Scene.css: -------------------------------------------------------------------------------- 1 | .scene { 2 | background: #1a1a1a; 3 | border-radius: 8px; 4 | padding: 1rem; 5 | display: flex; 6 | flex-direction: column; 7 | gap: 1rem; 8 | --color: #56335e; 9 | border: 2px solid var(--color); 10 | [data-record-state="STOPPED"] &:has(.active) { 11 | --color: green; 12 | } 13 | [data-record-state="STARTED"] &:has(.active) { 14 | --color: red; 15 | } 16 | } 17 | 18 | .scene-title { 19 | margin: 0; 20 | font-size: 1.25rem; 21 | color: #fff; 22 | } 23 | 24 | .scene-preview { 25 | width: 100%; 26 | aspect-ratio: 16/9; 27 | background: #000; 28 | border-radius: 4px; 29 | overflow: hidden; 30 | } 31 | 32 | .scene-preview img { 33 | width: 100%; 34 | height: 100%; 35 | object-fit: contain; 36 | } 37 | 38 | .scene-content { 39 | } 40 | 41 | .scene-sources, 42 | .scene-filters { 43 | background: #242424; 44 | border-radius: 4px; 45 | padding: 0.75rem; 46 | } 47 | 48 | .scene-sources h3, 49 | .scene-filters h3 { 50 | margin: 0 0 0.5rem 0; 51 | font-size: 1rem; 52 | color: #fff; 53 | display: flex; 54 | align-items: center; 55 | gap: 0.5rem; 56 | text-align: center; 57 | justify-content: center; 58 | margin: 0; 59 | } 60 | 61 | .source-list, 62 | .filter-list { 63 | list-style: none; 64 | padding: 0; 65 | margin: 0; 66 | display: flex; 67 | flex-direction: column; 68 | gap: 0.5rem; 69 | } 70 | 71 | .source-item, 72 | .filter-item { 73 | display: flex; 74 | align-items: center; 75 | gap: 0.5rem; 76 | padding: 0.5rem; 77 | background: #333; 78 | border-radius: 4px; 79 | font-size: 0.875rem; 80 | } 81 | 82 | .source-icon { 83 | width: 20px; 84 | height: 20px; 85 | flex-shrink: 0; 86 | opacity: 0.8; 87 | filter: invert(1) brightness(1); 88 | } 89 | 90 | pre { 91 | font-size: 0.75rem; 92 | color: #fff; 93 | text-align: left; 94 | overflow-x: auto; 95 | } 96 | 97 | .source-name, 98 | .filter-name { 99 | flex: 1; 100 | color: #fff; 101 | } 102 | 103 | .source-type { 104 | color: #888; 105 | font-size: 0.75rem; 106 | padding: 0.25rem 0.5rem; 107 | background: #444; 108 | border-radius: 4px; 109 | } 110 | 111 | .source-dimensions { 112 | color: #888; 113 | font-size: 0.75rem; 114 | } 115 | 116 | .filter-enabled { 117 | font-size: 0.75rem; 118 | padding: 0.25rem 0.5rem; 119 | border-radius: 4px; 120 | } 121 | 122 | .filter-enabled.active { 123 | background: #4caf50; 124 | color: #fff; 125 | } 126 | 127 | .filter-enabled.inactive { 128 | background: #666; 129 | color: #fff; 130 | } 131 | 132 | .scene-error { 133 | color: #f44336; 134 | padding: 1rem; 135 | background: #1a1a1a; 136 | border-radius: 8px; 137 | border: 1px solid #f44336; 138 | } 139 | 140 | .light { 141 | color: rgba(255, 255, 255, 0.3); 142 | font-size: 0.75rem; 143 | } 144 | -------------------------------------------------------------------------------- /src/components/MediaItem.tsx: -------------------------------------------------------------------------------- 1 | import { Source, useOBSStore } from "../store/obsStore"; 2 | import { Output } from "./OutputList"; 3 | import { Filters } from "./Scene"; 4 | import { Preview } from "./Preview"; 5 | import { getSourceIcon, InputKind } from "../utils/scene"; 6 | 7 | interface SourceWithInputKind extends Source { 8 | inputKind: InputKind; 9 | } 10 | 11 | interface MediaItemProps { 12 | type: 'scene' | 'source'; 13 | name: string; 14 | source?: Source; // Only provided when type is 'source' 15 | } 16 | 17 | export function MediaItem({ type, name, source }: MediaItemProps) { 18 | const sceneFilters = useOBSStore(state => state.sceneFilters); 19 | const sceneSources = useOBSStore(state => state.sceneSources); 20 | const error = useOBSStore(state => state.error); 21 | 22 | const filters = sceneFilters[name] || []; 23 | const sources = type === 'scene' ? (sceneSources[name] || []) : []; 24 | 25 | // Find outputs that match the name of filters applied to this item. Usually this is one, but can be more. 26 | const outputs = useOBSStore((state) => state.outputs).filter((output) => 27 | filters.some((filter) => filter.filterName === output.outputName) 28 | ); 29 | 30 | if (error) { 31 | return
{error}
; 32 | } 33 | 34 | return ( 35 |
36 | 37 |
38 |
39 |

40 | {type === 'source' && source && ( 41 | {`${source.inputKind} 46 | )} 47 | {name} 48 | [{type}] 49 |

50 | 51 | {sources && ( 52 |
    53 | {sources.map((sceneSource) => { 54 | const sourceWithKind = sceneSource as SourceWithInputKind; 55 | return ( 56 |
  • 57 | {`${sourceWithKind.inputKind} 62 | {sceneSource.sourceName} 63 |
  • 64 | ); 65 | })} 66 |
67 | )} 68 |
69 | 70 |
71 | 72 |
73 | 74 | {type === 'scene' && outputs.map((output) => ( 75 | 76 | ))} 77 |
78 |
79 | ); 80 | } 81 | -------------------------------------------------------------------------------- /src/components/StatusBar.tsx: -------------------------------------------------------------------------------- 1 | import { useOBSStore } from '../store/obsStore'; 2 | import { RecordButton } from './RecordButton'; 3 | import './StatusBar.css'; 4 | 5 | function formatDuration(ms: number): string { 6 | const seconds = Math.floor(ms / 1000); 7 | const minutes = Math.floor(seconds / 60); 8 | const hours = Math.floor(minutes / 60); 9 | 10 | const pad = (num: number) => num.toString().padStart(2, '0'); 11 | 12 | return `${pad(hours)}:${pad(minutes % 60)}:${pad(seconds % 60)}`; 13 | } 14 | 15 | function formatFileSize(bytes: number | undefined): string { 16 | if (bytes === undefined) return '0 B'; 17 | 18 | const units = ['B', 'KB', 'MB', 'GB']; 19 | let size = bytes; 20 | let unitIndex = 0; 21 | 22 | while (size >= 1024 && unitIndex < units.length - 1) { 23 | size /= 1024; 24 | unitIndex++; 25 | } 26 | 27 | return `${size.toFixed(1)} ${units[unitIndex]}`; 28 | } 29 | 30 | function formatTimecode(timecode: string | undefined): string { 31 | if (!timecode) return '00:00:00'; 32 | // Remove milliseconds from timecode 33 | return timecode.split('.')[0]; 34 | } 35 | 36 | export function StatusBar() { 37 | const isConnected = useOBSStore(state => state.isConnected); 38 | const isStreaming = useOBSStore(state => state.isStreaming); 39 | const recordStatus = useOBSStore(state => state.recordStatus); 40 | const isVirtualCamActive = useOBSStore(state => state.isVirtualCamActive); 41 | 42 | const handleEditConnection = () => { 43 | localStorage.removeItem('obsConnectionString'); 44 | window.location.reload(); // Force a reload to show the connection input 45 | }; 46 | 47 | return ( 48 |
49 |
50 |
51 | OBS 52 | 53 |
54 |
55 |
56 | Stream 57 |
58 |
59 |
60 | Record 61 | {recordStatus?.outputActive && ( 62 |
63 | {formatTimecode(recordStatus.outputTimecode)} 64 | {formatFileSize(recordStatus.outputBytes)} 65 |
66 | )} 67 |
68 |
69 |
70 | Virtual Cam 71 |
72 |
73 | 74 |
75 |
76 | ); 77 | } 78 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | margin: 0 auto; 3 | width: 100%; 4 | text-align: center; 5 | } 6 | 7 | .logo { 8 | height: 6em; 9 | padding: 1.5em; 10 | will-change: filter; 11 | transition: filter 300ms; 12 | } 13 | .logo:hover { 14 | filter: drop-shadow(0 0 2em #646cffaa); 15 | } 16 | .logo.react:hover { 17 | filter: drop-shadow(0 0 2em #61dafbaa); 18 | } 19 | 20 | @keyframes logo-spin { 21 | from { 22 | transform: rotate(0deg); 23 | } 24 | to { 25 | transform: rotate(360deg); 26 | } 27 | } 28 | 29 | @media (prefers-reduced-motion: no-preference) { 30 | a:nth-of-type(2) .logo { 31 | animation: logo-spin infinite 20s linear; 32 | } 33 | } 34 | 35 | .card { 36 | padding: 2em; 37 | } 38 | 39 | .read-the-docs { 40 | color: #888; 41 | } 42 | 43 | .app-loading { 44 | display: flex; 45 | justify-content: center; 46 | align-items: center; 47 | height: 100vh; 48 | font-size: 1.5rem; 49 | } 50 | 51 | .error-message { 52 | color: #e74c3c; 53 | background-color: #fdd; 54 | padding: 1rem; 55 | border-radius: 4px; 56 | margin-bottom: 1rem; 57 | } 58 | 59 | .app { 60 | display: grid; 61 | grid-template-rows: auto 1fr auto; 62 | height: 100vh; 63 | background: #222; 64 | } 65 | 66 | .scenes-grid { 67 | display: grid; 68 | grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 69 | gap: 1rem; 70 | padding: 1rem; 71 | overflow-y: auto; 72 | } 73 | 74 | .scene { 75 | background: #f5f5f5; 76 | border-radius: 8px; 77 | padding: 1rem; 78 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 79 | } 80 | 81 | .scene h2 { 82 | margin: 0 0 1rem 0; 83 | color: #333; 84 | font-size: 1.5rem; 85 | } 86 | 87 | .scene-preview { 88 | width: 100%; 89 | margin-bottom: 1rem; 90 | } 91 | 92 | .scene-preview img { 93 | width: 100%; 94 | height: auto; 95 | border-radius: 4px; 96 | } 97 | 98 | .scene-filters { 99 | background: white; 100 | padding: 1rem; 101 | border-radius: 4px; 102 | } 103 | 104 | .scene-filters h3 { 105 | margin: 0 0 0.5rem 0; 106 | color: #666; 107 | font-size: 1.1rem; 108 | } 109 | 110 | .scene-filters ul { 111 | list-style: none; 112 | padding: 0; 113 | margin: 0; 114 | } 115 | 116 | .scene-filters li { 117 | padding: 0.5rem; 118 | border-bottom: 1px solid #eee; 119 | font-size: 0.9rem; 120 | } 121 | 122 | .scene-filters li:last-child { 123 | border-bottom: none; 124 | } 125 | 126 | .scene-filters li.enabled { 127 | color: #2ecc71; 128 | } 129 | 130 | .scene-filters li.disabled { 131 | color: #e74c3c; 132 | } 133 | 134 | .app-error, 135 | .scene-error { 136 | background: #fee; 137 | color: #c00; 138 | padding: 1rem; 139 | border-radius: 4px; 140 | text-align: center; 141 | margin: 1rem 0; 142 | } 143 | 144 | .app-footer { 145 | padding: 0; 146 | text-align: center; 147 | background: #1a1a1a; 148 | border-top: 1px solid #333; 149 | a { 150 | font-size: 11px; 151 | } 152 | } 153 | 154 | .github-link { 155 | color: #646cff; 156 | text-decoration: none; 157 | font-size: 0.875rem; 158 | transition: color 0.2s; 159 | } 160 | 161 | .github-link:hover { 162 | color: #535bf2; 163 | } 164 | 165 | .white { 166 | color: white; 167 | } 168 | -------------------------------------------------------------------------------- /src/components/RecordButton.tsx: -------------------------------------------------------------------------------- 1 | import { getOBS } from "../obs"; 2 | import { useOBSStore } from "../store/obsStore"; 3 | import './RecordButton.css'; 4 | 5 | const obs = getOBS(); 6 | 7 | interface Filter { 8 | filterName: string; 9 | filterKind: string; 10 | filterEnabled: boolean; 11 | } 12 | 13 | 14 | 15 | export function RecordButton() { 16 | const recordStatus = useOBSStore(state => state.recordStatus); 17 | const recordState = useOBSStore(state => state.recordState); 18 | const filters = useOBSStore(state => state.sceneFilters); 19 | const scenesorSourcesWithRecordFilter = Object.values(filters).flat().filter(filter => 20 | filter.filterKind === 'source_record_filter' && filter.filterEnabled 21 | ); 22 | 23 | 24 | return ( 25 |
26 | {!recordState?.outputState || recordState?.outputState === "OBS_WEBSOCKET_OUTPUT_STOPPED" ? ( 27 | 65 | ) : ( 66 | 84 | )} 85 |
86 | ); 87 | } 88 | -------------------------------------------------------------------------------- /src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { useOBSStore } from './store/obsStore'; 3 | import { StatusBar } from './components/StatusBar'; 4 | import './App.css'; 5 | import { ConnectionStringInput } from './components/ConnectionStringInput'; 6 | import './components/ConnectionStringInput.css'; 7 | import { OBSDebugger } from './components/OBSDebugger'; 8 | import { MediaItem } from './components/MediaItem'; 9 | import { uniqueSceneSources } from './utils/sources'; 10 | 11 | export function App() { 12 | const [connectionString, setConnectionString] = useState(localStorage.getItem('obsConnectionString')); 13 | const [password, setPassword] = useState(localStorage.getItem('obsPassword')); 14 | const [isConnecting, setIsConnecting] = useState(false); 15 | const connect = useOBSStore(state => state.connect); 16 | const fetchScenes = useOBSStore(state => state.fetchScenes); 17 | const startPolling = useOBSStore(state => state.startPolling); 18 | const stopPolling = useOBSStore(state => state.stopPolling); 19 | const isConnected = useOBSStore(state => state.isConnected); 20 | const scenes = useOBSStore(state => state.scenes); 21 | const sceneSources = useOBSStore(state => state.sceneSources); 22 | const error = useOBSStore(state => state.error); 23 | const recordStatus = useOBSStore((state) => state.recordStatus); 24 | const recordState = useOBSStore((state) => state.recordState); 25 | 26 | useEffect(() => { 27 | const init = async () => { 28 | if (connectionString) { 29 | setIsConnecting(true); 30 | try { 31 | await connect(connectionString, password || undefined); 32 | await fetchScenes(); 33 | startPolling(); 34 | } catch (error) { 35 | console.error('Failed to initialize:', error); 36 | } finally { 37 | setIsConnecting(false); 38 | } 39 | } 40 | }; 41 | 42 | init(); 43 | 44 | return () => { 45 | stopPolling(); 46 | }; 47 | }, [connect, fetchScenes, startPolling, stopPolling, connectionString, password]); 48 | 49 | const handleConnect = (newConnectionString: string, newPassword?: string) => { 50 | localStorage.setItem('obsConnectionString', newConnectionString); 51 | if (newPassword) { 52 | localStorage.setItem('obsPassword', newPassword); 53 | } 54 | setConnectionString(newConnectionString); 55 | setPassword(newPassword || null); 56 | }; 57 | 58 | if (isConnecting) { 59 | return
Connecting to OBS...
; 60 | } 61 | 62 | if (!isConnected) { 63 | return ; 64 | } 65 | 66 | // Create combined list of scenes and sources 67 | const sources = uniqueSceneSources(sceneSources); 68 | const mediaItems = [ 69 | // Add scenes first 70 | ...scenes.map(scene => ({ 71 | type: 'scene' as const, 72 | key: `scene-${scene.sceneName}`, 73 | name: scene.sceneName, 74 | source: undefined 75 | })), 76 | // Add sources second 77 | ...sources.map(source => ({ 78 | type: 'source' as const, 79 | key: `source-${source.sourceUuid}`, 80 | name: source.sourceName, 81 | source: source 82 | })) 83 | ]; 84 | 85 | 86 | 87 | return ( 88 |
89 | 90 | {/*

Record Status: {JSON.stringify(recordStatus)}

91 |

Record State: {JSON.stringify(recordState)}

92 | */} 93 |
94 | {mediaItems.map(item => ( 95 | 101 | ))} 102 |
103 | 113 |
114 | ); 115 | } 116 | 117 | export default App; 118 | -------------------------------------------------------------------------------- /src/store/obsStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from 'zustand'; 2 | import { devtools } from 'zustand/middleware'; 3 | import { connectOBS, getOBS } from '../obs'; 4 | import { SceneItem, Filter, SceneListResponse, SourceFilterListResponse, SourceScreenshotResponse } from '../types/obs'; 5 | import { RequestBatchRequest } from 'obs-websocket-js'; 6 | import { uniqueSceneSources } from '../utils/sources'; 7 | 8 | export interface Source { 9 | sourceName: string; 10 | sourceType: string; 11 | sourceWidth: number; 12 | sourceHeight: number; 13 | sourceUuid: string; 14 | inputKind: string; 15 | } 16 | 17 | interface OutputFlags { 18 | OBS_OUTPUT_VIDEO: boolean; 19 | OBS_OUTPUT_AUDIO: boolean; 20 | OBS_OUTPUT_ENCODED: boolean; 21 | OBS_OUTPUT_MULTI_TRACK: boolean; 22 | OBS_OUTPUT_SERVICE: boolean; 23 | } 24 | 25 | interface Output { 26 | outputName: string; 27 | outputType: string; 28 | outputWidth: number; 29 | outputHeight: number; 30 | outputFlags: OutputFlags; 31 | outputActive: boolean; 32 | } 33 | 34 | type OBS_OUTPUT_STATE = 35 | | "OBS_WEBSOCKET_OUTPUT_STARTING" 36 | | "OBS_WEBSOCKET_OUTPUT_STARTED" 37 | | "OBS_WEBSOCKET_OUTPUT_STOPPING" 38 | | "OBS_WEBSOCKET_OUTPUT_STOPPED" 39 | | "OBS_WEBSOCKET_OUTPUT_PAUSED" 40 | | "OBS_WEBSOCKET_OUTPUT_RESUMED"; 41 | 42 | interface RecordStatus { 43 | outputActive: boolean; 44 | outputPaused: boolean; 45 | outputTimecode: string; 46 | outputDuration: number; 47 | outputBytes: number; 48 | } 49 | 50 | interface RecordState { 51 | outputState: OBS_OUTPUT_STATE; 52 | } 53 | 54 | interface OBSState { 55 | scenes: SceneItem[]; 56 | sceneFilters: Record; 57 | scenePreviews: Record; 58 | sceneSources: Record; 59 | outputs: Output[]; 60 | error: string | null; 61 | isConnected: boolean; 62 | isPolling: boolean; 63 | isStreaming: boolean; 64 | recordStatus: RecordStatus; 65 | isVirtualCamActive: boolean; 66 | 67 | // Actions 68 | connect: (connectionString: string, password?: string) => Promise; 69 | fetchScenes: () => Promise; 70 | fetchSceneFilters: (sourceNames: string[]) => Promise; 71 | fetchScenePreview: (sourceNames: string[]) => Promise; 72 | fetchSceneSources: (sceneNames: string[]) => Promise; 73 | fetchOutputs: () => Promise; 74 | startPolling: () => void; 75 | stopPolling: () => void; 76 | setError: (error: string | null) => void; 77 | } 78 | 79 | let pollingInterval: NodeJS.Timeout | null = null; 80 | let recordStatusInterval: NodeJS.Timeout | null = null; 81 | 82 | export const useOBSStore = create()( 83 | devtools( 84 | (set, get) => ({ 85 | scenes: [], 86 | sceneFilters: {}, 87 | scenePreviews: {}, 88 | sceneSources: {}, 89 | outputs: [], 90 | error: null, 91 | isConnected: false, 92 | isPolling: false, 93 | isStreaming: false, 94 | recordState: { 95 | outputState: 'OBS_WEBSOCKET_OUTPUT_STOPPED' 96 | }, 97 | recordStatus: { 98 | outputActive: false, 99 | outputPaused: false, 100 | outputTimecode: '', 101 | outputDuration: 0, 102 | outputBytes: 0 103 | }, 104 | isVirtualCamActive: false, 105 | 106 | connect: async (connectionString: string, password?: string) => { 107 | try { 108 | await connectOBS(connectionString, password); 109 | const obs = getOBS(); 110 | 111 | // Set up global event listeners 112 | obs.on('SceneListChanged', (data) => { 113 | set({ scenes: data.scenes as SceneItem[] }, false, 'SceneListChanged'); 114 | }); 115 | 116 | 117 | const filterEvents = [ 118 | 'SourceFilterListReindexed', 119 | 'SourceFilterCreated', 120 | 'SourceFilterRemoved', 121 | 'SourceFilterNameChanged', 122 | 'SourceFilterSettingsChanged', 123 | 'SourceFilterEnableStateChanged' 124 | ]; 125 | 126 | filterEvents.forEach(event => { 127 | obs.on(event, (data) => { 128 | console.debug(event, data); 129 | get().fetchSceneFilters([data.sourceName]); 130 | }); 131 | }); 132 | 133 | // Add source change listener 134 | obs.on('SceneItemCreated', async (data) => { 135 | console.debug('SceneItemAdded', data); 136 | await get().fetchSceneSources([data.sceneName]); 137 | }); 138 | 139 | obs.on('SceneItemRemoved', async (data) => { 140 | console.debug('SceneItemRemoved', data); 141 | await get().fetchSceneSources([data.sceneName]); 142 | }); 143 | 144 | // Add status event listeners 145 | obs.on('StreamStateChanged', (data) => { 146 | console.debug('StreamStateChanged', data); 147 | set({ isStreaming: data.outputActive }, false, 'StreamStateChanged'); 148 | }); 149 | 150 | obs.on('RecordStateChanged', (data) => { 151 | console.debug('RecordStateChanged', data); 152 | set({ recordState: data }, false, 'RecordStateChanged'); 153 | }); 154 | 155 | obs.on('VirtualcamStateChanged', (data) => { 156 | console.debug('VirtualcamStateChanged', data); 157 | set({ isVirtualCamActive: data.outputActive }, false, 'VirtualcamStateChanged'); 158 | }); 159 | 160 | // Get initial states. TODO Batch this instead of three calls 161 | const [streamState, recordStatus, virtualCamState] = await Promise.all([ 162 | obs.call('GetStreamStatus'), 163 | obs.call('GetRecordStatus'), 164 | obs.call('GetVirtualCamStatus') 165 | ]); 166 | 167 | set({ 168 | isConnected: true, 169 | error: null, 170 | isStreaming: streamState.outputActive, 171 | recordStatus, 172 | isVirtualCamActive: virtualCamState.outputActive 173 | }, false, 'Connected'); 174 | 175 | } catch (error: any) { 176 | set({ error: error.message || 'Failed to connect to OBS', isConnected: false }, false, 'ConnectionError'); 177 | throw error; 178 | } 179 | }, 180 | 181 | fetchScenes: async () => { 182 | console.debug('Fetching scenes'); 183 | try { 184 | const obs = getOBS(); 185 | const sceneList = await obs.call('GetSceneList') as unknown as SceneListResponse; 186 | set({ scenes: sceneList.scenes, error: null }, false, 'FetchedScenes'); 187 | 188 | // Fetch sources + filters for all scenes in batch. This usually happens on initial load and then we only listen for changes scene-by-scene. 189 | const sceneNames = sceneList.scenes.map(scene => scene.sceneName); 190 | await get().fetchSceneSources(sceneNames); 191 | const sources = uniqueSceneSources(get().sceneSources); 192 | const sourceNames = sources.map(source => source.sourceName); 193 | // then get the fillter for all scenes AND sources 194 | await get().fetchSceneFilters([...sceneNames, ...sourceNames]); 195 | 196 | } catch (error) { 197 | set({ error: 'Failed to fetch scenes' }, false, 'FetchScenesError'); 198 | throw error; 199 | } 200 | }, 201 | 202 | fetchSceneFilters: async (sourceNames: string[]) => { 203 | if (!sourceNames?.length) return; 204 | console.debug('Fetching filters for sources', sourceNames); 205 | try { 206 | const obs = getOBS(); 207 | // Create batch request for multiple source filters 208 | const request: RequestBatchRequest[] = sourceNames.map((sourceName) => ({ 209 | requestType: 'GetSourceFilterList', 210 | requestId: sourceName, // This is so we can line them up with the source names in the response 211 | requestData: { 212 | sourceName 213 | } 214 | })); 215 | 216 | const responses = await obs.callBatch(request, { 217 | // Parallel execution is disabled as the data is returned in a random order: https://github.com/obsproject/obs-websocket/issues/1317 218 | // executionType: 2 // Parallel 219 | }); 220 | 221 | // Line them up with the source names and create the filters object 222 | const filtersWithSourceNames = Object.fromEntries( 223 | responses.map((response) => [ 224 | response.requestId, 225 | (response.responseData as unknown as SourceFilterListResponse)?.filters || [] 226 | ]) 227 | ); 228 | 229 | set((state) => ({ 230 | sceneFilters: { 231 | ...state.sceneFilters, 232 | ...filtersWithSourceNames 233 | }, 234 | error: null 235 | }), false, `FetchedFilters_${sourceNames.join(',')}`); 236 | } catch (error) { 237 | set({ error: `Failed to fetch filters for ${sourceNames.join(', ')}` }, false, `FetchFiltersError_${sourceNames.join(',')}`); 238 | throw error; 239 | } 240 | }, 241 | 242 | fetchScenePreview: async (sourceNames: string[]) => { 243 | if (!sourceNames?.length) return; 244 | // console.debug('Fetching preview for sources', sourceNames); 245 | try { 246 | const obs = getOBS(); 247 | // If they pass in an array of scene names, we need to use the batch request aPI 248 | // assemble the request 249 | const request: RequestBatchRequest[] = sourceNames.map((sourceName) => ({ 250 | requestType: 'GetSourceScreenshot', 251 | requestId: sourceName, // This is so we can line them up with the source names in the response 252 | requestData: { 253 | sourceName, 254 | imageFormat: 'png', 255 | imageWidth: Math.floor(1920 / 8), 256 | imageHeight: Math.floor(1080 / 8) 257 | } 258 | })); 259 | const previews = await obs.callBatch(request, { 260 | // Parallel execution is disabled as the data is returned in a random order: https://github.com/obsproject/obs-websocket/issues/1317 261 | // executionType: 2 // Parallel 262 | }); 263 | // line them up with the source names 264 | const previewsWithSourceNames = Object.fromEntries(previews.map((response, i) => [response.requestId, response.responseData?.imageData as string])); 265 | set(() => ({ 266 | scenePreviews: previewsWithSourceNames, 267 | error: null 268 | }), false, `FetchedPreview_${sourceNames}`); 269 | return; 270 | 271 | } catch (error) { 272 | set({ error: `Failed to fetch preview for ${sourceNames}` }, false, `FetchPreviewError_${sourceNames}`); 273 | throw error; 274 | } 275 | }, 276 | 277 | fetchSceneSources: async (sceneNames: string[]) => { 278 | if (!sceneNames?.length) return; 279 | console.debug('Fetching sources for scenes', sceneNames); 280 | try { 281 | const obs = getOBS(); 282 | // Create batch request for multiple scene sources 283 | const request: RequestBatchRequest[] = sceneNames.map((sceneName) => ({ 284 | requestType: 'GetSceneItemList', 285 | requestId: sceneName, // This is so we can line them up with the scene names in the response 286 | requestData: { 287 | sceneName 288 | } 289 | })); 290 | 291 | const responses = await obs.callBatch(request); 292 | 293 | // Line them up with the scene names and create the sources object 294 | const sourcesWithSceneNames = Object.fromEntries( 295 | responses.map((response) => [ 296 | response.requestId, 297 | (response.responseData as unknown as { sceneItems: Source[] })?.sceneItems || [] 298 | ]) 299 | ); 300 | 301 | set((state) => ({ 302 | sceneSources: { 303 | ...state.sceneSources, 304 | ...sourcesWithSceneNames 305 | }, 306 | error: null 307 | }), false, `FetchedSources_${sceneNames.join(',')}`); 308 | } catch (error) { 309 | set({ error: `Failed to fetch sources for ${sceneNames.join(', ')}` }, false, `FetchSourcesError_${sceneNames.join(',')}`); 310 | throw error; 311 | } 312 | }, 313 | 314 | fetchOutputs: async () => { 315 | try { 316 | const obs = getOBS(); 317 | const response = await obs.call('GetOutputList'); 318 | set({ outputs: response.outputs, error: null }, false, 'FetchedOutputs'); 319 | } catch (error) { 320 | set({ error: 'Failed to fetch outputs' }, false, 'FetchOutputsError'); 321 | throw error; 322 | } 323 | }, 324 | 325 | startPolling: () => { 326 | if (pollingInterval) { 327 | clearInterval(pollingInterval); 328 | } 329 | if (recordStatusInterval) { 330 | clearInterval(recordStatusInterval); 331 | } 332 | 333 | const poll = async () => { 334 | const state = get(); 335 | if (!state.isConnected) return; 336 | 337 | try { 338 | const sceneNames = state.scenes.map(scene => scene.sceneName); 339 | const sourceNames = uniqueSceneSources(state.sceneSources).map(source => source.sourceName); 340 | await state.fetchScenePreview([...sceneNames, ...sourceNames]); 341 | // Recursively call the poll function again as soon as possible 342 | setTimeout(poll, 33); 343 | // poll(); 344 | } catch (error) { 345 | console.error('Polling error:', error); 346 | } 347 | }; 348 | 349 | const pollRecordStatus = async () => { 350 | const state = get(); 351 | if (!state.isConnected) return; 352 | 353 | try { 354 | const obs = getOBS(); 355 | const recordStatus = await obs.call('GetRecordStatus'); 356 | set({ recordStatus }, false, 'PolledRecordStatus'); 357 | setTimeout(pollRecordStatus, 1000); 358 | } catch (error) { 359 | console.error('Record status polling error:', error); 360 | } 361 | }; 362 | 363 | // Initial polls 364 | poll(); 365 | pollRecordStatus(); 366 | set({ isPolling: true }, false, 'StartedPolling'); 367 | }, 368 | 369 | stopPolling: () => { 370 | if (pollingInterval) { 371 | clearInterval(pollingInterval); 372 | pollingInterval = null; 373 | } 374 | if (recordStatusInterval) { 375 | clearInterval(recordStatusInterval); 376 | recordStatusInterval = null; 377 | } 378 | set({ isPolling: false }, false, 'StoppedPolling'); 379 | }, 380 | 381 | setError: (error: string | null) => set({ error }, false, 'SetError') 382 | }), 383 | { 384 | name: 'OBS Store', 385 | enabled: process.env.NODE_ENV === 'development' 386 | } 387 | ) 388 | ); 389 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@cloudflare/vite-plugin': 12 | specifier: ^1.7.5 13 | version: 1.13.0(vite@6.3.6(@types/node@22.18.2))(workerd@1.20250906.0)(wrangler@4.36.0) 14 | '@redux-devtools/extension': 15 | specifier: ^3.3.0 16 | version: 3.3.0(redux@5.0.1) 17 | obs-websocket-js: 18 | specifier: ^5.0.6 19 | version: 5.0.6 20 | react: 21 | specifier: ^19.1.0 22 | version: 19.1.1 23 | react-dom: 24 | specifier: ^19.1.0 25 | version: 19.1.1(react@19.1.1) 26 | wrangler: 27 | specifier: ^4.36.0 28 | version: 4.36.0 29 | zustand: 30 | specifier: ^5.0.5 31 | version: 5.0.8(@types/react@19.1.13)(react@19.1.1) 32 | zustand-devtools: 33 | specifier: ^1.1.0 34 | version: 1.1.0(typescript@5.8.3)(zustand@5.0.8(@types/react@19.1.13)(react@19.1.1)) 35 | devDependencies: 36 | '@eslint/js': 37 | specifier: ^9.25.0 38 | version: 9.35.0 39 | '@types/node': 40 | specifier: ^22.15.21 41 | version: 22.18.2 42 | '@types/react': 43 | specifier: ^19.1.2 44 | version: 19.1.13 45 | '@types/react-dom': 46 | specifier: ^19.1.2 47 | version: 19.1.9(@types/react@19.1.13) 48 | '@vitejs/plugin-react': 49 | specifier: ^4.4.1 50 | version: 4.7.0(vite@6.3.6(@types/node@22.18.2)) 51 | eslint: 52 | specifier: ^9.25.0 53 | version: 9.35.0 54 | eslint-plugin-react-hooks: 55 | specifier: ^5.2.0 56 | version: 5.2.0(eslint@9.35.0) 57 | eslint-plugin-react-refresh: 58 | specifier: ^0.4.19 59 | version: 0.4.20(eslint@9.35.0) 60 | globals: 61 | specifier: ^16.0.0 62 | version: 16.4.0 63 | typescript: 64 | specifier: ~5.8.3 65 | version: 5.8.3 66 | typescript-eslint: 67 | specifier: ^8.30.1 68 | version: 8.43.0(eslint@9.35.0)(typescript@5.8.3) 69 | vite: 70 | specifier: ^6.3.5 71 | version: 6.3.6(@types/node@22.18.2) 72 | 73 | packages: 74 | 75 | '@babel/code-frame@7.27.1': 76 | resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} 77 | engines: {node: '>=6.9.0'} 78 | 79 | '@babel/compat-data@7.28.4': 80 | resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} 81 | engines: {node: '>=6.9.0'} 82 | 83 | '@babel/core@7.28.4': 84 | resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} 85 | engines: {node: '>=6.9.0'} 86 | 87 | '@babel/generator@7.28.3': 88 | resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} 89 | engines: {node: '>=6.9.0'} 90 | 91 | '@babel/helper-compilation-targets@7.27.2': 92 | resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} 93 | engines: {node: '>=6.9.0'} 94 | 95 | '@babel/helper-globals@7.28.0': 96 | resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} 97 | engines: {node: '>=6.9.0'} 98 | 99 | '@babel/helper-module-imports@7.27.1': 100 | resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} 101 | engines: {node: '>=6.9.0'} 102 | 103 | '@babel/helper-module-transforms@7.28.3': 104 | resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} 105 | engines: {node: '>=6.9.0'} 106 | peerDependencies: 107 | '@babel/core': ^7.0.0 108 | 109 | '@babel/helper-plugin-utils@7.27.1': 110 | resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} 111 | engines: {node: '>=6.9.0'} 112 | 113 | '@babel/helper-string-parser@7.27.1': 114 | resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} 115 | engines: {node: '>=6.9.0'} 116 | 117 | '@babel/helper-validator-identifier@7.27.1': 118 | resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} 119 | engines: {node: '>=6.9.0'} 120 | 121 | '@babel/helper-validator-option@7.27.1': 122 | resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} 123 | engines: {node: '>=6.9.0'} 124 | 125 | '@babel/helpers@7.28.4': 126 | resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} 127 | engines: {node: '>=6.9.0'} 128 | 129 | '@babel/parser@7.28.4': 130 | resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} 131 | engines: {node: '>=6.0.0'} 132 | hasBin: true 133 | 134 | '@babel/plugin-transform-react-jsx-self@7.27.1': 135 | resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} 136 | engines: {node: '>=6.9.0'} 137 | peerDependencies: 138 | '@babel/core': ^7.0.0-0 139 | 140 | '@babel/plugin-transform-react-jsx-source@7.27.1': 141 | resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} 142 | engines: {node: '>=6.9.0'} 143 | peerDependencies: 144 | '@babel/core': ^7.0.0-0 145 | 146 | '@babel/runtime@7.28.4': 147 | resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} 148 | engines: {node: '>=6.9.0'} 149 | 150 | '@babel/template@7.27.2': 151 | resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} 152 | engines: {node: '>=6.9.0'} 153 | 154 | '@babel/traverse@7.28.4': 155 | resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} 156 | engines: {node: '>=6.9.0'} 157 | 158 | '@babel/types@7.28.4': 159 | resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} 160 | engines: {node: '>=6.9.0'} 161 | 162 | '@cloudflare/kv-asset-handler@0.4.0': 163 | resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==} 164 | engines: {node: '>=18.0.0'} 165 | 166 | '@cloudflare/unenv-preset@2.7.3': 167 | resolution: {integrity: sha512-tsQQagBKjvpd9baa6nWVIv399ejiqcrUBBW6SZx6Z22+ymm+Odv5+cFimyuCsD/fC1fQTwfRmwXBNpzvHSeGCw==} 168 | peerDependencies: 169 | unenv: 2.0.0-rc.21 170 | workerd: ^1.20250828.1 171 | peerDependenciesMeta: 172 | workerd: 173 | optional: true 174 | 175 | '@cloudflare/vite-plugin@1.13.0': 176 | resolution: {integrity: sha512-vLToGk7PTtvNFQwlXqVHK1l637Uy2xPccRMbAjXlwRxoaEu0CvL1rZj7tiSb8KDtMU0DbJqqzVjawHyQly3q1w==} 177 | peerDependencies: 178 | vite: ^6.1.0 || ^7.0.0 179 | wrangler: ^4.36.0 180 | 181 | '@cloudflare/workerd-darwin-64@1.20250906.0': 182 | resolution: {integrity: sha512-E+X/YYH9BmX0ew2j/mAWFif2z05NMNuhCTlNYEGLkqMe99K15UewBqajL9pMcMUKxylnlrEoK3VNxl33DkbnPA==} 183 | engines: {node: '>=16'} 184 | cpu: [x64] 185 | os: [darwin] 186 | 187 | '@cloudflare/workerd-darwin-arm64@1.20250906.0': 188 | resolution: {integrity: sha512-X5apsZ1SFW4FYTM19ISHf8005FJMPfrcf4U5rO0tdj+TeJgQgXuZ57IG0WeW7SpLVeBo8hM6WC8CovZh41AfnA==} 189 | engines: {node: '>=16'} 190 | cpu: [arm64] 191 | os: [darwin] 192 | 193 | '@cloudflare/workerd-linux-64@1.20250906.0': 194 | resolution: {integrity: sha512-rlKzWgsLnlQ5Nt9W69YBJKcmTmZbOGu0edUsenXPmc6wzULUxoQpi7ZE9k3TfTonJx4WoQsQlzCUamRYFsX+0Q==} 195 | engines: {node: '>=16'} 196 | cpu: [x64] 197 | os: [linux] 198 | 199 | '@cloudflare/workerd-linux-arm64@1.20250906.0': 200 | resolution: {integrity: sha512-DdedhiQ+SeLzpg7BpcLrIPEZ33QKioJQ1wvL4X7nuLzEB9rWzS37NNNahQzc1+44rhG4fyiHbXBPOeox4B9XVA==} 201 | engines: {node: '>=16'} 202 | cpu: [arm64] 203 | os: [linux] 204 | 205 | '@cloudflare/workerd-windows-64@1.20250906.0': 206 | resolution: {integrity: sha512-Q8Qjfs8jGVILnZL6vUpQ90q/8MTCYaGR3d1LGxZMBqte8Vr7xF3KFHPEy7tFs0j0mMjnqCYzlofmPNY+9ZaDRg==} 207 | engines: {node: '>=16'} 208 | cpu: [x64] 209 | os: [win32] 210 | 211 | '@cspotcode/source-map-support@0.8.1': 212 | resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} 213 | engines: {node: '>=12'} 214 | 215 | '@emnapi/runtime@1.5.0': 216 | resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} 217 | 218 | '@esbuild/aix-ppc64@0.25.4': 219 | resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} 220 | engines: {node: '>=18'} 221 | cpu: [ppc64] 222 | os: [aix] 223 | 224 | '@esbuild/aix-ppc64@0.25.9': 225 | resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} 226 | engines: {node: '>=18'} 227 | cpu: [ppc64] 228 | os: [aix] 229 | 230 | '@esbuild/android-arm64@0.25.4': 231 | resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} 232 | engines: {node: '>=18'} 233 | cpu: [arm64] 234 | os: [android] 235 | 236 | '@esbuild/android-arm64@0.25.9': 237 | resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} 238 | engines: {node: '>=18'} 239 | cpu: [arm64] 240 | os: [android] 241 | 242 | '@esbuild/android-arm@0.25.4': 243 | resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} 244 | engines: {node: '>=18'} 245 | cpu: [arm] 246 | os: [android] 247 | 248 | '@esbuild/android-arm@0.25.9': 249 | resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} 250 | engines: {node: '>=18'} 251 | cpu: [arm] 252 | os: [android] 253 | 254 | '@esbuild/android-x64@0.25.4': 255 | resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} 256 | engines: {node: '>=18'} 257 | cpu: [x64] 258 | os: [android] 259 | 260 | '@esbuild/android-x64@0.25.9': 261 | resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} 262 | engines: {node: '>=18'} 263 | cpu: [x64] 264 | os: [android] 265 | 266 | '@esbuild/darwin-arm64@0.25.4': 267 | resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} 268 | engines: {node: '>=18'} 269 | cpu: [arm64] 270 | os: [darwin] 271 | 272 | '@esbuild/darwin-arm64@0.25.9': 273 | resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} 274 | engines: {node: '>=18'} 275 | cpu: [arm64] 276 | os: [darwin] 277 | 278 | '@esbuild/darwin-x64@0.25.4': 279 | resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} 280 | engines: {node: '>=18'} 281 | cpu: [x64] 282 | os: [darwin] 283 | 284 | '@esbuild/darwin-x64@0.25.9': 285 | resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} 286 | engines: {node: '>=18'} 287 | cpu: [x64] 288 | os: [darwin] 289 | 290 | '@esbuild/freebsd-arm64@0.25.4': 291 | resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} 292 | engines: {node: '>=18'} 293 | cpu: [arm64] 294 | os: [freebsd] 295 | 296 | '@esbuild/freebsd-arm64@0.25.9': 297 | resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} 298 | engines: {node: '>=18'} 299 | cpu: [arm64] 300 | os: [freebsd] 301 | 302 | '@esbuild/freebsd-x64@0.25.4': 303 | resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} 304 | engines: {node: '>=18'} 305 | cpu: [x64] 306 | os: [freebsd] 307 | 308 | '@esbuild/freebsd-x64@0.25.9': 309 | resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} 310 | engines: {node: '>=18'} 311 | cpu: [x64] 312 | os: [freebsd] 313 | 314 | '@esbuild/linux-arm64@0.25.4': 315 | resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} 316 | engines: {node: '>=18'} 317 | cpu: [arm64] 318 | os: [linux] 319 | 320 | '@esbuild/linux-arm64@0.25.9': 321 | resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} 322 | engines: {node: '>=18'} 323 | cpu: [arm64] 324 | os: [linux] 325 | 326 | '@esbuild/linux-arm@0.25.4': 327 | resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} 328 | engines: {node: '>=18'} 329 | cpu: [arm] 330 | os: [linux] 331 | 332 | '@esbuild/linux-arm@0.25.9': 333 | resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} 334 | engines: {node: '>=18'} 335 | cpu: [arm] 336 | os: [linux] 337 | 338 | '@esbuild/linux-ia32@0.25.4': 339 | resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} 340 | engines: {node: '>=18'} 341 | cpu: [ia32] 342 | os: [linux] 343 | 344 | '@esbuild/linux-ia32@0.25.9': 345 | resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} 346 | engines: {node: '>=18'} 347 | cpu: [ia32] 348 | os: [linux] 349 | 350 | '@esbuild/linux-loong64@0.25.4': 351 | resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} 352 | engines: {node: '>=18'} 353 | cpu: [loong64] 354 | os: [linux] 355 | 356 | '@esbuild/linux-loong64@0.25.9': 357 | resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} 358 | engines: {node: '>=18'} 359 | cpu: [loong64] 360 | os: [linux] 361 | 362 | '@esbuild/linux-mips64el@0.25.4': 363 | resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} 364 | engines: {node: '>=18'} 365 | cpu: [mips64el] 366 | os: [linux] 367 | 368 | '@esbuild/linux-mips64el@0.25.9': 369 | resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} 370 | engines: {node: '>=18'} 371 | cpu: [mips64el] 372 | os: [linux] 373 | 374 | '@esbuild/linux-ppc64@0.25.4': 375 | resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} 376 | engines: {node: '>=18'} 377 | cpu: [ppc64] 378 | os: [linux] 379 | 380 | '@esbuild/linux-ppc64@0.25.9': 381 | resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} 382 | engines: {node: '>=18'} 383 | cpu: [ppc64] 384 | os: [linux] 385 | 386 | '@esbuild/linux-riscv64@0.25.4': 387 | resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} 388 | engines: {node: '>=18'} 389 | cpu: [riscv64] 390 | os: [linux] 391 | 392 | '@esbuild/linux-riscv64@0.25.9': 393 | resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} 394 | engines: {node: '>=18'} 395 | cpu: [riscv64] 396 | os: [linux] 397 | 398 | '@esbuild/linux-s390x@0.25.4': 399 | resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} 400 | engines: {node: '>=18'} 401 | cpu: [s390x] 402 | os: [linux] 403 | 404 | '@esbuild/linux-s390x@0.25.9': 405 | resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} 406 | engines: {node: '>=18'} 407 | cpu: [s390x] 408 | os: [linux] 409 | 410 | '@esbuild/linux-x64@0.25.4': 411 | resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} 412 | engines: {node: '>=18'} 413 | cpu: [x64] 414 | os: [linux] 415 | 416 | '@esbuild/linux-x64@0.25.9': 417 | resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} 418 | engines: {node: '>=18'} 419 | cpu: [x64] 420 | os: [linux] 421 | 422 | '@esbuild/netbsd-arm64@0.25.4': 423 | resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} 424 | engines: {node: '>=18'} 425 | cpu: [arm64] 426 | os: [netbsd] 427 | 428 | '@esbuild/netbsd-arm64@0.25.9': 429 | resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} 430 | engines: {node: '>=18'} 431 | cpu: [arm64] 432 | os: [netbsd] 433 | 434 | '@esbuild/netbsd-x64@0.25.4': 435 | resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} 436 | engines: {node: '>=18'} 437 | cpu: [x64] 438 | os: [netbsd] 439 | 440 | '@esbuild/netbsd-x64@0.25.9': 441 | resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} 442 | engines: {node: '>=18'} 443 | cpu: [x64] 444 | os: [netbsd] 445 | 446 | '@esbuild/openbsd-arm64@0.25.4': 447 | resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} 448 | engines: {node: '>=18'} 449 | cpu: [arm64] 450 | os: [openbsd] 451 | 452 | '@esbuild/openbsd-arm64@0.25.9': 453 | resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} 454 | engines: {node: '>=18'} 455 | cpu: [arm64] 456 | os: [openbsd] 457 | 458 | '@esbuild/openbsd-x64@0.25.4': 459 | resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} 460 | engines: {node: '>=18'} 461 | cpu: [x64] 462 | os: [openbsd] 463 | 464 | '@esbuild/openbsd-x64@0.25.9': 465 | resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} 466 | engines: {node: '>=18'} 467 | cpu: [x64] 468 | os: [openbsd] 469 | 470 | '@esbuild/openharmony-arm64@0.25.9': 471 | resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} 472 | engines: {node: '>=18'} 473 | cpu: [arm64] 474 | os: [openharmony] 475 | 476 | '@esbuild/sunos-x64@0.25.4': 477 | resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} 478 | engines: {node: '>=18'} 479 | cpu: [x64] 480 | os: [sunos] 481 | 482 | '@esbuild/sunos-x64@0.25.9': 483 | resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} 484 | engines: {node: '>=18'} 485 | cpu: [x64] 486 | os: [sunos] 487 | 488 | '@esbuild/win32-arm64@0.25.4': 489 | resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} 490 | engines: {node: '>=18'} 491 | cpu: [arm64] 492 | os: [win32] 493 | 494 | '@esbuild/win32-arm64@0.25.9': 495 | resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} 496 | engines: {node: '>=18'} 497 | cpu: [arm64] 498 | os: [win32] 499 | 500 | '@esbuild/win32-ia32@0.25.4': 501 | resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} 502 | engines: {node: '>=18'} 503 | cpu: [ia32] 504 | os: [win32] 505 | 506 | '@esbuild/win32-ia32@0.25.9': 507 | resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} 508 | engines: {node: '>=18'} 509 | cpu: [ia32] 510 | os: [win32] 511 | 512 | '@esbuild/win32-x64@0.25.4': 513 | resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} 514 | engines: {node: '>=18'} 515 | cpu: [x64] 516 | os: [win32] 517 | 518 | '@esbuild/win32-x64@0.25.9': 519 | resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} 520 | engines: {node: '>=18'} 521 | cpu: [x64] 522 | os: [win32] 523 | 524 | '@eslint-community/eslint-utils@4.9.0': 525 | resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} 526 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 527 | peerDependencies: 528 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 529 | 530 | '@eslint-community/regexpp@4.12.1': 531 | resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} 532 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 533 | 534 | '@eslint/config-array@0.21.0': 535 | resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} 536 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 537 | 538 | '@eslint/config-helpers@0.3.1': 539 | resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==} 540 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 541 | 542 | '@eslint/core@0.15.2': 543 | resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} 544 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 545 | 546 | '@eslint/eslintrc@3.3.1': 547 | resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} 548 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 549 | 550 | '@eslint/js@9.35.0': 551 | resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==} 552 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 553 | 554 | '@eslint/object-schema@2.1.6': 555 | resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} 556 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 557 | 558 | '@eslint/plugin-kit@0.3.5': 559 | resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} 560 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 561 | 562 | '@humanfs/core@0.19.1': 563 | resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} 564 | engines: {node: '>=18.18.0'} 565 | 566 | '@humanfs/node@0.16.7': 567 | resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} 568 | engines: {node: '>=18.18.0'} 569 | 570 | '@humanwhocodes/module-importer@1.0.1': 571 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 572 | engines: {node: '>=12.22'} 573 | 574 | '@humanwhocodes/retry@0.4.3': 575 | resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} 576 | engines: {node: '>=18.18'} 577 | 578 | '@img/sharp-darwin-arm64@0.33.5': 579 | resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} 580 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 581 | cpu: [arm64] 582 | os: [darwin] 583 | 584 | '@img/sharp-darwin-x64@0.33.5': 585 | resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} 586 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 587 | cpu: [x64] 588 | os: [darwin] 589 | 590 | '@img/sharp-libvips-darwin-arm64@1.0.4': 591 | resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} 592 | cpu: [arm64] 593 | os: [darwin] 594 | 595 | '@img/sharp-libvips-darwin-x64@1.0.4': 596 | resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} 597 | cpu: [x64] 598 | os: [darwin] 599 | 600 | '@img/sharp-libvips-linux-arm64@1.0.4': 601 | resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} 602 | cpu: [arm64] 603 | os: [linux] 604 | 605 | '@img/sharp-libvips-linux-arm@1.0.5': 606 | resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} 607 | cpu: [arm] 608 | os: [linux] 609 | 610 | '@img/sharp-libvips-linux-s390x@1.0.4': 611 | resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} 612 | cpu: [s390x] 613 | os: [linux] 614 | 615 | '@img/sharp-libvips-linux-x64@1.0.4': 616 | resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} 617 | cpu: [x64] 618 | os: [linux] 619 | 620 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4': 621 | resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} 622 | cpu: [arm64] 623 | os: [linux] 624 | 625 | '@img/sharp-libvips-linuxmusl-x64@1.0.4': 626 | resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} 627 | cpu: [x64] 628 | os: [linux] 629 | 630 | '@img/sharp-linux-arm64@0.33.5': 631 | resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} 632 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 633 | cpu: [arm64] 634 | os: [linux] 635 | 636 | '@img/sharp-linux-arm@0.33.5': 637 | resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} 638 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 639 | cpu: [arm] 640 | os: [linux] 641 | 642 | '@img/sharp-linux-s390x@0.33.5': 643 | resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} 644 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 645 | cpu: [s390x] 646 | os: [linux] 647 | 648 | '@img/sharp-linux-x64@0.33.5': 649 | resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} 650 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 651 | cpu: [x64] 652 | os: [linux] 653 | 654 | '@img/sharp-linuxmusl-arm64@0.33.5': 655 | resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} 656 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 657 | cpu: [arm64] 658 | os: [linux] 659 | 660 | '@img/sharp-linuxmusl-x64@0.33.5': 661 | resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} 662 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 663 | cpu: [x64] 664 | os: [linux] 665 | 666 | '@img/sharp-wasm32@0.33.5': 667 | resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} 668 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 669 | cpu: [wasm32] 670 | 671 | '@img/sharp-win32-ia32@0.33.5': 672 | resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} 673 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 674 | cpu: [ia32] 675 | os: [win32] 676 | 677 | '@img/sharp-win32-x64@0.33.5': 678 | resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} 679 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 680 | cpu: [x64] 681 | os: [win32] 682 | 683 | '@jridgewell/gen-mapping@0.3.13': 684 | resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} 685 | 686 | '@jridgewell/remapping@2.3.5': 687 | resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} 688 | 689 | '@jridgewell/resolve-uri@3.1.2': 690 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 691 | engines: {node: '>=6.0.0'} 692 | 693 | '@jridgewell/sourcemap-codec@1.5.5': 694 | resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} 695 | 696 | '@jridgewell/trace-mapping@0.3.31': 697 | resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} 698 | 699 | '@jridgewell/trace-mapping@0.3.9': 700 | resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} 701 | 702 | '@msgpack/msgpack@2.8.0': 703 | resolution: {integrity: sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==} 704 | engines: {node: '>= 10'} 705 | 706 | '@nodelib/fs.scandir@2.1.5': 707 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 708 | engines: {node: '>= 8'} 709 | 710 | '@nodelib/fs.stat@2.0.5': 711 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 712 | engines: {node: '>= 8'} 713 | 714 | '@nodelib/fs.walk@1.2.8': 715 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 716 | engines: {node: '>= 8'} 717 | 718 | '@poppinss/colors@4.1.5': 719 | resolution: {integrity: sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==} 720 | 721 | '@poppinss/dumper@0.6.4': 722 | resolution: {integrity: sha512-iG0TIdqv8xJ3Lt9O8DrPRxw1MRLjNpoqiSGU03P/wNLP/s0ra0udPJ1J2Tx5M0J3H/cVyEgpbn8xUKRY9j59kQ==} 723 | 724 | '@poppinss/exception@1.2.2': 725 | resolution: {integrity: sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==} 726 | 727 | '@redux-devtools/extension@3.3.0': 728 | resolution: {integrity: sha512-X34S/rC8S/M1BIrkYD1mJ5f8vlH0BDqxXrs96cvxSBo4FhMdbhU+GUGsmNYov1xjSyLMHgo8NYrUG8bNX7525g==} 729 | peerDependencies: 730 | redux: ^3.1.0 || ^4.0.0 || ^5.0.0 731 | 732 | '@remix-run/node-fetch-server@0.8.1': 733 | resolution: {integrity: sha512-J1dev372wtJqmqn9U/qbpbZxbJSQrogNN2+Qv1lKlpATpe/WQ9aCZfl/xSb9d2Rgh1IyLSvNxZAXPZxruO6Xig==} 734 | 735 | '@rolldown/pluginutils@1.0.0-beta.27': 736 | resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} 737 | 738 | '@rollup/rollup-android-arm-eabi@4.50.1': 739 | resolution: {integrity: sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==} 740 | cpu: [arm] 741 | os: [android] 742 | 743 | '@rollup/rollup-android-arm64@4.50.1': 744 | resolution: {integrity: sha512-PZlsJVcjHfcH53mOImyt3bc97Ep3FJDXRpk9sMdGX0qgLmY0EIWxCag6EigerGhLVuL8lDVYNnSo8qnTElO4xw==} 745 | cpu: [arm64] 746 | os: [android] 747 | 748 | '@rollup/rollup-darwin-arm64@4.50.1': 749 | resolution: {integrity: sha512-xc6i2AuWh++oGi4ylOFPmzJOEeAa2lJeGUGb4MudOtgfyyjr4UPNK+eEWTPLvmPJIY/pgw6ssFIox23SyrkkJw==} 750 | cpu: [arm64] 751 | os: [darwin] 752 | 753 | '@rollup/rollup-darwin-x64@4.50.1': 754 | resolution: {integrity: sha512-2ofU89lEpDYhdLAbRdeyz/kX3Y2lpYc6ShRnDjY35bZhd2ipuDMDi6ZTQ9NIag94K28nFMofdnKeHR7BT0CATw==} 755 | cpu: [x64] 756 | os: [darwin] 757 | 758 | '@rollup/rollup-freebsd-arm64@4.50.1': 759 | resolution: {integrity: sha512-wOsE6H2u6PxsHY/BeFHA4VGQN3KUJFZp7QJBmDYI983fgxq5Th8FDkVuERb2l9vDMs1D5XhOrhBrnqcEY6l8ZA==} 760 | cpu: [arm64] 761 | os: [freebsd] 762 | 763 | '@rollup/rollup-freebsd-x64@4.50.1': 764 | resolution: {integrity: sha512-A/xeqaHTlKbQggxCqispFAcNjycpUEHP52mwMQZUNqDUJFFYtPHCXS1VAG29uMlDzIVr+i00tSFWFLivMcoIBQ==} 765 | cpu: [x64] 766 | os: [freebsd] 767 | 768 | '@rollup/rollup-linux-arm-gnueabihf@4.50.1': 769 | resolution: {integrity: sha512-54v4okehwl5TaSIkpp97rAHGp7t3ghinRd/vyC1iXqXMfjYUTm7TfYmCzXDoHUPTTf36L8pr0E7YsD3CfB3ZDg==} 770 | cpu: [arm] 771 | os: [linux] 772 | 773 | '@rollup/rollup-linux-arm-musleabihf@4.50.1': 774 | resolution: {integrity: sha512-p/LaFyajPN/0PUHjv8TNyxLiA7RwmDoVY3flXHPSzqrGcIp/c2FjwPPP5++u87DGHtw+5kSH5bCJz0mvXngYxw==} 775 | cpu: [arm] 776 | os: [linux] 777 | 778 | '@rollup/rollup-linux-arm64-gnu@4.50.1': 779 | resolution: {integrity: sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw==} 780 | cpu: [arm64] 781 | os: [linux] 782 | 783 | '@rollup/rollup-linux-arm64-musl@4.50.1': 784 | resolution: {integrity: sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w==} 785 | cpu: [arm64] 786 | os: [linux] 787 | 788 | '@rollup/rollup-linux-loongarch64-gnu@4.50.1': 789 | resolution: {integrity: sha512-RPhTwWMzpYYrHrJAS7CmpdtHNKtt2Ueo+BlLBjfZEhYBhK00OsEqM08/7f+eohiF6poe0YRDDd8nAvwtE/Y62Q==} 790 | cpu: [loong64] 791 | os: [linux] 792 | 793 | '@rollup/rollup-linux-ppc64-gnu@4.50.1': 794 | resolution: {integrity: sha512-eSGMVQw9iekut62O7eBdbiccRguuDgiPMsw++BVUg+1K7WjZXHOg/YOT9SWMzPZA+w98G+Fa1VqJgHZOHHnY0Q==} 795 | cpu: [ppc64] 796 | os: [linux] 797 | 798 | '@rollup/rollup-linux-riscv64-gnu@4.50.1': 799 | resolution: {integrity: sha512-S208ojx8a4ciIPrLgazF6AgdcNJzQE4+S9rsmOmDJkusvctii+ZvEuIC4v/xFqzbuP8yDjn73oBlNDgF6YGSXQ==} 800 | cpu: [riscv64] 801 | os: [linux] 802 | 803 | '@rollup/rollup-linux-riscv64-musl@4.50.1': 804 | resolution: {integrity: sha512-3Ag8Ls1ggqkGUvSZWYcdgFwriy2lWo+0QlYgEFra/5JGtAd6C5Hw59oojx1DeqcA2Wds2ayRgvJ4qxVTzCHgzg==} 805 | cpu: [riscv64] 806 | os: [linux] 807 | 808 | '@rollup/rollup-linux-s390x-gnu@4.50.1': 809 | resolution: {integrity: sha512-t9YrKfaxCYe7l7ldFERE1BRg/4TATxIg+YieHQ966jwvo7ddHJxPj9cNFWLAzhkVsbBvNA4qTbPVNsZKBO4NSg==} 810 | cpu: [s390x] 811 | os: [linux] 812 | 813 | '@rollup/rollup-linux-x64-gnu@4.50.1': 814 | resolution: {integrity: sha512-MCgtFB2+SVNuQmmjHf+wfI4CMxy3Tk8XjA5Z//A0AKD7QXUYFMQcns91K6dEHBvZPCnhJSyDWLApk40Iq/H3tA==} 815 | cpu: [x64] 816 | os: [linux] 817 | 818 | '@rollup/rollup-linux-x64-musl@4.50.1': 819 | resolution: {integrity: sha512-nEvqG+0jeRmqaUMuwzlfMKwcIVffy/9KGbAGyoa26iu6eSngAYQ512bMXuqqPrlTyfqdlB9FVINs93j534UJrg==} 820 | cpu: [x64] 821 | os: [linux] 822 | 823 | '@rollup/rollup-openharmony-arm64@4.50.1': 824 | resolution: {integrity: sha512-RDsLm+phmT3MJd9SNxA9MNuEAO/J2fhW8GXk62G/B4G7sLVumNFbRwDL6v5NrESb48k+QMqdGbHgEtfU0LCpbA==} 825 | cpu: [arm64] 826 | os: [openharmony] 827 | 828 | '@rollup/rollup-win32-arm64-msvc@4.50.1': 829 | resolution: {integrity: sha512-hpZB/TImk2FlAFAIsoElM3tLzq57uxnGYwplg6WDyAxbYczSi8O2eQ+H2Lx74504rwKtZ3N2g4bCUkiamzS6TQ==} 830 | cpu: [arm64] 831 | os: [win32] 832 | 833 | '@rollup/rollup-win32-ia32-msvc@4.50.1': 834 | resolution: {integrity: sha512-SXjv8JlbzKM0fTJidX4eVsH+Wmnp0/WcD8gJxIZyR6Gay5Qcsmdbi9zVtnbkGPG8v2vMR1AD06lGWy5FLMcG7A==} 835 | cpu: [ia32] 836 | os: [win32] 837 | 838 | '@rollup/rollup-win32-x64-msvc@4.50.1': 839 | resolution: {integrity: sha512-StxAO/8ts62KZVRAm4JZYq9+NqNsV7RvimNK+YM7ry//zebEH6meuugqW/P5OFUCjyQgui+9fUxT6d5NShvMvA==} 840 | cpu: [x64] 841 | os: [win32] 842 | 843 | '@sindresorhus/is@7.0.2': 844 | resolution: {integrity: sha512-d9xRovfKNz1SKieM0qJdO+PQonjnnIfSNWfHYnBSJ9hkjm0ZPw6HlxscDXYstp3z+7V2GOFHc+J0CYrYTjqCJw==} 845 | engines: {node: '>=18'} 846 | 847 | '@speed-highlight/core@1.2.7': 848 | resolution: {integrity: sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==} 849 | 850 | '@types/babel__core@7.20.5': 851 | resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} 852 | 853 | '@types/babel__generator@7.27.0': 854 | resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} 855 | 856 | '@types/babel__template@7.4.4': 857 | resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} 858 | 859 | '@types/babel__traverse@7.28.0': 860 | resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} 861 | 862 | '@types/estree@1.0.8': 863 | resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} 864 | 865 | '@types/json-schema@7.0.15': 866 | resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} 867 | 868 | '@types/node@22.18.2': 869 | resolution: {integrity: sha512-lif9hF9afNk39jMUVYk5eyYEojLZQqaYX61LfuwUJJ1+qiQbh7jVaZXskYgzyjAIFDFQRf5Sd6MVM7EyXkfiRw==} 870 | 871 | '@types/react-dom@19.1.9': 872 | resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} 873 | peerDependencies: 874 | '@types/react': ^19.0.0 875 | 876 | '@types/react@19.1.13': 877 | resolution: {integrity: sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==} 878 | 879 | '@typescript-eslint/eslint-plugin@8.43.0': 880 | resolution: {integrity: sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==} 881 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 882 | peerDependencies: 883 | '@typescript-eslint/parser': ^8.43.0 884 | eslint: ^8.57.0 || ^9.0.0 885 | typescript: '>=4.8.4 <6.0.0' 886 | 887 | '@typescript-eslint/parser@8.43.0': 888 | resolution: {integrity: sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==} 889 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 890 | peerDependencies: 891 | eslint: ^8.57.0 || ^9.0.0 892 | typescript: '>=4.8.4 <6.0.0' 893 | 894 | '@typescript-eslint/project-service@8.43.0': 895 | resolution: {integrity: sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==} 896 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 897 | peerDependencies: 898 | typescript: '>=4.8.4 <6.0.0' 899 | 900 | '@typescript-eslint/scope-manager@8.43.0': 901 | resolution: {integrity: sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==} 902 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 903 | 904 | '@typescript-eslint/tsconfig-utils@8.43.0': 905 | resolution: {integrity: sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==} 906 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 907 | peerDependencies: 908 | typescript: '>=4.8.4 <6.0.0' 909 | 910 | '@typescript-eslint/type-utils@8.43.0': 911 | resolution: {integrity: sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==} 912 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 913 | peerDependencies: 914 | eslint: ^8.57.0 || ^9.0.0 915 | typescript: '>=4.8.4 <6.0.0' 916 | 917 | '@typescript-eslint/types@8.43.0': 918 | resolution: {integrity: sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==} 919 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 920 | 921 | '@typescript-eslint/typescript-estree@8.43.0': 922 | resolution: {integrity: sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==} 923 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 924 | peerDependencies: 925 | typescript: '>=4.8.4 <6.0.0' 926 | 927 | '@typescript-eslint/utils@8.43.0': 928 | resolution: {integrity: sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==} 929 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 930 | peerDependencies: 931 | eslint: ^8.57.0 || ^9.0.0 932 | typescript: '>=4.8.4 <6.0.0' 933 | 934 | '@typescript-eslint/visitor-keys@8.43.0': 935 | resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==} 936 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 937 | 938 | '@vitejs/plugin-react@4.7.0': 939 | resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} 940 | engines: {node: ^14.18.0 || >=16.0.0} 941 | peerDependencies: 942 | vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 943 | 944 | acorn-jsx@5.3.2: 945 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 946 | peerDependencies: 947 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 948 | 949 | acorn-walk@8.3.2: 950 | resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} 951 | engines: {node: '>=0.4.0'} 952 | 953 | acorn@8.14.0: 954 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} 955 | engines: {node: '>=0.4.0'} 956 | hasBin: true 957 | 958 | acorn@8.15.0: 959 | resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} 960 | engines: {node: '>=0.4.0'} 961 | hasBin: true 962 | 963 | ajv@6.12.6: 964 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 965 | 966 | ansi-styles@4.3.0: 967 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 968 | engines: {node: '>=8'} 969 | 970 | argparse@2.0.1: 971 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 972 | 973 | balanced-match@1.0.2: 974 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 975 | 976 | baseline-browser-mapping@2.8.2: 977 | resolution: {integrity: sha512-NvcIedLxrs9llVpX7wI+Jz4Hn9vJQkCPKrTaHIE0sW/Rj1iq6Fzby4NbyTZjQJNoypBXNaG7tEHkTgONZpwgxQ==} 978 | hasBin: true 979 | 980 | blake3-wasm@2.1.5: 981 | resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} 982 | 983 | brace-expansion@1.1.12: 984 | resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} 985 | 986 | brace-expansion@2.0.2: 987 | resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} 988 | 989 | braces@3.0.3: 990 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 991 | engines: {node: '>=8'} 992 | 993 | browserslist@4.26.0: 994 | resolution: {integrity: sha512-P9go2WrP9FiPwLv3zqRD/Uoxo0RSHjzFCiQz7d4vbmwNqQFo9T9WCeP/Qn5EbcKQY6DBbkxEXNcpJOmncNrb7A==} 995 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 996 | hasBin: true 997 | 998 | callsites@3.1.0: 999 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 1000 | engines: {node: '>=6'} 1001 | 1002 | caniuse-lite@1.0.30001741: 1003 | resolution: {integrity: sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==} 1004 | 1005 | chalk@4.1.2: 1006 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 1007 | engines: {node: '>=10'} 1008 | 1009 | color-convert@2.0.1: 1010 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 1011 | engines: {node: '>=7.0.0'} 1012 | 1013 | color-name@1.1.4: 1014 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 1015 | 1016 | color-string@1.9.1: 1017 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} 1018 | 1019 | color@4.2.3: 1020 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} 1021 | engines: {node: '>=12.5.0'} 1022 | 1023 | concat-map@0.0.1: 1024 | resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} 1025 | 1026 | convert-source-map@2.0.0: 1027 | resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} 1028 | 1029 | cookie@1.0.2: 1030 | resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} 1031 | engines: {node: '>=18'} 1032 | 1033 | cross-spawn@7.0.6: 1034 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 1035 | engines: {node: '>= 8'} 1036 | 1037 | crypto-js@4.2.0: 1038 | resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} 1039 | 1040 | csstype@3.1.3: 1041 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 1042 | 1043 | debug@4.4.1: 1044 | resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} 1045 | engines: {node: '>=6.0'} 1046 | peerDependencies: 1047 | supports-color: '*' 1048 | peerDependenciesMeta: 1049 | supports-color: 1050 | optional: true 1051 | 1052 | deep-is@0.1.4: 1053 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 1054 | 1055 | defu@6.1.4: 1056 | resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} 1057 | 1058 | detect-libc@2.0.4: 1059 | resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} 1060 | engines: {node: '>=8'} 1061 | 1062 | electron-to-chromium@1.5.218: 1063 | resolution: {integrity: sha512-uwwdN0TUHs8u6iRgN8vKeWZMRll4gBkz+QMqdS7DDe49uiK68/UX92lFb61oiFPrpYZNeZIqa4bA7O6Aiasnzg==} 1064 | 1065 | error-stack-parser-es@1.0.5: 1066 | resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} 1067 | 1068 | esbuild@0.25.4: 1069 | resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} 1070 | engines: {node: '>=18'} 1071 | hasBin: true 1072 | 1073 | esbuild@0.25.9: 1074 | resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} 1075 | engines: {node: '>=18'} 1076 | hasBin: true 1077 | 1078 | escalade@3.2.0: 1079 | resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} 1080 | engines: {node: '>=6'} 1081 | 1082 | escape-string-regexp@4.0.0: 1083 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 1084 | engines: {node: '>=10'} 1085 | 1086 | eslint-plugin-react-hooks@5.2.0: 1087 | resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} 1088 | engines: {node: '>=10'} 1089 | peerDependencies: 1090 | eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 1091 | 1092 | eslint-plugin-react-refresh@0.4.20: 1093 | resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} 1094 | peerDependencies: 1095 | eslint: '>=8.40' 1096 | 1097 | eslint-scope@8.4.0: 1098 | resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} 1099 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1100 | 1101 | eslint-visitor-keys@3.4.3: 1102 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} 1103 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 1104 | 1105 | eslint-visitor-keys@4.2.1: 1106 | resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} 1107 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1108 | 1109 | eslint@9.35.0: 1110 | resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==} 1111 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1112 | hasBin: true 1113 | peerDependencies: 1114 | jiti: '*' 1115 | peerDependenciesMeta: 1116 | jiti: 1117 | optional: true 1118 | 1119 | espree@10.4.0: 1120 | resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} 1121 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1122 | 1123 | esquery@1.6.0: 1124 | resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} 1125 | engines: {node: '>=0.10'} 1126 | 1127 | esrecurse@4.3.0: 1128 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 1129 | engines: {node: '>=4.0'} 1130 | 1131 | estraverse@5.3.0: 1132 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 1133 | engines: {node: '>=4.0'} 1134 | 1135 | esutils@2.0.3: 1136 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 1137 | engines: {node: '>=0.10.0'} 1138 | 1139 | eventemitter3@5.0.1: 1140 | resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} 1141 | 1142 | exit-hook@2.2.1: 1143 | resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} 1144 | engines: {node: '>=6'} 1145 | 1146 | exsolve@1.0.7: 1147 | resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} 1148 | 1149 | fast-deep-equal@3.1.3: 1150 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 1151 | 1152 | fast-glob@3.3.3: 1153 | resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} 1154 | engines: {node: '>=8.6.0'} 1155 | 1156 | fast-json-stable-stringify@2.1.0: 1157 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 1158 | 1159 | fast-levenshtein@2.0.6: 1160 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 1161 | 1162 | fastq@1.19.1: 1163 | resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} 1164 | 1165 | fdir@6.5.0: 1166 | resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} 1167 | engines: {node: '>=12.0.0'} 1168 | peerDependencies: 1169 | picomatch: ^3 || ^4 1170 | peerDependenciesMeta: 1171 | picomatch: 1172 | optional: true 1173 | 1174 | file-entry-cache@8.0.0: 1175 | resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} 1176 | engines: {node: '>=16.0.0'} 1177 | 1178 | fill-range@7.1.1: 1179 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 1180 | engines: {node: '>=8'} 1181 | 1182 | find-up@5.0.0: 1183 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 1184 | engines: {node: '>=10'} 1185 | 1186 | flat-cache@4.0.1: 1187 | resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} 1188 | engines: {node: '>=16'} 1189 | 1190 | flatted@3.3.3: 1191 | resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} 1192 | 1193 | fsevents@2.3.3: 1194 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 1195 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 1196 | os: [darwin] 1197 | 1198 | gensync@1.0.0-beta.2: 1199 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} 1200 | engines: {node: '>=6.9.0'} 1201 | 1202 | get-port@7.1.0: 1203 | resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} 1204 | engines: {node: '>=16'} 1205 | 1206 | glob-parent@5.1.2: 1207 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 1208 | engines: {node: '>= 6'} 1209 | 1210 | glob-parent@6.0.2: 1211 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 1212 | engines: {node: '>=10.13.0'} 1213 | 1214 | glob-to-regexp@0.4.1: 1215 | resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} 1216 | 1217 | globals@14.0.0: 1218 | resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} 1219 | engines: {node: '>=18'} 1220 | 1221 | globals@16.4.0: 1222 | resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} 1223 | engines: {node: '>=18'} 1224 | 1225 | graphemer@1.4.0: 1226 | resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 1227 | 1228 | has-flag@4.0.0: 1229 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 1230 | engines: {node: '>=8'} 1231 | 1232 | ignore@5.3.2: 1233 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 1234 | engines: {node: '>= 4'} 1235 | 1236 | ignore@7.0.5: 1237 | resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} 1238 | engines: {node: '>= 4'} 1239 | 1240 | immutable@4.3.7: 1241 | resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} 1242 | 1243 | import-fresh@3.3.1: 1244 | resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} 1245 | engines: {node: '>=6'} 1246 | 1247 | imurmurhash@0.1.4: 1248 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 1249 | engines: {node: '>=0.8.19'} 1250 | 1251 | is-arrayish@0.3.2: 1252 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} 1253 | 1254 | is-extglob@2.1.1: 1255 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 1256 | engines: {node: '>=0.10.0'} 1257 | 1258 | is-glob@4.0.3: 1259 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 1260 | engines: {node: '>=0.10.0'} 1261 | 1262 | is-number@7.0.0: 1263 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 1264 | engines: {node: '>=0.12.0'} 1265 | 1266 | isexe@2.0.0: 1267 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 1268 | 1269 | isomorphic-ws@5.0.0: 1270 | resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} 1271 | peerDependencies: 1272 | ws: '*' 1273 | 1274 | js-tokens@4.0.0: 1275 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 1276 | 1277 | js-yaml@4.1.0: 1278 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 1279 | hasBin: true 1280 | 1281 | jsesc@3.1.0: 1282 | resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} 1283 | engines: {node: '>=6'} 1284 | hasBin: true 1285 | 1286 | json-buffer@3.0.1: 1287 | resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} 1288 | 1289 | json-schema-traverse@0.4.1: 1290 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 1291 | 1292 | json-stable-stringify-without-jsonify@1.0.1: 1293 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 1294 | 1295 | json5@2.2.3: 1296 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} 1297 | engines: {node: '>=6'} 1298 | hasBin: true 1299 | 1300 | keyv@4.5.4: 1301 | resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} 1302 | 1303 | kleur@4.1.5: 1304 | resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} 1305 | engines: {node: '>=6'} 1306 | 1307 | levn@0.4.1: 1308 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 1309 | engines: {node: '>= 0.8.0'} 1310 | 1311 | locate-path@6.0.0: 1312 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 1313 | engines: {node: '>=10'} 1314 | 1315 | lodash.merge@4.6.2: 1316 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 1317 | 1318 | lru-cache@5.1.1: 1319 | resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} 1320 | 1321 | merge2@1.4.1: 1322 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 1323 | engines: {node: '>= 8'} 1324 | 1325 | micromatch@4.0.8: 1326 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 1327 | engines: {node: '>=8.6'} 1328 | 1329 | mime@3.0.0: 1330 | resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} 1331 | engines: {node: '>=10.0.0'} 1332 | hasBin: true 1333 | 1334 | miniflare@4.20250906.1: 1335 | resolution: {integrity: sha512-yuPHog7j+GKHtRaKKF3Mpwvb5SVtvmkQpY/f9Ue0xhG/fYQcaxTKVO6RAB1pUN1jSyvmDOxVEAFFVoni8GYl3g==} 1336 | engines: {node: '>=18.0.0'} 1337 | hasBin: true 1338 | 1339 | minimatch@3.1.2: 1340 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1341 | 1342 | minimatch@9.0.5: 1343 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 1344 | engines: {node: '>=16 || 14 >=14.17'} 1345 | 1346 | ms@2.1.3: 1347 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 1348 | 1349 | nanoid@3.3.11: 1350 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} 1351 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1352 | hasBin: true 1353 | 1354 | natural-compare@1.4.0: 1355 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 1356 | 1357 | node-releases@2.0.21: 1358 | resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} 1359 | 1360 | obs-websocket-js@5.0.6: 1361 | resolution: {integrity: sha512-tHRq8py1XrdlMhSV+N/KTGHqoRIcsBBXbjcA9ex21k128iQ7YXjxzNWs3s9gidP1tEcIyVuJu8FnPgrSBWGm0Q==} 1362 | engines: {node: '>16.0'} 1363 | 1364 | ohash@2.0.11: 1365 | resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} 1366 | 1367 | optionator@0.9.4: 1368 | resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} 1369 | engines: {node: '>= 0.8.0'} 1370 | 1371 | p-limit@3.1.0: 1372 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 1373 | engines: {node: '>=10'} 1374 | 1375 | p-locate@5.0.0: 1376 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 1377 | engines: {node: '>=10'} 1378 | 1379 | parent-module@1.0.1: 1380 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 1381 | engines: {node: '>=6'} 1382 | 1383 | path-exists@4.0.0: 1384 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 1385 | engines: {node: '>=8'} 1386 | 1387 | path-key@3.1.1: 1388 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 1389 | engines: {node: '>=8'} 1390 | 1391 | path-to-regexp@6.3.0: 1392 | resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} 1393 | 1394 | pathe@2.0.3: 1395 | resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} 1396 | 1397 | picocolors@1.1.1: 1398 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 1399 | 1400 | picomatch@2.3.1: 1401 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1402 | engines: {node: '>=8.6'} 1403 | 1404 | picomatch@4.0.3: 1405 | resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} 1406 | engines: {node: '>=12'} 1407 | 1408 | postcss@8.5.6: 1409 | resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} 1410 | engines: {node: ^10 || ^12 || >=14} 1411 | 1412 | prelude-ls@1.2.1: 1413 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 1414 | engines: {node: '>= 0.8.0'} 1415 | 1416 | punycode@2.3.1: 1417 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 1418 | engines: {node: '>=6'} 1419 | 1420 | queue-microtask@1.2.3: 1421 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1422 | 1423 | react-dom@19.1.1: 1424 | resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} 1425 | peerDependencies: 1426 | react: ^19.1.1 1427 | 1428 | react-refresh@0.17.0: 1429 | resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} 1430 | engines: {node: '>=0.10.0'} 1431 | 1432 | react@19.1.1: 1433 | resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} 1434 | engines: {node: '>=0.10.0'} 1435 | 1436 | redux@5.0.1: 1437 | resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} 1438 | 1439 | resolve-from@4.0.0: 1440 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 1441 | engines: {node: '>=4'} 1442 | 1443 | reusify@1.1.0: 1444 | resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} 1445 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1446 | 1447 | rollup@4.50.1: 1448 | resolution: {integrity: sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA==} 1449 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 1450 | hasBin: true 1451 | 1452 | run-parallel@1.2.0: 1453 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1454 | 1455 | scheduler@0.26.0: 1456 | resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} 1457 | 1458 | semver@6.3.1: 1459 | resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} 1460 | hasBin: true 1461 | 1462 | semver@7.7.2: 1463 | resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} 1464 | engines: {node: '>=10'} 1465 | hasBin: true 1466 | 1467 | sharp@0.33.5: 1468 | resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} 1469 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 1470 | 1471 | shebang-command@2.0.0: 1472 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1473 | engines: {node: '>=8'} 1474 | 1475 | shebang-regex@3.0.0: 1476 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1477 | engines: {node: '>=8'} 1478 | 1479 | simple-swizzle@0.2.2: 1480 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} 1481 | 1482 | source-map-js@1.2.1: 1483 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 1484 | engines: {node: '>=0.10.0'} 1485 | 1486 | stoppable@1.1.0: 1487 | resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} 1488 | engines: {node: '>=4', npm: '>=6'} 1489 | 1490 | strip-json-comments@3.1.1: 1491 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 1492 | engines: {node: '>=8'} 1493 | 1494 | supports-color@10.2.2: 1495 | resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} 1496 | engines: {node: '>=18'} 1497 | 1498 | supports-color@7.2.0: 1499 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1500 | engines: {node: '>=8'} 1501 | 1502 | tinyglobby@0.2.15: 1503 | resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} 1504 | engines: {node: '>=12.0.0'} 1505 | 1506 | to-regex-range@5.0.1: 1507 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1508 | engines: {node: '>=8.0'} 1509 | 1510 | ts-api-utils@2.1.0: 1511 | resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} 1512 | engines: {node: '>=18.12'} 1513 | peerDependencies: 1514 | typescript: '>=4.8.4' 1515 | 1516 | tslib@2.8.1: 1517 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 1518 | 1519 | type-check@0.4.0: 1520 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 1521 | engines: {node: '>= 0.8.0'} 1522 | 1523 | type-fest@3.13.1: 1524 | resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} 1525 | engines: {node: '>=14.16'} 1526 | 1527 | typescript-eslint@8.43.0: 1528 | resolution: {integrity: sha512-FyRGJKUGvcFekRRcBKFBlAhnp4Ng8rhe8tuvvkR9OiU0gfd4vyvTRQHEckO6VDlH57jbeUQem2IpqPq9kLJH+w==} 1529 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1530 | peerDependencies: 1531 | eslint: ^8.57.0 || ^9.0.0 1532 | typescript: '>=4.8.4 <6.0.0' 1533 | 1534 | typescript@5.8.3: 1535 | resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} 1536 | engines: {node: '>=14.17'} 1537 | hasBin: true 1538 | 1539 | ufo@1.6.1: 1540 | resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} 1541 | 1542 | undici-types@6.21.0: 1543 | resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} 1544 | 1545 | undici@7.14.0: 1546 | resolution: {integrity: sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==} 1547 | engines: {node: '>=20.18.1'} 1548 | 1549 | unenv@2.0.0-rc.21: 1550 | resolution: {integrity: sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A==} 1551 | 1552 | update-browserslist-db@1.1.3: 1553 | resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} 1554 | hasBin: true 1555 | peerDependencies: 1556 | browserslist: '>= 4.21.0' 1557 | 1558 | uri-js@4.4.1: 1559 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 1560 | 1561 | vite@6.3.6: 1562 | resolution: {integrity: sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==} 1563 | engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} 1564 | hasBin: true 1565 | peerDependencies: 1566 | '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 1567 | jiti: '>=1.21.0' 1568 | less: '*' 1569 | lightningcss: ^1.21.0 1570 | sass: '*' 1571 | sass-embedded: '*' 1572 | stylus: '*' 1573 | sugarss: '*' 1574 | terser: ^5.16.0 1575 | tsx: ^4.8.1 1576 | yaml: ^2.4.2 1577 | peerDependenciesMeta: 1578 | '@types/node': 1579 | optional: true 1580 | jiti: 1581 | optional: true 1582 | less: 1583 | optional: true 1584 | lightningcss: 1585 | optional: true 1586 | sass: 1587 | optional: true 1588 | sass-embedded: 1589 | optional: true 1590 | stylus: 1591 | optional: true 1592 | sugarss: 1593 | optional: true 1594 | terser: 1595 | optional: true 1596 | tsx: 1597 | optional: true 1598 | yaml: 1599 | optional: true 1600 | 1601 | which@2.0.2: 1602 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1603 | engines: {node: '>= 8'} 1604 | hasBin: true 1605 | 1606 | word-wrap@1.2.5: 1607 | resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} 1608 | engines: {node: '>=0.10.0'} 1609 | 1610 | workerd@1.20250906.0: 1611 | resolution: {integrity: sha512-ryVyEaqXPPsr/AxccRmYZZmDAkfQVjhfRqrNTlEeN8aftBk6Ca1u7/VqmfOayjCXrA+O547TauebU+J3IpvFXw==} 1612 | engines: {node: '>=16'} 1613 | hasBin: true 1614 | 1615 | wrangler@4.36.0: 1616 | resolution: {integrity: sha512-J1sZh7ePy7BtzvIyt9ufiL6aQOW6OE0VEi9YJiyXOuaXDKrR7V5HJBTsraNdFDqXgi30mYGGBVs0mgZHGRhTBA==} 1617 | engines: {node: '>=18.0.0'} 1618 | hasBin: true 1619 | peerDependencies: 1620 | '@cloudflare/workers-types': ^4.20250906.0 1621 | peerDependenciesMeta: 1622 | '@cloudflare/workers-types': 1623 | optional: true 1624 | 1625 | ws@8.18.0: 1626 | resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} 1627 | engines: {node: '>=10.0.0'} 1628 | peerDependencies: 1629 | bufferutil: ^4.0.1 1630 | utf-8-validate: '>=5.0.2' 1631 | peerDependenciesMeta: 1632 | bufferutil: 1633 | optional: true 1634 | utf-8-validate: 1635 | optional: true 1636 | 1637 | ws@8.18.3: 1638 | resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} 1639 | engines: {node: '>=10.0.0'} 1640 | peerDependencies: 1641 | bufferutil: ^4.0.1 1642 | utf-8-validate: '>=5.0.2' 1643 | peerDependenciesMeta: 1644 | bufferutil: 1645 | optional: true 1646 | utf-8-validate: 1647 | optional: true 1648 | 1649 | yallist@3.1.1: 1650 | resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} 1651 | 1652 | yocto-queue@0.1.0: 1653 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 1654 | engines: {node: '>=10'} 1655 | 1656 | youch-core@0.3.3: 1657 | resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} 1658 | 1659 | youch@4.1.0-beta.10: 1660 | resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} 1661 | 1662 | zod@3.22.3: 1663 | resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} 1664 | 1665 | zustand-devtools@1.1.0: 1666 | resolution: {integrity: sha512-TfH8jv3M0fa0tFxgq1j+X6qCRE3/Z3W2Woutf82IPwmrMi+3Gytb43hka1tQg8Xm2So0uitJe1lIkikoaqv6JQ==} 1667 | peerDependencies: 1668 | typescript: '*' 1669 | zustand: '*' 1670 | 1671 | zustand@5.0.8: 1672 | resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==} 1673 | engines: {node: '>=12.20.0'} 1674 | peerDependencies: 1675 | '@types/react': '>=18.0.0' 1676 | immer: '>=9.0.6' 1677 | react: '>=18.0.0' 1678 | use-sync-external-store: '>=1.2.0' 1679 | peerDependenciesMeta: 1680 | '@types/react': 1681 | optional: true 1682 | immer: 1683 | optional: true 1684 | react: 1685 | optional: true 1686 | use-sync-external-store: 1687 | optional: true 1688 | 1689 | snapshots: 1690 | 1691 | '@babel/code-frame@7.27.1': 1692 | dependencies: 1693 | '@babel/helper-validator-identifier': 7.27.1 1694 | js-tokens: 4.0.0 1695 | picocolors: 1.1.1 1696 | 1697 | '@babel/compat-data@7.28.4': {} 1698 | 1699 | '@babel/core@7.28.4': 1700 | dependencies: 1701 | '@babel/code-frame': 7.27.1 1702 | '@babel/generator': 7.28.3 1703 | '@babel/helper-compilation-targets': 7.27.2 1704 | '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) 1705 | '@babel/helpers': 7.28.4 1706 | '@babel/parser': 7.28.4 1707 | '@babel/template': 7.27.2 1708 | '@babel/traverse': 7.28.4 1709 | '@babel/types': 7.28.4 1710 | '@jridgewell/remapping': 2.3.5 1711 | convert-source-map: 2.0.0 1712 | debug: 4.4.1 1713 | gensync: 1.0.0-beta.2 1714 | json5: 2.2.3 1715 | semver: 6.3.1 1716 | transitivePeerDependencies: 1717 | - supports-color 1718 | 1719 | '@babel/generator@7.28.3': 1720 | dependencies: 1721 | '@babel/parser': 7.28.4 1722 | '@babel/types': 7.28.4 1723 | '@jridgewell/gen-mapping': 0.3.13 1724 | '@jridgewell/trace-mapping': 0.3.31 1725 | jsesc: 3.1.0 1726 | 1727 | '@babel/helper-compilation-targets@7.27.2': 1728 | dependencies: 1729 | '@babel/compat-data': 7.28.4 1730 | '@babel/helper-validator-option': 7.27.1 1731 | browserslist: 4.26.0 1732 | lru-cache: 5.1.1 1733 | semver: 6.3.1 1734 | 1735 | '@babel/helper-globals@7.28.0': {} 1736 | 1737 | '@babel/helper-module-imports@7.27.1': 1738 | dependencies: 1739 | '@babel/traverse': 7.28.4 1740 | '@babel/types': 7.28.4 1741 | transitivePeerDependencies: 1742 | - supports-color 1743 | 1744 | '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': 1745 | dependencies: 1746 | '@babel/core': 7.28.4 1747 | '@babel/helper-module-imports': 7.27.1 1748 | '@babel/helper-validator-identifier': 7.27.1 1749 | '@babel/traverse': 7.28.4 1750 | transitivePeerDependencies: 1751 | - supports-color 1752 | 1753 | '@babel/helper-plugin-utils@7.27.1': {} 1754 | 1755 | '@babel/helper-string-parser@7.27.1': {} 1756 | 1757 | '@babel/helper-validator-identifier@7.27.1': {} 1758 | 1759 | '@babel/helper-validator-option@7.27.1': {} 1760 | 1761 | '@babel/helpers@7.28.4': 1762 | dependencies: 1763 | '@babel/template': 7.27.2 1764 | '@babel/types': 7.28.4 1765 | 1766 | '@babel/parser@7.28.4': 1767 | dependencies: 1768 | '@babel/types': 7.28.4 1769 | 1770 | '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.4)': 1771 | dependencies: 1772 | '@babel/core': 7.28.4 1773 | '@babel/helper-plugin-utils': 7.27.1 1774 | 1775 | '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.4)': 1776 | dependencies: 1777 | '@babel/core': 7.28.4 1778 | '@babel/helper-plugin-utils': 7.27.1 1779 | 1780 | '@babel/runtime@7.28.4': {} 1781 | 1782 | '@babel/template@7.27.2': 1783 | dependencies: 1784 | '@babel/code-frame': 7.27.1 1785 | '@babel/parser': 7.28.4 1786 | '@babel/types': 7.28.4 1787 | 1788 | '@babel/traverse@7.28.4': 1789 | dependencies: 1790 | '@babel/code-frame': 7.27.1 1791 | '@babel/generator': 7.28.3 1792 | '@babel/helper-globals': 7.28.0 1793 | '@babel/parser': 7.28.4 1794 | '@babel/template': 7.27.2 1795 | '@babel/types': 7.28.4 1796 | debug: 4.4.1 1797 | transitivePeerDependencies: 1798 | - supports-color 1799 | 1800 | '@babel/types@7.28.4': 1801 | dependencies: 1802 | '@babel/helper-string-parser': 7.27.1 1803 | '@babel/helper-validator-identifier': 7.27.1 1804 | 1805 | '@cloudflare/kv-asset-handler@0.4.0': 1806 | dependencies: 1807 | mime: 3.0.0 1808 | 1809 | '@cloudflare/unenv-preset@2.7.3(unenv@2.0.0-rc.21)(workerd@1.20250906.0)': 1810 | dependencies: 1811 | unenv: 2.0.0-rc.21 1812 | optionalDependencies: 1813 | workerd: 1.20250906.0 1814 | 1815 | '@cloudflare/vite-plugin@1.13.0(vite@6.3.6(@types/node@22.18.2))(workerd@1.20250906.0)(wrangler@4.36.0)': 1816 | dependencies: 1817 | '@cloudflare/unenv-preset': 2.7.3(unenv@2.0.0-rc.21)(workerd@1.20250906.0) 1818 | '@remix-run/node-fetch-server': 0.8.1 1819 | get-port: 7.1.0 1820 | miniflare: 4.20250906.1 1821 | picocolors: 1.1.1 1822 | tinyglobby: 0.2.15 1823 | unenv: 2.0.0-rc.21 1824 | vite: 6.3.6(@types/node@22.18.2) 1825 | wrangler: 4.36.0 1826 | ws: 8.18.0 1827 | transitivePeerDependencies: 1828 | - bufferutil 1829 | - utf-8-validate 1830 | - workerd 1831 | 1832 | '@cloudflare/workerd-darwin-64@1.20250906.0': 1833 | optional: true 1834 | 1835 | '@cloudflare/workerd-darwin-arm64@1.20250906.0': 1836 | optional: true 1837 | 1838 | '@cloudflare/workerd-linux-64@1.20250906.0': 1839 | optional: true 1840 | 1841 | '@cloudflare/workerd-linux-arm64@1.20250906.0': 1842 | optional: true 1843 | 1844 | '@cloudflare/workerd-windows-64@1.20250906.0': 1845 | optional: true 1846 | 1847 | '@cspotcode/source-map-support@0.8.1': 1848 | dependencies: 1849 | '@jridgewell/trace-mapping': 0.3.9 1850 | 1851 | '@emnapi/runtime@1.5.0': 1852 | dependencies: 1853 | tslib: 2.8.1 1854 | optional: true 1855 | 1856 | '@esbuild/aix-ppc64@0.25.4': 1857 | optional: true 1858 | 1859 | '@esbuild/aix-ppc64@0.25.9': 1860 | optional: true 1861 | 1862 | '@esbuild/android-arm64@0.25.4': 1863 | optional: true 1864 | 1865 | '@esbuild/android-arm64@0.25.9': 1866 | optional: true 1867 | 1868 | '@esbuild/android-arm@0.25.4': 1869 | optional: true 1870 | 1871 | '@esbuild/android-arm@0.25.9': 1872 | optional: true 1873 | 1874 | '@esbuild/android-x64@0.25.4': 1875 | optional: true 1876 | 1877 | '@esbuild/android-x64@0.25.9': 1878 | optional: true 1879 | 1880 | '@esbuild/darwin-arm64@0.25.4': 1881 | optional: true 1882 | 1883 | '@esbuild/darwin-arm64@0.25.9': 1884 | optional: true 1885 | 1886 | '@esbuild/darwin-x64@0.25.4': 1887 | optional: true 1888 | 1889 | '@esbuild/darwin-x64@0.25.9': 1890 | optional: true 1891 | 1892 | '@esbuild/freebsd-arm64@0.25.4': 1893 | optional: true 1894 | 1895 | '@esbuild/freebsd-arm64@0.25.9': 1896 | optional: true 1897 | 1898 | '@esbuild/freebsd-x64@0.25.4': 1899 | optional: true 1900 | 1901 | '@esbuild/freebsd-x64@0.25.9': 1902 | optional: true 1903 | 1904 | '@esbuild/linux-arm64@0.25.4': 1905 | optional: true 1906 | 1907 | '@esbuild/linux-arm64@0.25.9': 1908 | optional: true 1909 | 1910 | '@esbuild/linux-arm@0.25.4': 1911 | optional: true 1912 | 1913 | '@esbuild/linux-arm@0.25.9': 1914 | optional: true 1915 | 1916 | '@esbuild/linux-ia32@0.25.4': 1917 | optional: true 1918 | 1919 | '@esbuild/linux-ia32@0.25.9': 1920 | optional: true 1921 | 1922 | '@esbuild/linux-loong64@0.25.4': 1923 | optional: true 1924 | 1925 | '@esbuild/linux-loong64@0.25.9': 1926 | optional: true 1927 | 1928 | '@esbuild/linux-mips64el@0.25.4': 1929 | optional: true 1930 | 1931 | '@esbuild/linux-mips64el@0.25.9': 1932 | optional: true 1933 | 1934 | '@esbuild/linux-ppc64@0.25.4': 1935 | optional: true 1936 | 1937 | '@esbuild/linux-ppc64@0.25.9': 1938 | optional: true 1939 | 1940 | '@esbuild/linux-riscv64@0.25.4': 1941 | optional: true 1942 | 1943 | '@esbuild/linux-riscv64@0.25.9': 1944 | optional: true 1945 | 1946 | '@esbuild/linux-s390x@0.25.4': 1947 | optional: true 1948 | 1949 | '@esbuild/linux-s390x@0.25.9': 1950 | optional: true 1951 | 1952 | '@esbuild/linux-x64@0.25.4': 1953 | optional: true 1954 | 1955 | '@esbuild/linux-x64@0.25.9': 1956 | optional: true 1957 | 1958 | '@esbuild/netbsd-arm64@0.25.4': 1959 | optional: true 1960 | 1961 | '@esbuild/netbsd-arm64@0.25.9': 1962 | optional: true 1963 | 1964 | '@esbuild/netbsd-x64@0.25.4': 1965 | optional: true 1966 | 1967 | '@esbuild/netbsd-x64@0.25.9': 1968 | optional: true 1969 | 1970 | '@esbuild/openbsd-arm64@0.25.4': 1971 | optional: true 1972 | 1973 | '@esbuild/openbsd-arm64@0.25.9': 1974 | optional: true 1975 | 1976 | '@esbuild/openbsd-x64@0.25.4': 1977 | optional: true 1978 | 1979 | '@esbuild/openbsd-x64@0.25.9': 1980 | optional: true 1981 | 1982 | '@esbuild/openharmony-arm64@0.25.9': 1983 | optional: true 1984 | 1985 | '@esbuild/sunos-x64@0.25.4': 1986 | optional: true 1987 | 1988 | '@esbuild/sunos-x64@0.25.9': 1989 | optional: true 1990 | 1991 | '@esbuild/win32-arm64@0.25.4': 1992 | optional: true 1993 | 1994 | '@esbuild/win32-arm64@0.25.9': 1995 | optional: true 1996 | 1997 | '@esbuild/win32-ia32@0.25.4': 1998 | optional: true 1999 | 2000 | '@esbuild/win32-ia32@0.25.9': 2001 | optional: true 2002 | 2003 | '@esbuild/win32-x64@0.25.4': 2004 | optional: true 2005 | 2006 | '@esbuild/win32-x64@0.25.9': 2007 | optional: true 2008 | 2009 | '@eslint-community/eslint-utils@4.9.0(eslint@9.35.0)': 2010 | dependencies: 2011 | eslint: 9.35.0 2012 | eslint-visitor-keys: 3.4.3 2013 | 2014 | '@eslint-community/regexpp@4.12.1': {} 2015 | 2016 | '@eslint/config-array@0.21.0': 2017 | dependencies: 2018 | '@eslint/object-schema': 2.1.6 2019 | debug: 4.4.1 2020 | minimatch: 3.1.2 2021 | transitivePeerDependencies: 2022 | - supports-color 2023 | 2024 | '@eslint/config-helpers@0.3.1': {} 2025 | 2026 | '@eslint/core@0.15.2': 2027 | dependencies: 2028 | '@types/json-schema': 7.0.15 2029 | 2030 | '@eslint/eslintrc@3.3.1': 2031 | dependencies: 2032 | ajv: 6.12.6 2033 | debug: 4.4.1 2034 | espree: 10.4.0 2035 | globals: 14.0.0 2036 | ignore: 5.3.2 2037 | import-fresh: 3.3.1 2038 | js-yaml: 4.1.0 2039 | minimatch: 3.1.2 2040 | strip-json-comments: 3.1.1 2041 | transitivePeerDependencies: 2042 | - supports-color 2043 | 2044 | '@eslint/js@9.35.0': {} 2045 | 2046 | '@eslint/object-schema@2.1.6': {} 2047 | 2048 | '@eslint/plugin-kit@0.3.5': 2049 | dependencies: 2050 | '@eslint/core': 0.15.2 2051 | levn: 0.4.1 2052 | 2053 | '@humanfs/core@0.19.1': {} 2054 | 2055 | '@humanfs/node@0.16.7': 2056 | dependencies: 2057 | '@humanfs/core': 0.19.1 2058 | '@humanwhocodes/retry': 0.4.3 2059 | 2060 | '@humanwhocodes/module-importer@1.0.1': {} 2061 | 2062 | '@humanwhocodes/retry@0.4.3': {} 2063 | 2064 | '@img/sharp-darwin-arm64@0.33.5': 2065 | optionalDependencies: 2066 | '@img/sharp-libvips-darwin-arm64': 1.0.4 2067 | optional: true 2068 | 2069 | '@img/sharp-darwin-x64@0.33.5': 2070 | optionalDependencies: 2071 | '@img/sharp-libvips-darwin-x64': 1.0.4 2072 | optional: true 2073 | 2074 | '@img/sharp-libvips-darwin-arm64@1.0.4': 2075 | optional: true 2076 | 2077 | '@img/sharp-libvips-darwin-x64@1.0.4': 2078 | optional: true 2079 | 2080 | '@img/sharp-libvips-linux-arm64@1.0.4': 2081 | optional: true 2082 | 2083 | '@img/sharp-libvips-linux-arm@1.0.5': 2084 | optional: true 2085 | 2086 | '@img/sharp-libvips-linux-s390x@1.0.4': 2087 | optional: true 2088 | 2089 | '@img/sharp-libvips-linux-x64@1.0.4': 2090 | optional: true 2091 | 2092 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4': 2093 | optional: true 2094 | 2095 | '@img/sharp-libvips-linuxmusl-x64@1.0.4': 2096 | optional: true 2097 | 2098 | '@img/sharp-linux-arm64@0.33.5': 2099 | optionalDependencies: 2100 | '@img/sharp-libvips-linux-arm64': 1.0.4 2101 | optional: true 2102 | 2103 | '@img/sharp-linux-arm@0.33.5': 2104 | optionalDependencies: 2105 | '@img/sharp-libvips-linux-arm': 1.0.5 2106 | optional: true 2107 | 2108 | '@img/sharp-linux-s390x@0.33.5': 2109 | optionalDependencies: 2110 | '@img/sharp-libvips-linux-s390x': 1.0.4 2111 | optional: true 2112 | 2113 | '@img/sharp-linux-x64@0.33.5': 2114 | optionalDependencies: 2115 | '@img/sharp-libvips-linux-x64': 1.0.4 2116 | optional: true 2117 | 2118 | '@img/sharp-linuxmusl-arm64@0.33.5': 2119 | optionalDependencies: 2120 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 2121 | optional: true 2122 | 2123 | '@img/sharp-linuxmusl-x64@0.33.5': 2124 | optionalDependencies: 2125 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4 2126 | optional: true 2127 | 2128 | '@img/sharp-wasm32@0.33.5': 2129 | dependencies: 2130 | '@emnapi/runtime': 1.5.0 2131 | optional: true 2132 | 2133 | '@img/sharp-win32-ia32@0.33.5': 2134 | optional: true 2135 | 2136 | '@img/sharp-win32-x64@0.33.5': 2137 | optional: true 2138 | 2139 | '@jridgewell/gen-mapping@0.3.13': 2140 | dependencies: 2141 | '@jridgewell/sourcemap-codec': 1.5.5 2142 | '@jridgewell/trace-mapping': 0.3.31 2143 | 2144 | '@jridgewell/remapping@2.3.5': 2145 | dependencies: 2146 | '@jridgewell/gen-mapping': 0.3.13 2147 | '@jridgewell/trace-mapping': 0.3.31 2148 | 2149 | '@jridgewell/resolve-uri@3.1.2': {} 2150 | 2151 | '@jridgewell/sourcemap-codec@1.5.5': {} 2152 | 2153 | '@jridgewell/trace-mapping@0.3.31': 2154 | dependencies: 2155 | '@jridgewell/resolve-uri': 3.1.2 2156 | '@jridgewell/sourcemap-codec': 1.5.5 2157 | 2158 | '@jridgewell/trace-mapping@0.3.9': 2159 | dependencies: 2160 | '@jridgewell/resolve-uri': 3.1.2 2161 | '@jridgewell/sourcemap-codec': 1.5.5 2162 | 2163 | '@msgpack/msgpack@2.8.0': {} 2164 | 2165 | '@nodelib/fs.scandir@2.1.5': 2166 | dependencies: 2167 | '@nodelib/fs.stat': 2.0.5 2168 | run-parallel: 1.2.0 2169 | 2170 | '@nodelib/fs.stat@2.0.5': {} 2171 | 2172 | '@nodelib/fs.walk@1.2.8': 2173 | dependencies: 2174 | '@nodelib/fs.scandir': 2.1.5 2175 | fastq: 1.19.1 2176 | 2177 | '@poppinss/colors@4.1.5': 2178 | dependencies: 2179 | kleur: 4.1.5 2180 | 2181 | '@poppinss/dumper@0.6.4': 2182 | dependencies: 2183 | '@poppinss/colors': 4.1.5 2184 | '@sindresorhus/is': 7.0.2 2185 | supports-color: 10.2.2 2186 | 2187 | '@poppinss/exception@1.2.2': {} 2188 | 2189 | '@redux-devtools/extension@3.3.0(redux@5.0.1)': 2190 | dependencies: 2191 | '@babel/runtime': 7.28.4 2192 | immutable: 4.3.7 2193 | redux: 5.0.1 2194 | 2195 | '@remix-run/node-fetch-server@0.8.1': {} 2196 | 2197 | '@rolldown/pluginutils@1.0.0-beta.27': {} 2198 | 2199 | '@rollup/rollup-android-arm-eabi@4.50.1': 2200 | optional: true 2201 | 2202 | '@rollup/rollup-android-arm64@4.50.1': 2203 | optional: true 2204 | 2205 | '@rollup/rollup-darwin-arm64@4.50.1': 2206 | optional: true 2207 | 2208 | '@rollup/rollup-darwin-x64@4.50.1': 2209 | optional: true 2210 | 2211 | '@rollup/rollup-freebsd-arm64@4.50.1': 2212 | optional: true 2213 | 2214 | '@rollup/rollup-freebsd-x64@4.50.1': 2215 | optional: true 2216 | 2217 | '@rollup/rollup-linux-arm-gnueabihf@4.50.1': 2218 | optional: true 2219 | 2220 | '@rollup/rollup-linux-arm-musleabihf@4.50.1': 2221 | optional: true 2222 | 2223 | '@rollup/rollup-linux-arm64-gnu@4.50.1': 2224 | optional: true 2225 | 2226 | '@rollup/rollup-linux-arm64-musl@4.50.1': 2227 | optional: true 2228 | 2229 | '@rollup/rollup-linux-loongarch64-gnu@4.50.1': 2230 | optional: true 2231 | 2232 | '@rollup/rollup-linux-ppc64-gnu@4.50.1': 2233 | optional: true 2234 | 2235 | '@rollup/rollup-linux-riscv64-gnu@4.50.1': 2236 | optional: true 2237 | 2238 | '@rollup/rollup-linux-riscv64-musl@4.50.1': 2239 | optional: true 2240 | 2241 | '@rollup/rollup-linux-s390x-gnu@4.50.1': 2242 | optional: true 2243 | 2244 | '@rollup/rollup-linux-x64-gnu@4.50.1': 2245 | optional: true 2246 | 2247 | '@rollup/rollup-linux-x64-musl@4.50.1': 2248 | optional: true 2249 | 2250 | '@rollup/rollup-openharmony-arm64@4.50.1': 2251 | optional: true 2252 | 2253 | '@rollup/rollup-win32-arm64-msvc@4.50.1': 2254 | optional: true 2255 | 2256 | '@rollup/rollup-win32-ia32-msvc@4.50.1': 2257 | optional: true 2258 | 2259 | '@rollup/rollup-win32-x64-msvc@4.50.1': 2260 | optional: true 2261 | 2262 | '@sindresorhus/is@7.0.2': {} 2263 | 2264 | '@speed-highlight/core@1.2.7': {} 2265 | 2266 | '@types/babel__core@7.20.5': 2267 | dependencies: 2268 | '@babel/parser': 7.28.4 2269 | '@babel/types': 7.28.4 2270 | '@types/babel__generator': 7.27.0 2271 | '@types/babel__template': 7.4.4 2272 | '@types/babel__traverse': 7.28.0 2273 | 2274 | '@types/babel__generator@7.27.0': 2275 | dependencies: 2276 | '@babel/types': 7.28.4 2277 | 2278 | '@types/babel__template@7.4.4': 2279 | dependencies: 2280 | '@babel/parser': 7.28.4 2281 | '@babel/types': 7.28.4 2282 | 2283 | '@types/babel__traverse@7.28.0': 2284 | dependencies: 2285 | '@babel/types': 7.28.4 2286 | 2287 | '@types/estree@1.0.8': {} 2288 | 2289 | '@types/json-schema@7.0.15': {} 2290 | 2291 | '@types/node@22.18.2': 2292 | dependencies: 2293 | undici-types: 6.21.0 2294 | 2295 | '@types/react-dom@19.1.9(@types/react@19.1.13)': 2296 | dependencies: 2297 | '@types/react': 19.1.13 2298 | 2299 | '@types/react@19.1.13': 2300 | dependencies: 2301 | csstype: 3.1.3 2302 | 2303 | '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.8.3))(eslint@9.35.0)(typescript@5.8.3)': 2304 | dependencies: 2305 | '@eslint-community/regexpp': 4.12.1 2306 | '@typescript-eslint/parser': 8.43.0(eslint@9.35.0)(typescript@5.8.3) 2307 | '@typescript-eslint/scope-manager': 8.43.0 2308 | '@typescript-eslint/type-utils': 8.43.0(eslint@9.35.0)(typescript@5.8.3) 2309 | '@typescript-eslint/utils': 8.43.0(eslint@9.35.0)(typescript@5.8.3) 2310 | '@typescript-eslint/visitor-keys': 8.43.0 2311 | eslint: 9.35.0 2312 | graphemer: 1.4.0 2313 | ignore: 7.0.5 2314 | natural-compare: 1.4.0 2315 | ts-api-utils: 2.1.0(typescript@5.8.3) 2316 | typescript: 5.8.3 2317 | transitivePeerDependencies: 2318 | - supports-color 2319 | 2320 | '@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.8.3)': 2321 | dependencies: 2322 | '@typescript-eslint/scope-manager': 8.43.0 2323 | '@typescript-eslint/types': 8.43.0 2324 | '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.8.3) 2325 | '@typescript-eslint/visitor-keys': 8.43.0 2326 | debug: 4.4.1 2327 | eslint: 9.35.0 2328 | typescript: 5.8.3 2329 | transitivePeerDependencies: 2330 | - supports-color 2331 | 2332 | '@typescript-eslint/project-service@8.43.0(typescript@5.8.3)': 2333 | dependencies: 2334 | '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.8.3) 2335 | '@typescript-eslint/types': 8.43.0 2336 | debug: 4.4.1 2337 | typescript: 5.8.3 2338 | transitivePeerDependencies: 2339 | - supports-color 2340 | 2341 | '@typescript-eslint/scope-manager@8.43.0': 2342 | dependencies: 2343 | '@typescript-eslint/types': 8.43.0 2344 | '@typescript-eslint/visitor-keys': 8.43.0 2345 | 2346 | '@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.8.3)': 2347 | dependencies: 2348 | typescript: 5.8.3 2349 | 2350 | '@typescript-eslint/type-utils@8.43.0(eslint@9.35.0)(typescript@5.8.3)': 2351 | dependencies: 2352 | '@typescript-eslint/types': 8.43.0 2353 | '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.8.3) 2354 | '@typescript-eslint/utils': 8.43.0(eslint@9.35.0)(typescript@5.8.3) 2355 | debug: 4.4.1 2356 | eslint: 9.35.0 2357 | ts-api-utils: 2.1.0(typescript@5.8.3) 2358 | typescript: 5.8.3 2359 | transitivePeerDependencies: 2360 | - supports-color 2361 | 2362 | '@typescript-eslint/types@8.43.0': {} 2363 | 2364 | '@typescript-eslint/typescript-estree@8.43.0(typescript@5.8.3)': 2365 | dependencies: 2366 | '@typescript-eslint/project-service': 8.43.0(typescript@5.8.3) 2367 | '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.8.3) 2368 | '@typescript-eslint/types': 8.43.0 2369 | '@typescript-eslint/visitor-keys': 8.43.0 2370 | debug: 4.4.1 2371 | fast-glob: 3.3.3 2372 | is-glob: 4.0.3 2373 | minimatch: 9.0.5 2374 | semver: 7.7.2 2375 | ts-api-utils: 2.1.0(typescript@5.8.3) 2376 | typescript: 5.8.3 2377 | transitivePeerDependencies: 2378 | - supports-color 2379 | 2380 | '@typescript-eslint/utils@8.43.0(eslint@9.35.0)(typescript@5.8.3)': 2381 | dependencies: 2382 | '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0) 2383 | '@typescript-eslint/scope-manager': 8.43.0 2384 | '@typescript-eslint/types': 8.43.0 2385 | '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.8.3) 2386 | eslint: 9.35.0 2387 | typescript: 5.8.3 2388 | transitivePeerDependencies: 2389 | - supports-color 2390 | 2391 | '@typescript-eslint/visitor-keys@8.43.0': 2392 | dependencies: 2393 | '@typescript-eslint/types': 8.43.0 2394 | eslint-visitor-keys: 4.2.1 2395 | 2396 | '@vitejs/plugin-react@4.7.0(vite@6.3.6(@types/node@22.18.2))': 2397 | dependencies: 2398 | '@babel/core': 7.28.4 2399 | '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) 2400 | '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.4) 2401 | '@rolldown/pluginutils': 1.0.0-beta.27 2402 | '@types/babel__core': 7.20.5 2403 | react-refresh: 0.17.0 2404 | vite: 6.3.6(@types/node@22.18.2) 2405 | transitivePeerDependencies: 2406 | - supports-color 2407 | 2408 | acorn-jsx@5.3.2(acorn@8.15.0): 2409 | dependencies: 2410 | acorn: 8.15.0 2411 | 2412 | acorn-walk@8.3.2: {} 2413 | 2414 | acorn@8.14.0: {} 2415 | 2416 | acorn@8.15.0: {} 2417 | 2418 | ajv@6.12.6: 2419 | dependencies: 2420 | fast-deep-equal: 3.1.3 2421 | fast-json-stable-stringify: 2.1.0 2422 | json-schema-traverse: 0.4.1 2423 | uri-js: 4.4.1 2424 | 2425 | ansi-styles@4.3.0: 2426 | dependencies: 2427 | color-convert: 2.0.1 2428 | 2429 | argparse@2.0.1: {} 2430 | 2431 | balanced-match@1.0.2: {} 2432 | 2433 | baseline-browser-mapping@2.8.2: {} 2434 | 2435 | blake3-wasm@2.1.5: {} 2436 | 2437 | brace-expansion@1.1.12: 2438 | dependencies: 2439 | balanced-match: 1.0.2 2440 | concat-map: 0.0.1 2441 | 2442 | brace-expansion@2.0.2: 2443 | dependencies: 2444 | balanced-match: 1.0.2 2445 | 2446 | braces@3.0.3: 2447 | dependencies: 2448 | fill-range: 7.1.1 2449 | 2450 | browserslist@4.26.0: 2451 | dependencies: 2452 | baseline-browser-mapping: 2.8.2 2453 | caniuse-lite: 1.0.30001741 2454 | electron-to-chromium: 1.5.218 2455 | node-releases: 2.0.21 2456 | update-browserslist-db: 1.1.3(browserslist@4.26.0) 2457 | 2458 | callsites@3.1.0: {} 2459 | 2460 | caniuse-lite@1.0.30001741: {} 2461 | 2462 | chalk@4.1.2: 2463 | dependencies: 2464 | ansi-styles: 4.3.0 2465 | supports-color: 7.2.0 2466 | 2467 | color-convert@2.0.1: 2468 | dependencies: 2469 | color-name: 1.1.4 2470 | 2471 | color-name@1.1.4: {} 2472 | 2473 | color-string@1.9.1: 2474 | dependencies: 2475 | color-name: 1.1.4 2476 | simple-swizzle: 0.2.2 2477 | 2478 | color@4.2.3: 2479 | dependencies: 2480 | color-convert: 2.0.1 2481 | color-string: 1.9.1 2482 | 2483 | concat-map@0.0.1: {} 2484 | 2485 | convert-source-map@2.0.0: {} 2486 | 2487 | cookie@1.0.2: {} 2488 | 2489 | cross-spawn@7.0.6: 2490 | dependencies: 2491 | path-key: 3.1.1 2492 | shebang-command: 2.0.0 2493 | which: 2.0.2 2494 | 2495 | crypto-js@4.2.0: {} 2496 | 2497 | csstype@3.1.3: {} 2498 | 2499 | debug@4.4.1: 2500 | dependencies: 2501 | ms: 2.1.3 2502 | 2503 | deep-is@0.1.4: {} 2504 | 2505 | defu@6.1.4: {} 2506 | 2507 | detect-libc@2.0.4: {} 2508 | 2509 | electron-to-chromium@1.5.218: {} 2510 | 2511 | error-stack-parser-es@1.0.5: {} 2512 | 2513 | esbuild@0.25.4: 2514 | optionalDependencies: 2515 | '@esbuild/aix-ppc64': 0.25.4 2516 | '@esbuild/android-arm': 0.25.4 2517 | '@esbuild/android-arm64': 0.25.4 2518 | '@esbuild/android-x64': 0.25.4 2519 | '@esbuild/darwin-arm64': 0.25.4 2520 | '@esbuild/darwin-x64': 0.25.4 2521 | '@esbuild/freebsd-arm64': 0.25.4 2522 | '@esbuild/freebsd-x64': 0.25.4 2523 | '@esbuild/linux-arm': 0.25.4 2524 | '@esbuild/linux-arm64': 0.25.4 2525 | '@esbuild/linux-ia32': 0.25.4 2526 | '@esbuild/linux-loong64': 0.25.4 2527 | '@esbuild/linux-mips64el': 0.25.4 2528 | '@esbuild/linux-ppc64': 0.25.4 2529 | '@esbuild/linux-riscv64': 0.25.4 2530 | '@esbuild/linux-s390x': 0.25.4 2531 | '@esbuild/linux-x64': 0.25.4 2532 | '@esbuild/netbsd-arm64': 0.25.4 2533 | '@esbuild/netbsd-x64': 0.25.4 2534 | '@esbuild/openbsd-arm64': 0.25.4 2535 | '@esbuild/openbsd-x64': 0.25.4 2536 | '@esbuild/sunos-x64': 0.25.4 2537 | '@esbuild/win32-arm64': 0.25.4 2538 | '@esbuild/win32-ia32': 0.25.4 2539 | '@esbuild/win32-x64': 0.25.4 2540 | 2541 | esbuild@0.25.9: 2542 | optionalDependencies: 2543 | '@esbuild/aix-ppc64': 0.25.9 2544 | '@esbuild/android-arm': 0.25.9 2545 | '@esbuild/android-arm64': 0.25.9 2546 | '@esbuild/android-x64': 0.25.9 2547 | '@esbuild/darwin-arm64': 0.25.9 2548 | '@esbuild/darwin-x64': 0.25.9 2549 | '@esbuild/freebsd-arm64': 0.25.9 2550 | '@esbuild/freebsd-x64': 0.25.9 2551 | '@esbuild/linux-arm': 0.25.9 2552 | '@esbuild/linux-arm64': 0.25.9 2553 | '@esbuild/linux-ia32': 0.25.9 2554 | '@esbuild/linux-loong64': 0.25.9 2555 | '@esbuild/linux-mips64el': 0.25.9 2556 | '@esbuild/linux-ppc64': 0.25.9 2557 | '@esbuild/linux-riscv64': 0.25.9 2558 | '@esbuild/linux-s390x': 0.25.9 2559 | '@esbuild/linux-x64': 0.25.9 2560 | '@esbuild/netbsd-arm64': 0.25.9 2561 | '@esbuild/netbsd-x64': 0.25.9 2562 | '@esbuild/openbsd-arm64': 0.25.9 2563 | '@esbuild/openbsd-x64': 0.25.9 2564 | '@esbuild/openharmony-arm64': 0.25.9 2565 | '@esbuild/sunos-x64': 0.25.9 2566 | '@esbuild/win32-arm64': 0.25.9 2567 | '@esbuild/win32-ia32': 0.25.9 2568 | '@esbuild/win32-x64': 0.25.9 2569 | 2570 | escalade@3.2.0: {} 2571 | 2572 | escape-string-regexp@4.0.0: {} 2573 | 2574 | eslint-plugin-react-hooks@5.2.0(eslint@9.35.0): 2575 | dependencies: 2576 | eslint: 9.35.0 2577 | 2578 | eslint-plugin-react-refresh@0.4.20(eslint@9.35.0): 2579 | dependencies: 2580 | eslint: 9.35.0 2581 | 2582 | eslint-scope@8.4.0: 2583 | dependencies: 2584 | esrecurse: 4.3.0 2585 | estraverse: 5.3.0 2586 | 2587 | eslint-visitor-keys@3.4.3: {} 2588 | 2589 | eslint-visitor-keys@4.2.1: {} 2590 | 2591 | eslint@9.35.0: 2592 | dependencies: 2593 | '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0) 2594 | '@eslint-community/regexpp': 4.12.1 2595 | '@eslint/config-array': 0.21.0 2596 | '@eslint/config-helpers': 0.3.1 2597 | '@eslint/core': 0.15.2 2598 | '@eslint/eslintrc': 3.3.1 2599 | '@eslint/js': 9.35.0 2600 | '@eslint/plugin-kit': 0.3.5 2601 | '@humanfs/node': 0.16.7 2602 | '@humanwhocodes/module-importer': 1.0.1 2603 | '@humanwhocodes/retry': 0.4.3 2604 | '@types/estree': 1.0.8 2605 | '@types/json-schema': 7.0.15 2606 | ajv: 6.12.6 2607 | chalk: 4.1.2 2608 | cross-spawn: 7.0.6 2609 | debug: 4.4.1 2610 | escape-string-regexp: 4.0.0 2611 | eslint-scope: 8.4.0 2612 | eslint-visitor-keys: 4.2.1 2613 | espree: 10.4.0 2614 | esquery: 1.6.0 2615 | esutils: 2.0.3 2616 | fast-deep-equal: 3.1.3 2617 | file-entry-cache: 8.0.0 2618 | find-up: 5.0.0 2619 | glob-parent: 6.0.2 2620 | ignore: 5.3.2 2621 | imurmurhash: 0.1.4 2622 | is-glob: 4.0.3 2623 | json-stable-stringify-without-jsonify: 1.0.1 2624 | lodash.merge: 4.6.2 2625 | minimatch: 3.1.2 2626 | natural-compare: 1.4.0 2627 | optionator: 0.9.4 2628 | transitivePeerDependencies: 2629 | - supports-color 2630 | 2631 | espree@10.4.0: 2632 | dependencies: 2633 | acorn: 8.15.0 2634 | acorn-jsx: 5.3.2(acorn@8.15.0) 2635 | eslint-visitor-keys: 4.2.1 2636 | 2637 | esquery@1.6.0: 2638 | dependencies: 2639 | estraverse: 5.3.0 2640 | 2641 | esrecurse@4.3.0: 2642 | dependencies: 2643 | estraverse: 5.3.0 2644 | 2645 | estraverse@5.3.0: {} 2646 | 2647 | esutils@2.0.3: {} 2648 | 2649 | eventemitter3@5.0.1: {} 2650 | 2651 | exit-hook@2.2.1: {} 2652 | 2653 | exsolve@1.0.7: {} 2654 | 2655 | fast-deep-equal@3.1.3: {} 2656 | 2657 | fast-glob@3.3.3: 2658 | dependencies: 2659 | '@nodelib/fs.stat': 2.0.5 2660 | '@nodelib/fs.walk': 1.2.8 2661 | glob-parent: 5.1.2 2662 | merge2: 1.4.1 2663 | micromatch: 4.0.8 2664 | 2665 | fast-json-stable-stringify@2.1.0: {} 2666 | 2667 | fast-levenshtein@2.0.6: {} 2668 | 2669 | fastq@1.19.1: 2670 | dependencies: 2671 | reusify: 1.1.0 2672 | 2673 | fdir@6.5.0(picomatch@4.0.3): 2674 | optionalDependencies: 2675 | picomatch: 4.0.3 2676 | 2677 | file-entry-cache@8.0.0: 2678 | dependencies: 2679 | flat-cache: 4.0.1 2680 | 2681 | fill-range@7.1.1: 2682 | dependencies: 2683 | to-regex-range: 5.0.1 2684 | 2685 | find-up@5.0.0: 2686 | dependencies: 2687 | locate-path: 6.0.0 2688 | path-exists: 4.0.0 2689 | 2690 | flat-cache@4.0.1: 2691 | dependencies: 2692 | flatted: 3.3.3 2693 | keyv: 4.5.4 2694 | 2695 | flatted@3.3.3: {} 2696 | 2697 | fsevents@2.3.3: 2698 | optional: true 2699 | 2700 | gensync@1.0.0-beta.2: {} 2701 | 2702 | get-port@7.1.0: {} 2703 | 2704 | glob-parent@5.1.2: 2705 | dependencies: 2706 | is-glob: 4.0.3 2707 | 2708 | glob-parent@6.0.2: 2709 | dependencies: 2710 | is-glob: 4.0.3 2711 | 2712 | glob-to-regexp@0.4.1: {} 2713 | 2714 | globals@14.0.0: {} 2715 | 2716 | globals@16.4.0: {} 2717 | 2718 | graphemer@1.4.0: {} 2719 | 2720 | has-flag@4.0.0: {} 2721 | 2722 | ignore@5.3.2: {} 2723 | 2724 | ignore@7.0.5: {} 2725 | 2726 | immutable@4.3.7: {} 2727 | 2728 | import-fresh@3.3.1: 2729 | dependencies: 2730 | parent-module: 1.0.1 2731 | resolve-from: 4.0.0 2732 | 2733 | imurmurhash@0.1.4: {} 2734 | 2735 | is-arrayish@0.3.2: {} 2736 | 2737 | is-extglob@2.1.1: {} 2738 | 2739 | is-glob@4.0.3: 2740 | dependencies: 2741 | is-extglob: 2.1.1 2742 | 2743 | is-number@7.0.0: {} 2744 | 2745 | isexe@2.0.0: {} 2746 | 2747 | isomorphic-ws@5.0.0(ws@8.18.3): 2748 | dependencies: 2749 | ws: 8.18.3 2750 | 2751 | js-tokens@4.0.0: {} 2752 | 2753 | js-yaml@4.1.0: 2754 | dependencies: 2755 | argparse: 2.0.1 2756 | 2757 | jsesc@3.1.0: {} 2758 | 2759 | json-buffer@3.0.1: {} 2760 | 2761 | json-schema-traverse@0.4.1: {} 2762 | 2763 | json-stable-stringify-without-jsonify@1.0.1: {} 2764 | 2765 | json5@2.2.3: {} 2766 | 2767 | keyv@4.5.4: 2768 | dependencies: 2769 | json-buffer: 3.0.1 2770 | 2771 | kleur@4.1.5: {} 2772 | 2773 | levn@0.4.1: 2774 | dependencies: 2775 | prelude-ls: 1.2.1 2776 | type-check: 0.4.0 2777 | 2778 | locate-path@6.0.0: 2779 | dependencies: 2780 | p-locate: 5.0.0 2781 | 2782 | lodash.merge@4.6.2: {} 2783 | 2784 | lru-cache@5.1.1: 2785 | dependencies: 2786 | yallist: 3.1.1 2787 | 2788 | merge2@1.4.1: {} 2789 | 2790 | micromatch@4.0.8: 2791 | dependencies: 2792 | braces: 3.0.3 2793 | picomatch: 2.3.1 2794 | 2795 | mime@3.0.0: {} 2796 | 2797 | miniflare@4.20250906.1: 2798 | dependencies: 2799 | '@cspotcode/source-map-support': 0.8.1 2800 | acorn: 8.14.0 2801 | acorn-walk: 8.3.2 2802 | exit-hook: 2.2.1 2803 | glob-to-regexp: 0.4.1 2804 | sharp: 0.33.5 2805 | stoppable: 1.1.0 2806 | undici: 7.14.0 2807 | workerd: 1.20250906.0 2808 | ws: 8.18.0 2809 | youch: 4.1.0-beta.10 2810 | zod: 3.22.3 2811 | transitivePeerDependencies: 2812 | - bufferutil 2813 | - utf-8-validate 2814 | 2815 | minimatch@3.1.2: 2816 | dependencies: 2817 | brace-expansion: 1.1.12 2818 | 2819 | minimatch@9.0.5: 2820 | dependencies: 2821 | brace-expansion: 2.0.2 2822 | 2823 | ms@2.1.3: {} 2824 | 2825 | nanoid@3.3.11: {} 2826 | 2827 | natural-compare@1.4.0: {} 2828 | 2829 | node-releases@2.0.21: {} 2830 | 2831 | obs-websocket-js@5.0.6: 2832 | dependencies: 2833 | '@msgpack/msgpack': 2.8.0 2834 | crypto-js: 4.2.0 2835 | debug: 4.4.1 2836 | eventemitter3: 5.0.1 2837 | isomorphic-ws: 5.0.0(ws@8.18.3) 2838 | type-fest: 3.13.1 2839 | ws: 8.18.3 2840 | transitivePeerDependencies: 2841 | - bufferutil 2842 | - supports-color 2843 | - utf-8-validate 2844 | 2845 | ohash@2.0.11: {} 2846 | 2847 | optionator@0.9.4: 2848 | dependencies: 2849 | deep-is: 0.1.4 2850 | fast-levenshtein: 2.0.6 2851 | levn: 0.4.1 2852 | prelude-ls: 1.2.1 2853 | type-check: 0.4.0 2854 | word-wrap: 1.2.5 2855 | 2856 | p-limit@3.1.0: 2857 | dependencies: 2858 | yocto-queue: 0.1.0 2859 | 2860 | p-locate@5.0.0: 2861 | dependencies: 2862 | p-limit: 3.1.0 2863 | 2864 | parent-module@1.0.1: 2865 | dependencies: 2866 | callsites: 3.1.0 2867 | 2868 | path-exists@4.0.0: {} 2869 | 2870 | path-key@3.1.1: {} 2871 | 2872 | path-to-regexp@6.3.0: {} 2873 | 2874 | pathe@2.0.3: {} 2875 | 2876 | picocolors@1.1.1: {} 2877 | 2878 | picomatch@2.3.1: {} 2879 | 2880 | picomatch@4.0.3: {} 2881 | 2882 | postcss@8.5.6: 2883 | dependencies: 2884 | nanoid: 3.3.11 2885 | picocolors: 1.1.1 2886 | source-map-js: 1.2.1 2887 | 2888 | prelude-ls@1.2.1: {} 2889 | 2890 | punycode@2.3.1: {} 2891 | 2892 | queue-microtask@1.2.3: {} 2893 | 2894 | react-dom@19.1.1(react@19.1.1): 2895 | dependencies: 2896 | react: 19.1.1 2897 | scheduler: 0.26.0 2898 | 2899 | react-refresh@0.17.0: {} 2900 | 2901 | react@19.1.1: {} 2902 | 2903 | redux@5.0.1: {} 2904 | 2905 | resolve-from@4.0.0: {} 2906 | 2907 | reusify@1.1.0: {} 2908 | 2909 | rollup@4.50.1: 2910 | dependencies: 2911 | '@types/estree': 1.0.8 2912 | optionalDependencies: 2913 | '@rollup/rollup-android-arm-eabi': 4.50.1 2914 | '@rollup/rollup-android-arm64': 4.50.1 2915 | '@rollup/rollup-darwin-arm64': 4.50.1 2916 | '@rollup/rollup-darwin-x64': 4.50.1 2917 | '@rollup/rollup-freebsd-arm64': 4.50.1 2918 | '@rollup/rollup-freebsd-x64': 4.50.1 2919 | '@rollup/rollup-linux-arm-gnueabihf': 4.50.1 2920 | '@rollup/rollup-linux-arm-musleabihf': 4.50.1 2921 | '@rollup/rollup-linux-arm64-gnu': 4.50.1 2922 | '@rollup/rollup-linux-arm64-musl': 4.50.1 2923 | '@rollup/rollup-linux-loongarch64-gnu': 4.50.1 2924 | '@rollup/rollup-linux-ppc64-gnu': 4.50.1 2925 | '@rollup/rollup-linux-riscv64-gnu': 4.50.1 2926 | '@rollup/rollup-linux-riscv64-musl': 4.50.1 2927 | '@rollup/rollup-linux-s390x-gnu': 4.50.1 2928 | '@rollup/rollup-linux-x64-gnu': 4.50.1 2929 | '@rollup/rollup-linux-x64-musl': 4.50.1 2930 | '@rollup/rollup-openharmony-arm64': 4.50.1 2931 | '@rollup/rollup-win32-arm64-msvc': 4.50.1 2932 | '@rollup/rollup-win32-ia32-msvc': 4.50.1 2933 | '@rollup/rollup-win32-x64-msvc': 4.50.1 2934 | fsevents: 2.3.3 2935 | 2936 | run-parallel@1.2.0: 2937 | dependencies: 2938 | queue-microtask: 1.2.3 2939 | 2940 | scheduler@0.26.0: {} 2941 | 2942 | semver@6.3.1: {} 2943 | 2944 | semver@7.7.2: {} 2945 | 2946 | sharp@0.33.5: 2947 | dependencies: 2948 | color: 4.2.3 2949 | detect-libc: 2.0.4 2950 | semver: 7.7.2 2951 | optionalDependencies: 2952 | '@img/sharp-darwin-arm64': 0.33.5 2953 | '@img/sharp-darwin-x64': 0.33.5 2954 | '@img/sharp-libvips-darwin-arm64': 1.0.4 2955 | '@img/sharp-libvips-darwin-x64': 1.0.4 2956 | '@img/sharp-libvips-linux-arm': 1.0.5 2957 | '@img/sharp-libvips-linux-arm64': 1.0.4 2958 | '@img/sharp-libvips-linux-s390x': 1.0.4 2959 | '@img/sharp-libvips-linux-x64': 1.0.4 2960 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 2961 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4 2962 | '@img/sharp-linux-arm': 0.33.5 2963 | '@img/sharp-linux-arm64': 0.33.5 2964 | '@img/sharp-linux-s390x': 0.33.5 2965 | '@img/sharp-linux-x64': 0.33.5 2966 | '@img/sharp-linuxmusl-arm64': 0.33.5 2967 | '@img/sharp-linuxmusl-x64': 0.33.5 2968 | '@img/sharp-wasm32': 0.33.5 2969 | '@img/sharp-win32-ia32': 0.33.5 2970 | '@img/sharp-win32-x64': 0.33.5 2971 | 2972 | shebang-command@2.0.0: 2973 | dependencies: 2974 | shebang-regex: 3.0.0 2975 | 2976 | shebang-regex@3.0.0: {} 2977 | 2978 | simple-swizzle@0.2.2: 2979 | dependencies: 2980 | is-arrayish: 0.3.2 2981 | 2982 | source-map-js@1.2.1: {} 2983 | 2984 | stoppable@1.1.0: {} 2985 | 2986 | strip-json-comments@3.1.1: {} 2987 | 2988 | supports-color@10.2.2: {} 2989 | 2990 | supports-color@7.2.0: 2991 | dependencies: 2992 | has-flag: 4.0.0 2993 | 2994 | tinyglobby@0.2.15: 2995 | dependencies: 2996 | fdir: 6.5.0(picomatch@4.0.3) 2997 | picomatch: 4.0.3 2998 | 2999 | to-regex-range@5.0.1: 3000 | dependencies: 3001 | is-number: 7.0.0 3002 | 3003 | ts-api-utils@2.1.0(typescript@5.8.3): 3004 | dependencies: 3005 | typescript: 5.8.3 3006 | 3007 | tslib@2.8.1: 3008 | optional: true 3009 | 3010 | type-check@0.4.0: 3011 | dependencies: 3012 | prelude-ls: 1.2.1 3013 | 3014 | type-fest@3.13.1: {} 3015 | 3016 | typescript-eslint@8.43.0(eslint@9.35.0)(typescript@5.8.3): 3017 | dependencies: 3018 | '@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0)(typescript@5.8.3))(eslint@9.35.0)(typescript@5.8.3) 3019 | '@typescript-eslint/parser': 8.43.0(eslint@9.35.0)(typescript@5.8.3) 3020 | '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.8.3) 3021 | '@typescript-eslint/utils': 8.43.0(eslint@9.35.0)(typescript@5.8.3) 3022 | eslint: 9.35.0 3023 | typescript: 5.8.3 3024 | transitivePeerDependencies: 3025 | - supports-color 3026 | 3027 | typescript@5.8.3: {} 3028 | 3029 | ufo@1.6.1: {} 3030 | 3031 | undici-types@6.21.0: {} 3032 | 3033 | undici@7.14.0: {} 3034 | 3035 | unenv@2.0.0-rc.21: 3036 | dependencies: 3037 | defu: 6.1.4 3038 | exsolve: 1.0.7 3039 | ohash: 2.0.11 3040 | pathe: 2.0.3 3041 | ufo: 1.6.1 3042 | 3043 | update-browserslist-db@1.1.3(browserslist@4.26.0): 3044 | dependencies: 3045 | browserslist: 4.26.0 3046 | escalade: 3.2.0 3047 | picocolors: 1.1.1 3048 | 3049 | uri-js@4.4.1: 3050 | dependencies: 3051 | punycode: 2.3.1 3052 | 3053 | vite@6.3.6(@types/node@22.18.2): 3054 | dependencies: 3055 | esbuild: 0.25.9 3056 | fdir: 6.5.0(picomatch@4.0.3) 3057 | picomatch: 4.0.3 3058 | postcss: 8.5.6 3059 | rollup: 4.50.1 3060 | tinyglobby: 0.2.15 3061 | optionalDependencies: 3062 | '@types/node': 22.18.2 3063 | fsevents: 2.3.3 3064 | 3065 | which@2.0.2: 3066 | dependencies: 3067 | isexe: 2.0.0 3068 | 3069 | word-wrap@1.2.5: {} 3070 | 3071 | workerd@1.20250906.0: 3072 | optionalDependencies: 3073 | '@cloudflare/workerd-darwin-64': 1.20250906.0 3074 | '@cloudflare/workerd-darwin-arm64': 1.20250906.0 3075 | '@cloudflare/workerd-linux-64': 1.20250906.0 3076 | '@cloudflare/workerd-linux-arm64': 1.20250906.0 3077 | '@cloudflare/workerd-windows-64': 1.20250906.0 3078 | 3079 | wrangler@4.36.0: 3080 | dependencies: 3081 | '@cloudflare/kv-asset-handler': 0.4.0 3082 | '@cloudflare/unenv-preset': 2.7.3(unenv@2.0.0-rc.21)(workerd@1.20250906.0) 3083 | blake3-wasm: 2.1.5 3084 | esbuild: 0.25.4 3085 | miniflare: 4.20250906.1 3086 | path-to-regexp: 6.3.0 3087 | unenv: 2.0.0-rc.21 3088 | workerd: 1.20250906.0 3089 | optionalDependencies: 3090 | fsevents: 2.3.3 3091 | transitivePeerDependencies: 3092 | - bufferutil 3093 | - utf-8-validate 3094 | 3095 | ws@8.18.0: {} 3096 | 3097 | ws@8.18.3: {} 3098 | 3099 | yallist@3.1.1: {} 3100 | 3101 | yocto-queue@0.1.0: {} 3102 | 3103 | youch-core@0.3.3: 3104 | dependencies: 3105 | '@poppinss/exception': 1.2.2 3106 | error-stack-parser-es: 1.0.5 3107 | 3108 | youch@4.1.0-beta.10: 3109 | dependencies: 3110 | '@poppinss/colors': 4.1.5 3111 | '@poppinss/dumper': 0.6.4 3112 | '@speed-highlight/core': 1.2.7 3113 | cookie: 1.0.2 3114 | youch-core: 0.3.3 3115 | 3116 | zod@3.22.3: {} 3117 | 3118 | zustand-devtools@1.1.0(typescript@5.8.3)(zustand@5.0.8(@types/react@19.1.13)(react@19.1.1)): 3119 | dependencies: 3120 | typescript: 5.8.3 3121 | zustand: 5.0.8(@types/react@19.1.13)(react@19.1.1) 3122 | 3123 | zustand@5.0.8(@types/react@19.1.13)(react@19.1.1): 3124 | optionalDependencies: 3125 | '@types/react': 19.1.13 3126 | react: 19.1.1 3127 | --------------------------------------------------------------------------------