diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 6df9d25..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index 40ae98d..f130b04 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ __pycache__/ *.py[cod] data/ .direnv/ +.fake-backend-config.json + +# OS files +.DS_Store \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..6baa25e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,9 @@ +This is a project designing the compute platform for UTMIST (University of Toronto Machine Intelligence Student Team). The target cluster is two computers, one with tenstorrent gpu and one with nvidia gpus. + +## Documentation + +Agents are allowed to edit the README and top level markdown files as well as docs/agents, but shouldn't touch docs/humans as those are by humans for humans (though agents may notify humans if they believe human docs are severely outdated). + +## Temporary Decisions + +Make the frontend lightweight and move logic to backend. We aren't short on bandwidth, so it is fine to send a new qpi request and refresh UI every once in a while. \ No newline at end of file diff --git a/README.md b/README.md index 9d0f2f8..ad6502a 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,17 @@ UTMIST's research compute platform. Submit Python scripts or tagged container images, choose CPU, NVIDIA GPUs or Tenstorrent boards, upload datasets, and collect persistent results through the same website or CLI. -**Private website:** http://100.73.139.66:8088, accessible through authorized +**Private website:** [http://100.73.139.66:8088](http://100.73.139.66:8088), accessible through authorized Tailscale connectivity. A Mist account and team membership are also required. ## Current installation -| Machine | Role | LAN address | Tailscale address | -|---|---|---|---| -| `utmist-z1opa08` | k3s server, API/auth, website, CPU and two RTX A4000 GPUs | `10.0.0.175` | `100.73.139.66` | -| `utmist-tt` | k3s worker, four n300 boards/eight chips, shared storage | `10.0.0.112` | `100.95.175.37` | + +| Machine | Role | LAN address | Tailscale address | +| ---------------- | --------------------------------------------------------- | ------------ | ----------------- | +| `utmist-z1opa08` | k3s server, API/auth, website, CPU and two RTX A4000 GPUs | `10.0.0.175` | `100.73.139.66` | +| `utmist-tt` | k3s worker, four n300 boards/eight chips, shared storage | `10.0.0.112` | `100.95.175.37` | + The cluster and NFS use the existing LAN. Tailscale provides private portal and administrator SSH access. Kubernetes/containerd run workload containers. @@ -60,3 +62,27 @@ chaining, browser image archives/builds, private pull-credential management and distributed multi-machine training are outside this release. Automatic backups, HTTPS and monitoring/cleanup products were explicitly excluded. This is a private HTTP installation with one control plane, one auth instance and one storage host. + +### Documentation + +Humans are responsible for editing the human facing docs. This is because the human facing docs will be read by humans, and it is rude to give them untested instructions to follow. + +Documentation should include explanations of design decisions for later platform maintainers. + +## Frontend Testing + +how to use fake backend for testing frontend. + +(temporary, functionality, to be removed in future commit.) + +```bash +# Terminal 1 +npm --prefix web-interface run dev -- --host 127.0.0.1 --port 3001 --strictPort + +# Terminal 2 +npm --prefix web-interface run fake-backend +``` + + + +  \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 17a1067..ce6536a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,6 +18,7 @@ host-specific settings when provisioning another environment. | Authenticate and submit from a terminal | [CLI](../cli/docs/setup.md) | | Run automated checks and read recorded live evidence | [Testing](testing.md) | | Maintain UI components and interactions | [Design system](design-system.md) | +| Understand frontend architecture and backend offloading | [Frontend architecture](frontend-architecture.md) | | Read completed scope, exclusions and release verification | [Execution record](department-rollout-execution.md) | | See what repository cleanup removed and verified | [Cleanup record](repository-cleanup.md) | diff --git a/docs/frontend-architecture.md b/docs/frontend-architecture.md new file mode 100644 index 0000000..f27ed6a --- /dev/null +++ b/docs/frontend-architecture.md @@ -0,0 +1,125 @@ +# Frontend Architecture & Backend Offloading + +Documentation of the current Mist frontend ([`web-interface`](../web-interface)), its structural organization, and a roadmap of client-side processing to offload to the backend. + +## Architecture overview + +```mermaid +flowchart TD + User([User Browser]) --> Shell[Root Shell: __root.tsx] + Shell --> AG[AccountGate: auth.tsx] + AG --> TG[TeamGate: teams.tsx] + TG --> Nav[Navbar.tsx] + TG --> RouterOutlet[TanStack Router Outlet] + + RouterOutlet --> DPage[Dashboard: dashboard.tsx] + RouterOutlet --> JPage[Jobs Page: jobs.tsx] + RouterOutlet --> SPage[Datasets Page: datasets.tsx] + RouterOutlet --> MPage[Machines Page: machines.tsx] + RouterOutlet --> TPage[Teams Page: teams.tsx] + RouterOutlet --> PPage[Profile: profile.tsx] + + JPage --> JSF[JobSubmissionForm.tsx] + JPage --> JC[JobCard.tsx] + JC --> JL[JobLogs.tsx] + JC --> JF[JobFiles.tsx] + + SPage --> TSB[TeamStorageBrowser.tsx] +``` + +### Technology stack + +- **Vite 7.3**: Build tool and development proxy (`/api` and `/auth` forwards). +- **React 19.3**: Functional component architecture with custom hooks. +- **TanStack Router**: File-based routing located in `src/routes/` with code-splitting. +- **Tailwind CSS 4**: Modern styling via `@tailwindcss/vite` and customized Mist theme classes. +- **Better Auth Client**: Authentication state and admin member management. +- **Vitest 5 & Testing Library**: Unit and component tests. + +### Source layout + +| Location | Purpose | +|---|---| +| `src/main.tsx`, `router.tsx` | Router initialization and DOM hydration | +| `src/routes/__root.tsx` | Shell wrapper containing `AccountGate`, `TeamGate`, and `Navbar` | +| `src/routes/` | File-based routes (`dashboard.tsx`, `jobs.tsx`, `datasets.tsx`, `machines.tsx`, `teams.tsx`, `profile.tsx`) | +| `src/auth.tsx` | Better Auth client configuration, `AccountContext`, and `AccountGate` | +| `src/teams.tsx` | `TeamContext`, active team selection, workspace selector | +| `src/api.ts` | Typed HTTP client for jobs, datasets, hardware, and teams | +| `src/hooks/usePolling.ts` | In-flight request deduplication and abortable periodic polling | +| `src/components/jobs/` | `JobSubmissionForm`, `JobCard`, `JobLogs`, `JobFiles` | +| `src/components/` | `HardwarePanel`, `TeamStorageBrowser`, `Modal`, `Picker`, `Tabs`, `Card`, `Buttons` | + +--- + +## Backend offloading plan + +To keep the frontend as lightweight and simple as possible, the following responsibilities currently performed on the client should be handled by the backend: + +1. **Pagination and filtering**: + - `JobsPage`: Replace client-side slicing and array filtering with query parameters on `GET /jobs?status=...&q=...&page=...&limit=...`. + - `DatasetsPage`: Add `GET /datasets?q=...`. + - `AccountPage`: Replace Better Auth `listUsers({ limit: 1000 })` with a paginated endpoint `GET /members?page=...&q=...`. +2. **Metrics aggregation**: + - Provide `GET /metrics/summary` or summary counters in list endpoints to avoid transferring full item arrays just to compute badge totals. +3. **Image catalog and validation**: + - Move registry string parsing and image approval checks from `JobSubmissionForm` to server-side submission validation. +4. **Quota and limit calculation**: + - Replace client-side calculation of `maxDevices` and `maxTimeout` with authoritative constraints provided by the team policy API. +5. **Form parsing**: + - Accept raw multiline environment variable text and shell commands on `POST /jobs`, delegating parsing and validation to the server. +6. **Error status handling**: + - Replace English error string matching (e.g. `isPreparing`) with typed machine-readable status fields (`{ status: "provisioning" }`). +7. **Permission flags**: + - Return explicit capability booleans (`can_cancel`, `can_delete`, `can_manage`) on entities rather than parsing role strings on the client. +8. **Atomic operations**: + - Consolidate multi-call client sequences (e.g. team creation + creator enrollment, password reset + session revocation) into atomic backend operations. +9. **Event-driven updates**: + - Replace high-frequency polling with Server-Sent Events (SSE) or WebSockets for live job status and log streaming. + +--- + +## Testing with the fake backend + +A self-contained testing backend is provided in `scripts/fake-backend.mjs`. It simulates all Mist API endpoints and Better Auth handlers in memory. + +### Running locally + +```bash +# Terminal 1: Start fake backend (default port 3000) +npm --prefix web-interface run fake-backend +``` + +```bash +# Terminal 2: Start frontend dev server (port 3001) +npm --prefix web-interface run dev -- --host 127.0.0.1 --port 3001 --strictPort +``` + +Open http://127.0.0.1:3001 in your browser. Pre-seeded users include `ada@utmist.gitlab.io` (admin), `alan@utmist.gitlab.io`, and `grace@utmist.gitlab.io`. + +### Configuring hypothetical scenarios and fake information + +A companion configure tool is provided at `scripts/configure-fake-backend.mjs` to set up hypothetical cluster topologies, error conditions, and user setups: + +```bash +# Interactive menu (choose scenarios, add fake nodes, switch active user) +npm --prefix web-interface run configure-fake-backend + +# Switch to a preset scenario directly +node scripts/configure-fake-backend.mjs --scenario high-load +node scripts/configure-fake-backend.mjs --scenario unhealthy +node scripts/configure-fake-backend.mjs --scenario empty-slate +node scripts/configure-fake-backend.mjs --scenario large-cluster +node scripts/configure-fake-backend.mjs --scenario default + +# Inspect current cluster topology & status +node scripts/configure-fake-backend.mjs --status + +# Add custom fake machines, users, or teams +node scripts/configure-fake-backend.mjs --add-machine name=dgx-custom,ip=10.99.1.5,cpu=64,ram=256Gi,gpu=8 +node scripts/configure-fake-backend.mjs --add-user name="Marie Curie",email=curie@rad.edu,role=admin +node scripts/configure-fake-backend.mjs --set-user curie@rad.edu +``` + +If the fake backend is running, `configure-fake-backend.mjs` updates the live server immediately without requiring a restart, while also saving to `.fake-backend-config.json` for persistence. + diff --git a/scripts/configure-fake-backend.mjs b/scripts/configure-fake-backend.mjs new file mode 100644 index 0000000..4796596 --- /dev/null +++ b/scripts/configure-fake-backend.mjs @@ -0,0 +1,547 @@ +#!/usr/bin/env node +/** + * Mist Fake Backend Configuration CLI + * + * Configures hypothetical scenarios, fake users, machines, and hardware pools + * for local testing of the web interface. + * + * Usage: + * node scripts/configure-fake-backend.mjs # Interactive mode + * node scripts/configure-fake-backend.mjs --scenario high-load # Switch scenario + * node scripts/configure-fake-backend.mjs --status # Show current topology + * node scripts/configure-fake-backend.mjs --list-scenarios # List all presets + * node scripts/configure-fake-backend.mjs --reset # Reset to default + */ + +import fs from 'node:fs' +import path from 'node:path' +import http from 'node:http' +import readline from 'node:readline/promises' +import { stdin as input, stdout as output } from 'node:process' +import { fileURLToPath } from 'node:url' +import { + getScenario, + SCENARIO_DESCRIPTIONS, + SCENARIO_FACTORIES, +} from './fake-backend-scenarios.mjs' + +const ROOT_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') +const CONFIG_FILE = path.resolve(ROOT_DIR, '.fake-backend-config.json') + +// Parse CLI flags +const argv = process.argv.slice(2) +function getFlag(name) { + const idx = argv.indexOf(name) + return idx !== -1 && argv[idx + 1] ? argv[idx + 1] : null +} +function hasFlag(name) { + return argv.includes(name) +} + +const PORT = Number( + getFlag('--port') || process.env.PORT || process.env.MIST_FAKE_PORT || 3000, +) +const HOST = process.env.HOST || '127.0.0.1' + +// --- Server Communication Helpers --- + +function requestJSON(method, endpointPath, body = null) { + return new Promise((resolve, reject) => { + const data = body ? JSON.stringify(body) : null + const req = http.request( + { + hostname: HOST, + port: PORT, + path: endpointPath, + method, + headers: { + 'Content-Type': 'application/json', + ...(data ? { 'Content-Length': Buffer.byteLength(data) } : {}), + }, + timeout: 1500, + }, + (res) => { + let resData = '' + res.on('data', (chunk) => (resData += chunk)) + res.on('end', () => { + try { + resolve({ + status: res.statusCode, + data: resData ? JSON.parse(resData) : null, + }) + } catch (e) { + resolve({ status: res.statusCode, raw: resData }) + } + }) + }, + ) + req.on('timeout', () => { + req.destroy() + reject(new Error('Connection timed out')) + }) + req.on('error', (err) => reject(err)) + if (data) req.write(data) + req.end() + }) +} + +async function checkLiveServer() { + try { + const res = await requestJSON('GET', '/_fake/state') + if (res.status === 200 && res.data) { + return res.data + } + } catch {} + return null +} + +function loadLocalConfigFile() { + if (fs.existsSync(CONFIG_FILE)) { + try { + return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8')) + } catch {} + } + return null +} + +function saveLocalConfigFile(state) { + fs.writeFileSync(CONFIG_FILE, JSON.stringify(state, null, 2), 'utf-8') +} + +async function applyState(state) { + // 1. Save to local config file + saveLocalConfigFile(state) + + // 2. If live server running, update it dynamically + const live = await checkLiveServer() + if (live) { + try { + await requestJSON('POST', '/_fake/state', state) + console.log(`\n✓ Live fake backend at http://${HOST}:${PORT} updated instantly!`) + console.log(`✓ Saved configuration to .fake-backend-config.json`) + return + } catch (err) { + console.warn(`\n(Live update failed: ${err.message})`) + } + } + console.log(`\n✓ Saved configuration to .fake-backend-config.json`) + console.log(` (The fake backend is offline. Changes will take effect when it starts.)`) +} + +function parseKeyValue(inputStr) { + const result = {} + const pairs = inputStr.split(',') + for (const pair of pairs) { + const [k, v] = pair.split('=').map((s) => s.trim()) + if (k && v !== undefined) { + result[k] = v.replace(/^["']|["']$/g, '') + } + } + return result +} + +function printStatus(state) { + console.log('\n======================================================') + console.log(`Scenario: ${state.activeScenario || state.name || 'custom'}`) + const activeUser = + state.users?.[state.currentUserIndex] || state.currentUser || null + console.log( + `Active User: ${activeUser ? `${activeUser.name} <${activeUser.email}> [${activeUser.role}]` : 'None'}`, + ) + console.log(`Total Users: ${state.users?.length ?? 0}`) + console.log('------------------------------------------------------') + console.log('Machines & Nodes:') + for (const m of state.machines || []) { + const status = m.ready ? (m.schedulable ? 'Ready' : 'Placement Paused') : 'Offline' + console.log(` • ${m.name.padEnd(22)} ${m.address.padEnd(14)} [${status.padEnd(16)}] ${m.cpu_allocatable} CPU · ${m.memory_allocatable} RAM`) + } + console.log('Hardware Accelerator Pools:') + for (const p of state.pools || []) { + const avail = p.available === null ? 'Unknown' : p.available + const msg = p.message ? ` (${p.message})` : '' + console.log(` • ${p.accelerator.toUpperCase().padEnd(12)} Node: ${p.node.padEnd(20)} Total: ${p.total} Allocated: ${p.allocated} Available: ${avail}${msg}`) + } + console.log('Teams:') + for (const t of state.teams || []) { + console.log(` • ${t.name.padEnd(26)} Members: ${t.members?.length ?? 0} Policy: ${t.policy?.storage_gib ?? 0} GiB Datasets / ${t.policy?.model_storage_gib ?? 0} GiB Models`) + } + console.log('Jobs in History:') + const states = {} + for (const j of state.jobs || []) { + states[j.job_state] = (states[j.job_state] || 0) + 1 + } + console.log(` Total: ${state.jobs?.length ?? 0} (${Object.entries(states).map(([k, v]) => `${k}: ${v}`).join(', ') || '0'})`) + console.log('======================================================\n') +} + +// --- CLI Commands --- + +async function main() { + if (hasFlag('--help') || hasFlag('-h')) { + console.log(` +Mist Fake Backend Configurator + +Commands & Options: + --scenario Load a preset scenario (default, high-load, unhealthy, empty-slate, large-cluster) + --list-scenarios List all available built-in scenarios + --status Display current cluster topology, machines, users, and jobs + --set-user Set which user is active in the web session + --add-user Add a user: name="...",email="...",role=admin|user + --add-machine Add a machine: name="...",ip="...",cpu=32,ram=128Gi,gpu=4,tt=0 + --add-team Add a team: name="...",storage=300,models=600 + --config Load configuration from a JSON file + --export Export active configuration to a JSON file + --reset Reset back to the default scenario + --port Target port (default: 3000) + +Run with no flags for the interactive menu. +`) + return + } + + if (hasFlag('--list-scenarios')) { + console.log('\nAvailable Hypothetical Scenarios:') + for (const [name, desc] of Object.entries(SCENARIO_DESCRIPTIONS)) { + console.log(` • ${name.padEnd(16)} : ${desc}`) + } + console.log('') + return + } + + // Current state resolution + let currentState = (await checkLiveServer()) || loadLocalConfigFile() || getScenario('default') + + if (hasFlag('--status')) { + const live = await checkLiveServer() + console.log(live ? `[Backend Server: ONLINE at http://${HOST}:${PORT}]` : `[Backend Server: OFFLINE (reading config file)]`) + printStatus(currentState) + return + } + + if (hasFlag('--scenario')) { + const name = getFlag('--scenario') + try { + const scenario = getScenario(name) + await applyState(scenario) + printStatus(scenario) + } catch (err) { + console.error(`Error: ${err.message}`) + process.exit(1) + } + return + } + + if (hasFlag('--reset')) { + const defaultScenario = getScenario('default') + await applyState(defaultScenario) + console.log('Reset to default scenario successfully.') + return + } + + if (hasFlag('--config')) { + const filePath = getFlag('--config') + if (!fs.existsSync(filePath)) { + console.error(`File not found: ${filePath}`) + process.exit(1) + } + const data = JSON.parse(fs.readFileSync(filePath, 'utf-8')) + await applyState(data) + console.log(`Loaded configuration from ${filePath}.`) + return + } + + if (hasFlag('--export')) { + const outPath = getFlag('--export') + fs.writeFileSync(outPath, JSON.stringify(currentState, null, 2), 'utf-8') + console.log(`Exported configuration to ${outPath}.`) + return + } + + if (hasFlag('--set-user')) { + const target = getFlag('--set-user') + const idx = (currentState.users || []).findIndex( + (u) => u.id === target || u.email.toLowerCase() === target.toLowerCase(), + ) + if (idx === -1) { + console.error(`User '${target}' not found. Available: ${currentState.users.map((u) => u.email).join(', ')}`) + process.exit(1) + } + currentState.currentUserIndex = idx + await applyState(currentState) + console.log(`Active user set to: ${currentState.users[idx].name} (${currentState.users[idx].email})`) + return + } + + if (hasFlag('--add-user')) { + const kv = parseKeyValue(getFlag('--add-user')) + if (!kv.name || !kv.email) { + console.error('Error: name and email are required (e.g. name="Marie Curie",email="curie@rad.edu",role=admin)') + process.exit(1) + } + const newUser = { + id: 'usr_' + Date.now().toString(36), + name: kv.name, + email: kv.email, + role: kv.role || 'user', + banned: false, + } + currentState.users = currentState.users || [] + currentState.users.push(newUser) + await applyState(currentState) + console.log(`Added user: ${newUser.name} <${newUser.email}> (${newUser.role})`) + return + } + + if (hasFlag('--add-machine')) { + const kv = parseKeyValue(getFlag('--add-machine')) + if (!kv.name) { + console.error('Error: machine name is required (e.g. name=dgx-a100,ip=10.0.1.50,cpu=64,ram=256Gi,gpu=8)') + process.exit(1) + } + const newMachine = { + name: kv.name, + address: kv.ip || kv.address || '10.0.1.' + Math.floor(Math.random() * 200 + 20), + ready: kv.ready !== 'false', + schedulable: kv.schedulable !== 'false', + cpu_allocatable: kv.cpu || '32', + memory_allocatable: kv.ram || '128Gi', + } + currentState.machines = currentState.machines || [] + currentState.machines.push(newMachine) + + // Add GPU or TT pools if requested + currentState.pools = currentState.pools || [] + if (Number(kv.gpu) > 0) { + currentState.pools.push({ + accelerator: 'nvidia', + node: newMachine.name, + unit: 'GPU', + total: Number(kv.gpu), + allocated: 0, + available: Number(kv.gpu), + ready: true, + }) + } + if (Number(kv.tt) > 0) { + currentState.pools.push({ + accelerator: 'tenstorrent', + node: newMachine.name, + unit: 'board', + total: Number(kv.tt), + allocated: 0, + available: Number(kv.tt), + ready: true, + chips_per_device: 2, + }) + } + await applyState(currentState) + console.log(`Added machine: ${newMachine.name} with ${kv.gpu || 0} GPUs and ${kv.tt || 0} Tenstorrent boards.`) + return + } + + if (hasFlag('--add-team')) { + const kv = parseKeyValue(getFlag('--add-team')) + if (!kv.name) { + console.error('Error: team name is required (e.g. name="Quantum ML",storage=500,models=1000)') + process.exit(1) + } + const activeUser = currentState.users?.[currentState.currentUserIndex] + const newTeam = { + id: 'team-' + kv.name.toLowerCase().replace(/\W+/g, '-'), + name: kv.name, + disabled: false, + policy: { + cpu: kv.cpu || '16', + memory: kv.memory || '64Gi', + nvidia: Number(kv.gpu ?? 2), + tenstorrent: Number(kv.tt ?? 2), + concurrent: 4, + queued: 20, + storage_gib: Number(kv.storage || 300), + model_storage_gib: Number(kv.models || 600), + runtime_seconds: 86400, + registries: ['docker.io', 'ghcr.io'], + }, + members: activeUser + ? [{ id: activeUser.id, name: activeUser.name, email: activeUser.email, common_writer: true }] + : [], + grants: [], + } + currentState.teams = currentState.teams || [] + currentState.teams.push(newTeam) + await applyState(currentState) + console.log(`Added team: ${newTeam.name}`) + return + } + + // --- Interactive Terminal Menu --- + const rl = readline.createInterface({ input, output }) + try { + while (true) { + const live = await checkLiveServer() + console.clear() + console.log('======================================================') + console.log(' MIST FAKE BACKEND CONFIGURATOR') + console.log('======================================================') + console.log(`Backend Server: ${live ? `ONLINE (http://${HOST}:${PORT})` : 'OFFLINE (saving to config file)'}`) + console.log(`Active Scenario: ${currentState.activeScenario || currentState.name || 'custom'}`) + const u = currentState.users?.[currentState.currentUserIndex] + console.log(`Active User: ${u ? `${u.name} <${u.email}> (${u.role})` : 'None'}`) + console.log(`Machines: ${currentState.machines?.map((m) => m.name).join(', ') || 'None'}`) + console.log(`Teams: ${currentState.teams?.map((t) => t.name).join(', ') || 'None'}`) + console.log('------------------------------------------------------') + console.log('Select an action:') + console.log(' 1) Switch to a hypothetical scenario preset') + console.log(' 2) Switch active logged-in user') + console.log(' 3) Add a fake machine / node') + console.log(' 4) Add a fake user') + console.log(' 5) Add a fake team') + console.log(' 6) View full cluster status') + console.log(' 7) Reset to default scenario') + console.log(' 8) Exit') + console.log('------------------------------------------------------') + + const choice = (await rl.question('Enter choice [1-8]: ')).trim() + + if (choice === '1') { + console.log('\nAvailable Hypothetical Scenarios:') + const keys = Object.keys(SCENARIO_DESCRIPTIONS) + keys.forEach((key, i) => { + console.log(` ${i + 1}) ${key.padEnd(16)} : ${SCENARIO_DESCRIPTIONS[key]}`) + }) + const sel = (await rl.question('\nSelect scenario [1-5]: ')).trim() + const idx = parseInt(sel, 10) - 1 + if (keys[idx]) { + currentState = getScenario(keys[idx]) + await applyState(currentState) + await rl.question('\nPress Enter to continue...') + } + } else if (choice === '2') { + console.log('\nAvailable Users:') + currentState.users.forEach((user, i) => { + const mark = i === currentState.currentUserIndex ? ' (ACTIVE)' : '' + console.log(` ${i + 1}) ${user.name} <${user.email}> [${user.role}]${mark}`) + }) + const sel = (await rl.question('\nSelect user number: ')).trim() + const idx = parseInt(sel, 10) - 1 + if (currentState.users[idx]) { + currentState.currentUserIndex = idx + await applyState(currentState) + } + } else if (choice === '3') { + console.log('\n--- Add Fake Machine ---') + const name = (await rl.question('Machine name (e.g. dgx-h100-01): ')).trim() + if (!name) continue + const ip = (await rl.question('IP Address (default 10.0.1.25): ')).trim() || '10.0.1.25' + const cpu = (await rl.question('Allocatable CPU cores (default 32): ')).trim() || '32' + const ram = (await rl.question('Allocatable RAM (default 128Gi): ')).trim() || '128Gi' + const gpu = parseInt((await rl.question('NVIDIA GPUs count (default 0): ')).trim() || '0', 10) + const tt = parseInt((await rl.question('Tenstorrent boards count (default 0): ')).trim() || '0', 10) + + const machine = { + name, + address: ip, + ready: true, + schedulable: true, + cpu_allocatable: cpu, + memory_allocatable: ram, + } + currentState.machines = currentState.machines || [] + currentState.machines.push(machine) + + currentState.pools = currentState.pools || [] + if (gpu > 0) { + currentState.pools.push({ + accelerator: 'nvidia', + node: name, + unit: 'GPU', + total: gpu, + allocated: 0, + available: gpu, + ready: true, + }) + } + if (tt > 0) { + currentState.pools.push({ + accelerator: 'tenstorrent', + node: name, + unit: 'board', + total: tt, + allocated: 0, + available: tt, + ready: true, + chips_per_device: 2, + }) + } + await applyState(currentState) + await rl.question('\nMachine added! Press Enter to continue...') + } else if (choice === '4') { + console.log('\n--- Add Fake User ---') + const name = (await rl.question('Full name (e.g. Marie Curie): ')).trim() + if (!name) continue + const email = (await rl.question('Email (e.g. marie@utmist.gitlab.io): ')).trim() + if (!email) continue + const role = (await rl.question('Role (admin / user, default user): ')).trim() || 'user' + currentState.users = currentState.users || [] + currentState.users.push({ + id: 'usr_' + Date.now().toString(36), + name, + email, + role, + banned: false, + }) + await applyState(currentState) + await rl.question('\nUser added! Press Enter to continue...') + } else if (choice === '5') { + console.log('\n--- Add Fake Team ---') + const name = (await rl.question('Team name (e.g. Quantum Computing Lab): ')).trim() + if (!name) continue + const storage = parseInt((await rl.question('Dataset storage in GiB (default 300): ')).trim() || '300', 10) + const models = parseInt((await rl.question('Model storage in GiB (default 600): ')).trim() || '600', 10) + const activeUser = currentState.users?.[currentState.currentUserIndex] + + const newTeam = { + id: 'team-' + name.toLowerCase().replace(/\W+/g, '-'), + name, + disabled: false, + policy: { + cpu: '16', + memory: '64Gi', + nvidia: 2, + tenstorrent: 2, + concurrent: 4, + queued: 20, + storage_gib: storage, + model_storage_gib: models, + runtime_seconds: 86400, + registries: ['docker.io', 'ghcr.io'], + }, + members: activeUser + ? [{ id: activeUser.id, name: activeUser.name, email: activeUser.email, common_writer: true }] + : [], + grants: [], + } + currentState.teams = currentState.teams || [] + currentState.teams.push(newTeam) + await applyState(currentState) + await rl.question('\nTeam added! Press Enter to continue...') + } else if (choice === '6') { + printStatus(currentState) + await rl.question('\nPress Enter to return to menu...') + } else if (choice === '7') { + currentState = getScenario('default') + await applyState(currentState) + await rl.question('\nReset to default scenario! Press Enter to continue...') + } else if (choice === '8') { + break + } + } + } finally { + rl.close() + } +} + +main().catch((err) => { + console.error('Fatal error:', err) + process.exit(1) +}) diff --git a/scripts/fake-backend-scenarios.mjs b/scripts/fake-backend-scenarios.mjs new file mode 100644 index 0000000..b9a0636 --- /dev/null +++ b/scripts/fake-backend-scenarios.mjs @@ -0,0 +1,643 @@ +/** + * Mist Fake Backend - Built-in Hypothetical Scenarios + * + * Provides modular scenario generators for testing various cluster topologies, + * load conditions, failure modes, and organizational structures. + */ + +export const SCENARIO_DESCRIPTIONS = { + default: 'Standard balanced cluster with 1 GPU node, 1 Tenstorrent node, 2 teams, and 3 users.', + 'high-load': 'Resource-exhausted cluster: 100% GPU/TT saturation, long waiting queue, and 95% full storage.', + unhealthy: 'Degraded cluster with offline nodes, failed jobs, driver error messages, and storage errors.', + 'empty-slate': 'Clean empty cluster with 0 jobs, 0 datasets, and 0 teams for onboarding / first-run testing.', + 'large-cluster': 'Multi-node enterprise setup with 5 machines (H100s, Wormholes), 5 teams, and 30+ jobs.', +} + +export function createDefaultScenario() { + const now = Date.now() + return { + name: 'default', + description: SCENARIO_DESCRIPTIONS.default, + currentUserIndex: 0, + storageBudgetGiB: 2000, + users: [ + { + id: 'usr_ada', + name: 'Ada Lovelace', + email: 'ada@utmist.gitlab.io', + role: 'admin', + banned: false, + }, + { + id: 'usr_alan', + name: 'Alan Turing', + email: 'alan@utmist.gitlab.io', + role: 'user', + banned: false, + }, + { + id: 'usr_grace', + name: 'Grace Hopper', + email: 'grace@utmist.gitlab.io', + role: 'user', + banned: false, + }, + ], + machines: [ + { + name: 'mist-gpu-node-01', + address: '10.0.1.10', + ready: true, + schedulable: true, + cpu_allocatable: '32', + memory_allocatable: '128Gi', + }, + { + name: 'mist-tt-worker-01', + address: '10.0.1.11', + ready: true, + schedulable: true, + cpu_allocatable: '16', + memory_allocatable: '64Gi', + }, + ], + pools: [ + { + accelerator: 'nvidia', + node: 'mist-gpu-node-01', + unit: 'GPU', + total: 4, + allocated: 1, + available: 3, + ready: true, + }, + { + accelerator: 'tenstorrent', + node: 'mist-tt-worker-01', + unit: 'board', + total: 4, + allocated: 0, + available: 4, + ready: true, + chips_per_device: 2, + }, + ], + storage: { + enabled: true, + capacity_bytes: 1099511627776, // 1 TiB + available_bytes: 879609302220, // 800 GiB + model_capacity_bytes: 2199023255552, // 2 TiB + model_available_bytes: 1759218604441, // 1.6 TiB + dataset_allocation_gib: 500, + model_allocation_gib: 1000, + upload_limit_bytes: 5368709120, // 5 GiB + }, + teams: [ + { + id: 'team-vision', + name: 'Computer Vision', + disabled: false, + policy: { + cpu: '16', + memory: '64Gi', + nvidia: 2, + tenstorrent: 4, + concurrent: 4, + queued: 20, + storage_gib: 300, + model_storage_gib: 600, + runtime_seconds: 86400, + registries: ['docker.io', 'ghcr.io', 'quay.io'], + }, + members: [ + { + id: 'usr_ada', + name: 'Ada Lovelace', + email: 'ada@utmist.gitlab.io', + common_writer: true, + }, + { + id: 'usr_alan', + name: 'Alan Turing', + email: 'alan@utmist.gitlab.io', + common_writer: false, + }, + ], + grants: [ + { + id: 'grant-nlp-share', + target_team: 'team-nlp', + scope: 'common', + }, + ], + }, + { + id: 'team-nlp', + name: 'Natural Language Processing', + disabled: false, + policy: { + cpu: '8', + memory: '32Gi', + nvidia: 1, + tenstorrent: 2, + concurrent: 2, + queued: 10, + storage_gib: 200, + model_storage_gib: 400, + runtime_seconds: 43200, + registries: ['docker.io', 'ghcr.io'], + }, + members: [ + { + id: 'usr_ada', + name: 'Ada Lovelace', + email: 'ada@utmist.gitlab.io', + common_writer: true, + }, + { + id: 'usr_grace', + name: 'Grace Hopper', + email: 'grace@utmist.gitlab.io', + common_writer: false, + }, + ], + grants: [], + }, + ], + jobs: [ + { + id: 'job-seed-001', + name: 'ResNet50 Vision Benchmark', + created: new Date(now - 3600000).toISOString(), + job_state: 'Success', + accelerator: 'nvidia', + device_count: 2, + image: 'ghcr.io/utmist/pytorch-cuda:latest', + cpu: '8', + memory: '32Gi', + node: 'mist-gpu-node-01', + exit_code: 0, + message: 'Job completed successfully in 1420s', + checkpoint_directory: '/outputs/checkpoints/job-seed-001', + output_directory: '/outputs/runs/job-seed-001', + timeout_seconds: 7200, + team_id: 'team-vision', + creator_id: 'usr_ada', + creator_name: 'Ada Lovelace', + storage_scope: 'common', + can_cancel: false, + }, + { + id: 'job-seed-002', + name: 'BERT Fine-tuning Test', + created: new Date(now - 1800000).toISOString(), + job_state: 'InProgress', + accelerator: 'nvidia', + device_count: 1, + image: 'ghcr.io/utmist/pytorch-cuda:latest', + cpu: '4', + memory: '16Gi', + node: 'mist-gpu-node-01', + checkpoint_directory: '/outputs/checkpoints/job-seed-002', + output_directory: '/outputs/runs/job-seed-002', + timeout_seconds: 3600, + team_id: 'team-nlp', + creator_id: 'usr_grace', + creator_name: 'Grace Hopper', + storage_scope: 'usr_grace', + can_cancel: true, + }, + { + id: 'job-seed-003', + name: 'Tenstorrent Wormhole Matrix Multiplication', + created: new Date(now - 600000).toISOString(), + job_state: 'Scheduled', + accelerator: 'tenstorrent', + device_count: 2, + image: 'ghcr.io/utmist/tt-metal-runtime:latest', + cpu: '4', + memory: '16Gi', + message: 'Queued; waiting for 2 Tenstorrent n300 board allocations', + checkpoint_directory: '/outputs/checkpoints/job-seed-003', + output_directory: '/outputs/runs/job-seed-003', + timeout_seconds: 1800, + team_id: 'team-vision', + creator_id: 'usr_alan', + creator_name: 'Alan Turing', + storage_scope: 'usr_alan', + can_cancel: true, + }, + ], + datasets: [ + { + id: 'ds-cifar100', + name: 'CIFAR-100 Benchmark Dataset', + filename: 'cifar100.zip', + size: 169000000, + files: 100, + sha256: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + created: new Date(now - 86400000).toISOString(), + state: 'ready', + team_id: 'team-vision', + team_name: 'Computer Vision', + scope: 'common', + member_name: 'Ada Lovelace', + shared: false, + }, + { + id: 'ds-wikitext', + name: 'Wikitext-103 Subset', + filename: 'wikitext.tar.gz', + size: 512000000, + files: 1, + sha256: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', + created: new Date(now - 43200000).toISOString(), + state: 'ready', + team_id: 'team-nlp', + team_name: 'Natural Language Processing', + scope: 'common', + member_name: 'Grace Hopper', + shared: true, + }, + ], + } +} + +export function createHighLoadScenario() { + const now = Date.now() + const base = createDefaultScenario() + base.name = 'high-load' + base.description = SCENARIO_DESCRIPTIONS['high-load'] + + // Saturated hardware: 0 available + base.pools = [ + { + accelerator: 'nvidia', + node: 'mist-gpu-node-01', + unit: 'GPU', + total: 4, + allocated: 4, + available: 0, + ready: true, + }, + { + accelerator: 'tenstorrent', + node: 'mist-tt-worker-01', + unit: 'board', + total: 4, + allocated: 4, + available: 0, + ready: true, + chips_per_device: 2, + }, + ] + + // Storage 95% consumed + base.storage = { + enabled: true, + capacity_bytes: 1073741824000, // 1 TiB + available_bytes: 32212254720, // 30 GiB left (near capacity!) + model_capacity_bytes: 2147483648000, + model_available_bytes: 53687091200, // 50 GiB left + dataset_allocation_gib: 980, + model_allocation_gib: 1950, + upload_limit_bytes: 2147483648, + } + + // 4 running jobs taking all accelerators + 8 queued jobs + base.jobs = [ + { + id: 'job-hl-run-01', + name: 'LLM Multi-GPU Pretraining Node 1', + created: new Date(now - 7200000).toISOString(), + job_state: 'InProgress', + accelerator: 'nvidia', + device_count: 2, + image: 'ghcr.io/utmist/pytorch-cuda:latest', + cpu: '16', + memory: '64Gi', + node: 'mist-gpu-node-01', + checkpoint_directory: '/outputs/checkpoints/job-hl-run-01', + output_directory: '/outputs/runs/job-hl-run-01', + team_id: 'team-vision', + creator_name: 'Ada Lovelace', + can_cancel: true, + }, + { + id: 'job-hl-run-02', + name: 'Diffusion Video Upscaler', + created: new Date(now - 3600000).toISOString(), + job_state: 'InProgress', + accelerator: 'nvidia', + device_count: 2, + image: 'ghcr.io/utmist/pytorch-cuda:latest', + cpu: '16', + memory: '64Gi', + node: 'mist-gpu-node-01', + checkpoint_directory: '/outputs/checkpoints/job-hl-run-02', + output_directory: '/outputs/runs/job-hl-run-02', + team_id: 'team-nlp', + creator_name: 'Grace Hopper', + can_cancel: true, + }, + { + id: 'job-hl-run-03', + name: 'TT Wormhole Full-Board Stress Test', + created: new Date(now - 5400000).toISOString(), + job_state: 'InProgress', + accelerator: 'tenstorrent', + device_count: 4, + image: 'ghcr.io/utmist/tt-metal-runtime:latest', + cpu: '16', + memory: '64Gi', + node: 'mist-tt-worker-01', + checkpoint_directory: '/outputs/checkpoints/job-hl-run-03', + output_directory: '/outputs/runs/job-hl-run-03', + team_id: 'team-vision', + creator_name: 'Alan Turing', + can_cancel: true, + }, + // Queued jobs + ...Array.from({ length: 8 }, (_, i) => ({ + id: `job-hl-wait-0${i + 1}`, + name: `Queued Experiment #${i + 1}`, + created: new Date(now - (8 - i) * 300000).toISOString(), + job_state: 'Scheduled', + accelerator: i % 2 === 0 ? 'nvidia' : 'tenstorrent', + device_count: (i % 2) + 1, + image: i % 2 === 0 ? 'ghcr.io/utmist/pytorch-cuda:latest' : 'ghcr.io/utmist/tt-metal-runtime:latest', + cpu: '4', + memory: '16Gi', + message: `Waiting for resources (Position in queue: ${i + 1})`, + checkpoint_directory: `/outputs/checkpoints/wait-${i + 1}`, + output_directory: `/outputs/runs/wait-${i + 1}`, + team_id: i % 2 === 0 ? 'team-vision' : 'team-nlp', + creator_name: i % 3 === 0 ? 'Ada Lovelace' : i % 3 === 1 ? 'Alan Turing' : 'Grace Hopper', + can_cancel: true, + })), + ] + + return base +} + +export function createUnhealthyScenario() { + const now = Date.now() + const base = createDefaultScenario() + base.name = 'unhealthy' + base.description = SCENARIO_DESCRIPTIONS.unhealthy + + base.machines = [ + { + name: 'mist-gpu-node-01', + address: '10.0.1.10', + ready: false, + schedulable: false, + cpu_allocatable: '0', + memory_allocatable: '0Gi', + }, + { + name: 'mist-tt-worker-01', + address: '10.0.1.11', + ready: true, + schedulable: false, // Placement paused! + cpu_allocatable: '16', + memory_allocatable: '64Gi', + }, + ] + + base.pools = [ + { + accelerator: 'nvidia', + node: 'mist-gpu-node-01', + unit: 'GPU', + total: 4, + allocated: 0, + available: null, + ready: false, + message: 'Node offline; NVIDIA driver communication lost (NVML error 999)', + }, + { + accelerator: 'tenstorrent', + node: 'mist-tt-worker-01', + unit: 'board', + total: 4, + allocated: 0, + available: 0, + ready: false, + chips_per_device: 2, + message: 'Node cordon active: scheduling paused for driver kernel patch', + }, + ] + + base.jobs = [ + { + id: 'job-fail-001', + name: 'Vision Model OOM Failure', + created: new Date(now - 7200000).toISOString(), + job_state: 'Failure', + accelerator: 'nvidia', + device_count: 2, + image: 'ghcr.io/utmist/pytorch-cuda:latest', + cpu: '8', + memory: '16Gi', + node: 'mist-gpu-node-01', + exit_code: 137, + message: 'Command terminated by SIGKILL (Out of Memory - cgroup limit exceeded)', + checkpoint_directory: '/outputs/checkpoints/job-fail-001', + output_directory: '/outputs/runs/job-fail-001', + team_id: 'team-vision', + creator_name: 'Ada Lovelace', + can_cancel: false, + }, + { + id: 'job-fail-002', + name: 'Faulty Python Script Crash', + created: new Date(now - 3600000).toISOString(), + job_state: 'Failure', + accelerator: 'cpu', + device_count: 0, + image: 'docker.io/library/python:3.11-slim', + cpu: '2', + memory: '4Gi', + node: 'mist-tt-worker-01', + exit_code: 1, + message: 'RuntimeError: ModuleNotFoundError: No module named torch_geometric', + checkpoint_directory: '/outputs/checkpoints/job-fail-002', + output_directory: '/outputs/runs/job-fail-002', + team_id: 'team-nlp', + creator_name: 'Grace Hopper', + can_cancel: false, + }, + { + id: 'job-stuck-003', + name: 'Stuck Queued Job', + created: new Date(now - 1800000).toISOString(), + job_state: 'Scheduled', + accelerator: 'nvidia', + device_count: 1, + image: 'ghcr.io/utmist/pytorch-cuda:latest', + cpu: '4', + memory: '16Gi', + message: '0/2 nodes are available: 1 node is offline, 1 node has untolerated taint', + checkpoint_directory: '/outputs/checkpoints/job-stuck-003', + output_directory: '/outputs/runs/job-stuck-003', + team_id: 'team-vision', + creator_name: 'Alan Turing', + can_cancel: true, + }, + ] + + return base +} + +export function createEmptySlateScenario() { + return { + name: 'empty-slate', + description: SCENARIO_DESCRIPTIONS['empty-slate'], + currentUserIndex: 0, + storageBudgetGiB: 1000, + users: [ + { + id: 'usr_newcomer', + name: 'New Researcher', + email: 'researcher@utmist.gitlab.io', + role: 'admin', + banned: false, + }, + ], + machines: [ + { + name: 'lab-cluster-master', + address: '192.168.1.10', + ready: true, + schedulable: true, + cpu_allocatable: '16', + memory_allocatable: '64Gi', + }, + ], + pools: [ + { + accelerator: 'nvidia', + node: 'lab-cluster-master', + unit: 'GPU', + total: 2, + allocated: 0, + available: 2, + ready: true, + }, + ], + storage: { + enabled: true, + capacity_bytes: 536870912000, // 500 GiB + available_bytes: 536870912000, + model_capacity_bytes: 1073741824000, + model_available_bytes: 1073741824000, + dataset_allocation_gib: 0, + model_allocation_gib: 0, + upload_limit_bytes: 5368709120, + }, + teams: [], + jobs: [], + datasets: [], + } +} + +export function createLargeClusterScenario() { + const now = Date.now() + const base = createDefaultScenario() + base.name = 'large-cluster' + base.description = SCENARIO_DESCRIPTIONS['large-cluster'] + base.storageBudgetGiB = 10000 + + base.users = [ + { id: 'usr_ada', name: 'Ada Lovelace', email: 'ada@utmist.gitlab.io', role: 'admin', banned: false }, + { id: 'usr_alan', name: 'Alan Turing', email: 'alan@utmist.gitlab.io', role: 'user', banned: false }, + { id: 'usr_grace', name: 'Grace Hopper', email: 'grace@utmist.gitlab.io', role: 'user', banned: false }, + { id: 'usr_curie', name: 'Marie Curie', email: 'marie@utmist.gitlab.io', role: 'admin', banned: false }, + { id: 'usr_feynman', name: 'Richard Feynman', email: 'feynman@utmist.gitlab.io', role: 'user', banned: false }, + { id: 'usr_shannon', name: 'Claude Shannon', email: 'shannon@utmist.gitlab.io', role: 'user', banned: false }, + { id: 'usr_neumann', name: 'John von Neumann', email: 'neumann@utmist.gitlab.io', role: 'user', banned: true }, + ] + + base.machines = [ + { name: 'dgx-h100-node-01', address: '10.10.1.1', ready: true, schedulable: true, cpu_allocatable: '64', memory_allocatable: '512Gi' }, + { name: 'dgx-h100-node-02', address: '10.10.1.2', ready: true, schedulable: true, cpu_allocatable: '64', memory_allocatable: '512Gi' }, + { name: 'tt-wormhole-box-01', address: '10.10.1.3', ready: true, schedulable: true, cpu_allocatable: '32', memory_allocatable: '128Gi' }, + { name: 'tt-wormhole-box-02', address: '10.10.1.4', ready: true, schedulable: true, cpu_allocatable: '32', memory_allocatable: '128Gi' }, + { name: 'control-plane-k3s', address: '10.10.1.100', ready: true, schedulable: true, cpu_allocatable: '16', memory_allocatable: '64Gi' }, + ] + + base.pools = [ + { accelerator: 'nvidia', node: 'dgx-h100-node-01', unit: 'GPU', total: 8, allocated: 4, available: 4, ready: true }, + { accelerator: 'nvidia', node: 'dgx-h100-node-02', unit: 'GPU', total: 8, allocated: 6, available: 2, ready: true }, + { accelerator: 'tenstorrent', node: 'tt-wormhole-box-01', unit: 'board', total: 4, allocated: 2, available: 2, ready: true, chips_per_device: 2 }, + { accelerator: 'tenstorrent', node: 'tt-wormhole-box-02', unit: 'board', total: 4, allocated: 1, available: 3, ready: true, chips_per_device: 2 }, + ] + + base.teams = [ + { + id: 'team-cv', + name: 'Computer Vision Lab', + disabled: false, + policy: { cpu: '32', memory: '128Gi', nvidia: 8, tenstorrent: 4, concurrent: 8, queued: 40, storage_gib: 1000, model_storage_gib: 2000, runtime_seconds: 86400, registries: ['docker.io', 'ghcr.io'] }, + members: [{ id: 'usr_ada', name: 'Ada Lovelace', email: 'ada@utmist.gitlab.io', common_writer: true }, { id: 'usr_curie', name: 'Marie Curie', email: 'marie@utmist.gitlab.io', common_writer: true }], + grants: [], + }, + { + id: 'team-llm', + name: 'Foundation Models & NLP', + disabled: false, + policy: { cpu: '64', memory: '256Gi', nvidia: 8, tenstorrent: 2, concurrent: 6, queued: 30, storage_gib: 2000, model_storage_gib: 4000, runtime_seconds: 86400, registries: ['docker.io', 'ghcr.io'] }, + members: [{ id: 'usr_grace', name: 'Grace Hopper', email: 'grace@utmist.gitlab.io', common_writer: true }, { id: 'usr_shannon', name: 'Claude Shannon', email: 'shannon@utmist.gitlab.io', common_writer: false }], + grants: [], + }, + { + id: 'team-robotics', + name: 'Autonomous Robotics', + disabled: false, + policy: { cpu: '16', memory: '64Gi', nvidia: 4, tenstorrent: 4, concurrent: 4, queued: 20, storage_gib: 800, model_storage_gib: 1200, runtime_seconds: 43200, registries: ['docker.io'] }, + members: [{ id: 'usr_alan', name: 'Alan Turing', email: 'alan@utmist.gitlab.io', common_writer: true }, { id: 'usr_feynman', name: 'Richard Feynman', email: 'feynman@utmist.gitlab.io', common_writer: false }], + grants: [], + }, + ] + + // Generate 25 jobs across all states + const jobStates = ['Success', 'InProgress', 'Scheduled', 'Failure', 'Cancelled'] + base.jobs = Array.from({ length: 25 }, (_, i) => ({ + id: `job-enterprise-${String(i + 1).padStart(3, '0')}`, + name: `Model Exploration #${i + 1}`, + created: new Date(now - (25 - i) * 1200000).toISOString(), + job_state: jobStates[i % jobStates.length], + accelerator: i % 3 === 0 ? 'nvidia' : i % 3 === 1 ? 'tenstorrent' : 'cpu', + device_count: i % 3 === 2 ? 0 : (i % 4) + 1, + image: i % 3 === 0 ? 'ghcr.io/utmist/pytorch-cuda:latest' : i % 3 === 1 ? 'ghcr.io/utmist/tt-metal-runtime:latest' : 'docker.io/library/python:3.11-slim', + cpu: String((i % 4 + 1) * 4), + memory: `${(i % 4 + 1) * 16}Gi`, + node: i % 2 === 0 ? 'dgx-h100-node-01' : 'tt-wormhole-box-01', + exit_code: jobStates[i % jobStates.length] === 'Failure' ? 1 : jobStates[i % jobStates.length] === 'Success' ? 0 : undefined, + message: jobStates[i % jobStates.length] === 'Failure' ? 'Killed by cluster controller' : undefined, + checkpoint_directory: `/outputs/checkpoints/job-enterprise-${i + 1}`, + output_directory: `/outputs/runs/job-enterprise-${i + 1}`, + team_id: i % 2 === 0 ? 'team-cv' : 'team-llm', + creator_name: base.users[i % base.users.length].name, + can_cancel: jobStates[i % jobStates.length] === 'InProgress' || jobStates[i % jobStates.length] === 'Scheduled', + })) + + return base +} + +export const SCENARIO_FACTORIES = { + default: createDefaultScenario, + 'high-load': createHighLoadScenario, + unhealthy: createUnhealthyScenario, + 'empty-slate': createEmptySlateScenario, + 'large-cluster': createLargeClusterScenario, +} + +export function getScenario(name) { + const factory = SCENARIO_FACTORIES[name] + if (!factory) { + throw new Error(`Unknown scenario '${name}'. Available: ${Object.keys(SCENARIO_FACTORIES).join(', ')}`) + } + return factory() +} diff --git a/scripts/fake-backend.mjs b/scripts/fake-backend.mjs new file mode 100644 index 0000000..d267623 --- /dev/null +++ b/scripts/fake-backend.mjs @@ -0,0 +1,882 @@ +#!/usr/bin/env node +/** + * Mist Fake Backend Server + * + * A standalone, zero-dependency Node.js HTTP server simulating the Mist Go API + * and Better Auth service. Designed for local frontend development, testing, + * and rapid prototyping without requiring k3s, GPUs, or Better Auth SQLite. + * + * Usage: + * node scripts/fake-backend.mjs + * node scripts/fake-backend.mjs --scenario high-load + * node scripts/fake-backend.mjs --config ./custom-config.json + * PORT=3000 node scripts/fake-backend.mjs + * npm --prefix web-interface run fake-backend + */ + +import http from 'node:http' +import fs from 'node:fs' +import path from 'node:path' +import { URL, fileURLToPath } from 'node:url' +import crypto from 'node:crypto' +import { + getScenario, + SCENARIO_DESCRIPTIONS, + SCENARIO_FACTORIES, +} from './fake-backend-scenarios.mjs' + +// Parse command line arguments +const args = process.argv.slice(2) +function getArg(flag) { + const idx = args.indexOf(flag) + return idx !== -1 && args[idx + 1] ? args[idx + 1] : null +} + +const PORT = Number( + getArg('--port') || process.env.PORT || process.env.MIST_FAKE_PORT || 3000, +) +const HOST = process.env.HOST || '127.0.0.1' +const ROOT_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') +const DEFAULT_CONFIG_FILE = path.resolve(ROOT_DIR, '.fake-backend-config.json') + +// --- Initial State Management --- + +let state = { + activeScenario: 'default', + users: [], + currentUserIndex: 0, + machines: [], + pools: [], + storageBudgetGiB: 2000, + storage: {}, + teams: [], + jobs: [], + datasets: [], + images: { + self_service: true, + teams_enabled: true, + registries: ['docker.io', 'ghcr.io', 'quay.io', 'localhost:5000'], + images: [ + { reference: 'docker.io/library/python:3.11-slim', accelerators: ['cpu'] }, + { reference: 'docker.io/library/pytorch-cpu:2.2.0', accelerators: ['cpu'] }, + { reference: 'ghcr.io/utmist/pytorch-cuda:latest', accelerators: ['nvidia'] }, + { reference: 'ghcr.io/utmist/tt-metal-runtime:latest', accelerators: ['tenstorrent'] }, + ], + profiles: [ + { + accelerator: 'cpu', + default_image: 'docker.io/library/python:3.11-slim', + device_unit: 'core', + max_devices: 16, + note: 'Standard CPU runtime', + }, + { + accelerator: 'nvidia', + default_image: 'ghcr.io/utmist/pytorch-cuda:latest', + device_unit: 'GPU', + max_devices: 4, + note: 'NVIDIA CUDA 12.4 + PyTorch runtime', + }, + { + accelerator: 'tenstorrent', + default_image: 'ghcr.io/utmist/tt-metal-runtime:latest', + device_unit: 'board', + max_devices: 4, + note: 'Tenstorrent Wormhole n300 PCIe runtime', + }, + ], + }, + jobLogs: new Map(), + jobFiles: new Map(), +} + +export function applyConfiguration(config) { + if (config.users) state.users = JSON.parse(JSON.stringify(config.users)) + if (config.currentUserIndex !== undefined) state.currentUserIndex = config.currentUserIndex + if (config.activeUserId) { + const idx = state.users.findIndex( + (u) => u.id === config.activeUserId || u.email.toLowerCase() === config.activeUserId.toLowerCase(), + ) + if (idx >= 0) state.currentUserIndex = idx + } + if (config.machines) state.machines = JSON.parse(JSON.stringify(config.machines)) + if (config.pools) state.pools = JSON.parse(JSON.stringify(config.pools)) + if (config.storage) state.storage = JSON.parse(JSON.stringify(config.storage)) + if (config.storageBudgetGiB !== undefined) state.storageBudgetGiB = config.storageBudgetGiB + if (config.teams) state.teams = JSON.parse(JSON.stringify(config.teams)) + if (config.jobs) { + state.jobs = JSON.parse(JSON.stringify(config.jobs)) + for (const job of state.jobs) { + if (!state.jobLogs.has(job.id)) { + state.jobLogs.set( + job.id, + `[${job.created}] Job ${job.name} initialized in state ${job.job_state}\n`, + ) + } + } + } + if (config.datasets) state.datasets = JSON.parse(JSON.stringify(config.datasets)) + if (config.images) state.images = JSON.parse(JSON.stringify(config.images)) + if (config.name) state.activeScenario = config.name +} + +// Determine initial scenario / config +function initializeState() { + const cliScenario = getArg('--scenario') || process.env.MIST_FAKE_SCENARIO + const cliConfig = getArg('--config') || process.env.MIST_FAKE_CONFIG + + if (cliScenario) { + try { + console.log(`[Config] Loading requested scenario: '${cliScenario}'`) + applyConfiguration(getScenario(cliScenario)) + return + } catch (err) { + console.warn(`[Config] Warning: ${err.message}. Falling back to default.`) + } + } + + if (cliConfig && fs.existsSync(cliConfig)) { + try { + console.log(`[Config] Loading configuration from: ${cliConfig}`) + const raw = fs.readFileSync(cliConfig, 'utf-8') + applyConfiguration(JSON.parse(raw)) + return + } catch (err) { + console.warn(`[Config] Failed to load config from ${cliConfig}: ${err.message}`) + } + } + + if (fs.existsSync(DEFAULT_CONFIG_FILE)) { + try { + console.log(`[Config] Found local ${DEFAULT_CONFIG_FILE}, loading...`) + const raw = fs.readFileSync(DEFAULT_CONFIG_FILE, 'utf-8') + applyConfiguration(JSON.parse(raw)) + return + } catch (err) { + console.warn(`[Config] Failed to parse ${DEFAULT_CONFIG_FILE}: ${err.message}`) + } + } + + // Fallback to default scenario + applyConfiguration(getScenario('default')) +} + +initializeState() + +// Automatically progress queued jobs over time +setInterval(() => { + for (const job of state.jobs) { + if (job.job_state === 'Scheduled') { + // Find suitable node if available + const pool = state.pools.find( + (p) => p.accelerator === job.accelerator && p.ready && (p.available === null || p.available > 0), + ) + if (pool) { + job.job_state = 'InProgress' + job.node = pool.node + job.message = `Pod running on ${job.node}` + const logs = state.jobLogs.get(job.id) || `[${new Date().toISOString()}] Job submitted.\n` + state.jobLogs.set( + job.id, + logs + `[${new Date().toISOString()}] Admitted to cluster. Initializing pod on ${job.node}...\n`, + ) + } + } else if (job.job_state === 'InProgress') { + const elapsed = Date.now() - new Date(job.created).getTime() + if (elapsed > 20000 && !job.id.startsWith('job-hl-run')) { + job.job_state = 'Success' + job.exit_code = 0 + job.message = 'Job completed successfully' + job.can_cancel = false + const logs = state.jobLogs.get(job.id) || '' + state.jobLogs.set( + job.id, + logs + `[${new Date().toISOString()}] Execution finished with code 0.\nOutputs saved.\n`, + ) + if (!state.jobFiles.has(job.id)) { + state.jobFiles.set(job.id, [ + { path: 'output.log', size: 2048, modified: new Date().toISOString() }, + { path: 'model_weights.bin', size: 52428800, modified: new Date().toISOString() }, + ]) + } + } + } + } +}, 5000) + +// --- Helper Functions --- + +function parseJSONBody(req) { + return new Promise((resolve, reject) => { + let data = '' + req.on('data', (chunk) => { + data += chunk + if (data.length > 50 * 1024 * 1024) { + req.destroy() + reject(new Error('Request payload too large')) + } + }) + req.on('end', () => { + if (!data.trim()) return resolve({}) + try { + resolve(JSON.parse(data)) + } catch (err) { + reject(new Error('Malformed JSON: ' + err.message)) + } + }) + req.on('error', reject) + }) +} + +function sendJSON(res, statusCode, payload) { + const body = JSON.stringify(payload) + res.writeHead(statusCode, { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(body), + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PATCH, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, X-Mist-Team, Authorization', + }) + res.end(body) +} + +function sendError(res, statusCode, message) { + sendJSON(res, statusCode, { error: message }) +} + +// --- Request Router --- + +const server = http.createServer(async (req, res) => { + // CORS Preflight + if (req.method === 'OPTIONS') { + res.writeHead(204, { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PATCH, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, X-Mist-Team, Authorization', + 'Access-Control-Max-Age': '86400', + }) + res.end() + return + } + + const parsedUrl = new URL(req.url, `http://${req.headers.host || 'localhost'}`) + let pathname = parsedUrl.pathname + const query = Object.fromEntries(parsedUrl.searchParams.entries()) + const activeTeam = req.headers['x-mist-team'] || query.team_id || '' + + // Normalize path by stripping optional '/api' prefix + if (pathname.startsWith('/api/')) { + pathname = pathname.slice(4) + } else if (pathname === '/api') { + pathname = '/' + } + + const currentUser = state.users[state.currentUserIndex] || null + + try { + // ---------------------------------------------------- + // FAKE BACKEND DYNAMIC CONFIGURATION & SCENARIO CONTROL + // ---------------------------------------------------- + + if (pathname === '/_fake/state' && req.method === 'GET') { + sendJSON(res, 200, { + activeScenario: state.activeScenario, + currentUserIndex: state.currentUserIndex, + currentUser, + users: state.users, + machines: state.machines, + pools: state.pools, + storage: state.storage, + storageBudgetGiB: state.storageBudgetGiB, + teams: state.teams, + jobs: state.jobs, + datasets: state.datasets, + }) + return + } + + if ((pathname === '/_fake/state' || pathname === '/_fake/configure') && req.method === 'POST') { + const body = await parseJSONBody(req) + applyConfiguration(body) + sendJSON(res, 200, { + success: true, + message: 'Configuration applied successfully', + activeScenario: state.activeScenario, + }) + return + } + + if (pathname === '/_fake/scenarios' && req.method === 'GET') { + sendJSON(res, 200, { + scenarios: Object.entries(SCENARIO_DESCRIPTIONS).map(([name, description]) => ({ + name, + description, + active: state.activeScenario === name, + })), + }) + return + } + + const scenarioMatch = pathname.match(/^\/_fake\/scenario\/([^/]+)$/) + if (scenarioMatch && req.method === 'POST') { + const name = scenarioMatch[1] + try { + const scenarioData = getScenario(name) + applyConfiguration(scenarioData) + sendJSON(res, 200, { + success: true, + scenario: name, + message: `Switched to hypothetical scenario: '${name}'`, + }) + } catch (err) { + sendError(res, 400, err.message) + } + return + } + + if (pathname === '/_fake/reset' && req.method === 'POST') { + const defaultData = getScenario('default') + applyConfiguration(defaultData) + sendJSON(res, 200, { success: true, message: 'Reset to default scenario' }) + return + } + + // ---------------------------------------------------- + // AUTH & SESSION ENDPOINTS + // ---------------------------------------------------- + + if (pathname === '/session' && req.method === 'GET') { + sendJSON(res, 200, { + enabled: true, + user: currentUser, + }) + return + } + + if (pathname === '/auth/get-session' && req.method === 'GET') { + if (!currentUser) { + sendJSON(res, 200, null) + } else { + sendJSON(res, 200, { + user: currentUser, + session: { + id: 'sess_' + currentUser.id, + userId: currentUser.id, + expiresAt: new Date(Date.now() + 86400000).toISOString(), + }, + }) + } + return + } + + if (pathname === '/auth/sign-in/email' && req.method === 'POST') { + const body = await parseJSONBody(req) + const user = state.users.find( + (u) => u.email.toLowerCase() === (body.email || '').toLowerCase(), + ) + if (!user) { + sendJSON(res, 401, { + error: { message: 'Invalid credentials or user not found' }, + }) + return + } + if (user.banned) { + sendJSON(res, 403, { + error: { message: 'Account is deactivated' }, + }) + return + } + state.currentUserIndex = state.users.findIndex((u) => u.id === user.id) + sendJSON(res, 200, { + user, + session: { + id: 'sess_' + user.id, + userId: user.id, + expiresAt: new Date(Date.now() + 86400000).toISOString(), + }, + }) + return + } + + if (pathname === '/auth/sign-out' && req.method === 'POST') { + state.currentUserIndex = -1 // signed out + sendJSON(res, 200, { success: true }) + return + } + + if (pathname === '/auth/change-password' && req.method === 'POST') { + await parseJSONBody(req) + sendJSON(res, 200, { success: true }) + return + } + + if ( + (pathname === '/auth/admin/list-users' || pathname === '/auth/admin/listUsers') && + (req.method === 'GET' || req.method === 'POST') + ) { + sendJSON(res, 200, { + users: state.users, + total: state.users.length, + }) + return + } + + if (pathname === '/auth/admin/create-user' && req.method === 'POST') { + const body = await parseJSONBody(req) + if (!body.name || !body.email) { + sendError(res, 400, 'Name and email are required') + return + } + const newUser = { + id: 'usr_' + crypto.randomBytes(4).toString('hex'), + name: body.name, + email: body.email, + role: body.role || 'user', + banned: false, + } + state.users.push(newUser) + sendJSON(res, 200, { user: newUser }) + return + } + + if (pathname === '/auth/admin/set-user-password' && req.method === 'POST') { + await parseJSONBody(req) + sendJSON(res, 200, { success: true }) + return + } + + if (pathname === '/auth/admin/revoke-user-sessions' && req.method === 'POST') { + await parseJSONBody(req) + sendJSON(res, 200, { success: true }) + return + } + + if (pathname === '/auth/admin/ban-user' && req.method === 'POST') { + const body = await parseJSONBody(req) + const target = state.users.find((u) => u.id === body.userId) + if (target) target.banned = true + sendJSON(res, 200, { success: true }) + return + } + + if (pathname === '/auth/admin/unban-user' && req.method === 'POST') { + const body = await parseJSONBody(req) + const target = state.users.find((u) => u.id === body.userId) + if (target) target.banned = false + sendJSON(res, 200, { success: true }) + return + } + + // ---------------------------------------------------- + // HARDWARE & IMAGES ENDPOINTS + // ---------------------------------------------------- + + if (pathname === '/hardware' && req.method === 'GET') { + sendJSON(res, 200, { + observed_at: new Date().toISOString(), + machines: state.machines, + pools: state.pools, + }) + return + } + + if (pathname === '/images' && req.method === 'GET') { + sendJSON(res, 200, state.images) + return + } + + // ---------------------------------------------------- + // TEAMS ENDPOINTS + // ---------------------------------------------------- + + if (pathname === '/teams' && req.method === 'GET') { + sendJSON(res, 200, { + teams: state.teams, + storage_budget_gib: state.storageBudgetGiB, + }) + return + } + + if (pathname === '/teams' && req.method === 'POST') { + const body = await parseJSONBody(req) + const newTeam = { + id: 'team-' + (body.name || 'unnamed').toLowerCase().replace(/\W+/g, '-'), + name: body.name || 'New Team', + disabled: false, + policy: { + cpu: '8', + memory: '32Gi', + nvidia: 1, + tenstorrent: 2, + concurrent: 2, + queued: 10, + storage_gib: Number(body.storage_gib || 200), + model_storage_gib: Number(body.model_storage_gib || 500), + runtime_seconds: 86400, + registries: ['docker.io', 'ghcr.io'], + }, + members: currentUser + ? [ + { + id: currentUser.id, + name: currentUser.name, + email: currentUser.email, + common_writer: true, + }, + ] + : [], + grants: [], + } + state.teams.push(newTeam) + sendJSON(res, 200, newTeam) + return + } + + const teamMatch = pathname.match(/^\/teams\/([^/]+)$/) + if (teamMatch && req.method === 'PATCH') { + const teamId = teamMatch[1] + const team = state.teams.find((t) => t.id === teamId) + if (!team) return sendError(res, 404, 'Team not found') + const body = await parseJSONBody(req) + if (body.name !== undefined) team.name = body.name + if (body.disabled !== undefined) team.disabled = body.disabled + if (body.policy !== undefined) team.policy = { ...team.policy, ...body.policy } + sendJSON(res, 200, team) + return + } + + const teamMembersMatch = pathname.match(/^\/teams\/([^/]+)\/members$/) + if (teamMembersMatch && req.method === 'POST') { + const teamId = teamMembersMatch[1] + const team = state.teams.find((t) => t.id === teamId) + if (!team) return sendError(res, 404, 'Team not found') + const body = await parseJSONBody(req) + const user = state.users.find((u) => u.id === body.user_id) + if (!user) return sendError(res, 404, 'User not found') + const existing = team.members.find((m) => m.id === user.id) + if (existing) { + existing.common_writer = !!body.common_writer + } else { + team.members.push({ + id: user.id, + name: user.name, + email: user.email, + common_writer: !!body.common_writer, + }) + } + sendJSON(res, 200, team) + return + } + + const teamMemberDeleteMatch = pathname.match(/^\/teams\/([^/]+)\/members\/([^/]+)$/) + if (teamMemberDeleteMatch && req.method === 'DELETE') { + const teamId = teamMemberDeleteMatch[1] + const userId = decodeURIComponent(teamMemberDeleteMatch[2]) + const team = state.teams.find((t) => t.id === teamId) + if (!team) return sendError(res, 404, 'Team not found') + team.members = team.members.filter((m) => m.id !== userId) + sendJSON(res, 200, team) + return + } + + const teamGrantsMatch = pathname.match(/^\/teams\/([^/]+)\/grants$/) + if (teamGrantsMatch && req.method === 'POST') { + const teamId = teamGrantsMatch[1] + const team = state.teams.find((t) => t.id === teamId) + if (!team) return sendError(res, 404, 'Team not found') + const body = await parseJSONBody(req) + const newGrant = { + id: 'grant-' + crypto.randomBytes(3).toString('hex'), + target_team: body.target_team, + scope: body.scope || 'common', + } + team.grants.push(newGrant) + sendJSON(res, 200, team) + return + } + + const teamGrantDeleteMatch = pathname.match(/^\/teams\/([^/]+)\/grants\/([^/]+)$/) + if (teamGrantDeleteMatch && req.method === 'DELETE') { + const teamId = teamGrantDeleteMatch[1] + const grantId = teamGrantDeleteMatch[2] + const team = state.teams.find((t) => t.id === teamId) + if (!team) return sendError(res, 404, 'Team not found') + team.grants = team.grants.filter((g) => g.id !== grantId) + sendJSON(res, 200, team) + return + } + + // ---------------------------------------------------- + // JOBS ENDPOINTS + // ---------------------------------------------------- + + if (pathname === '/jobs' && req.method === 'GET') { + let filtered = state.jobs + if (activeTeam) { + filtered = filtered.filter((j) => j.team_id === activeTeam) + } + sendJSON(res, 200, { + jobs: filtered, + count: filtered.length, + }) + return + } + + if (pathname === '/jobs' && req.method === 'POST') { + const body = await parseJSONBody(req) + const jobId = 'job-' + crypto.randomBytes(4).toString('hex') + const newJob = { + id: jobId, + name: body.name || `Experiment ${jobId}`, + created: new Date().toISOString(), + job_state: 'Scheduled', + accelerator: body.accelerator || 'cpu', + device_count: body.device_count || (body.accelerator === 'cpu' ? 0 : 1), + image: body.image || 'docker.io/library/python:3.11-slim', + cpu: body.cpu || '2', + memory: body.memory || '4Gi', + message: 'Job submitted; awaiting placement', + checkpoint_directory: `/outputs/checkpoints/${jobId}`, + output_directory: `/outputs/runs/${jobId}`, + working_directory: body.working_directory || '/workspace', + timeout_seconds: body.timeout_seconds || 3600, + team_id: activeTeam || 'legacy', + creator_id: currentUser?.id || 'usr_anonymous', + creator_name: currentUser?.name || 'Local Developer', + storage_scope: body.storage_scope || currentUser?.id || 'common', + can_cancel: true, + } + state.jobs.unshift(newJob) + state.jobLogs.set( + jobId, + `[${newJob.created}] Job created: ${newJob.name}\n[${newJob.created}] Image: ${newJob.image}\n[${newJob.created}] Queueing job on Kubernetes admission controller...\n`, + ) + sendJSON(res, 200, { + job_id: jobId, + job: newJob, + }) + return + } + + const jobCancelMatch = pathname.match(/^\/jobs\/([^/]+)\/cancel$/) + if (jobCancelMatch && req.method === 'POST') { + const jobId = decodeURIComponent(jobCancelMatch[1]) + const job = state.jobs.find((j) => j.id === jobId) + if (!job) return sendError(res, 404, 'Job not found') + job.job_state = 'Cancelled' + job.message = 'Cancelled by user' + job.can_cancel = false + const logs = state.jobLogs.get(jobId) || '' + state.jobLogs.set( + jobId, + logs + `[${new Date().toISOString()}] Job cancelled by user.\n`, + ) + sendJSON(res, 200, job) + return + } + + const jobLogsMatch = pathname.match(/^\/jobs\/([^/]+)\/logs$/) + if (jobLogsMatch && req.method === 'GET') { + const jobId = decodeURIComponent(jobLogsMatch[1]) + const logs = state.jobLogs.get(jobId) || 'No logs recorded for this job yet.' + sendJSON(res, 200, { logs }) + return + } + + const jobFilesMatch = pathname.match(/^\/jobs\/([^/]+)\/files$/) + if (jobFilesMatch && req.method === 'GET') { + const jobId = decodeURIComponent(jobFilesMatch[1]) + const files = state.jobFiles.get(jobId) || [] + sendJSON(res, 200, { files }) + return + } + + const jobDownloadMatch = pathname.match(/^\/jobs\/([^/]+)\/files\/download$/) + if (jobDownloadMatch && req.method === 'GET') { + const filePath = query.path || 'output.txt' + res.writeHead(200, { + 'Content-Type': 'text/plain; charset=utf-8', + 'Content-Disposition': `attachment; filename="${filePath.split('/').pop()}"`, + 'Access-Control-Allow-Origin': '*', + }) + res.end(`[Mock file content for ${filePath} from job]`) + return + } + + // ---------------------------------------------------- + // STORAGE & DATASETS ENDPOINTS + // ---------------------------------------------------- + + if (pathname === '/storage' && req.method === 'GET') { + sendJSON(res, 200, state.storage) + return + } + + if (pathname === '/storage/folders' && req.method === 'GET') { + const folders = [] + for (const t of state.teams) { + folders.push({ + team_id: t.id, + team_name: t.name, + scope: 'common', + name: 'Common Space', + shared: false, + writable: true, + }) + for (const m of t.members) { + folders.push({ + team_id: t.id, + team_name: t.name, + scope: m.id, + name: `${m.name}'s Folder`, + shared: false, + writable: m.id === currentUser?.id, + }) + } + } + sendJSON(res, 200, { folders }) + return + } + + if (pathname === '/storage/files' && req.method === 'GET') { + if (query.download === 'true') { + const filePath = query.path || 'downloaded-file.dat' + res.writeHead(200, { + 'Content-Type': 'application/octet-stream', + 'Content-Disposition': `attachment; filename="${filePath.split('/').pop()}"`, + 'Access-Control-Allow-Origin': '*', + }) + res.end(`[Mock content of ${filePath} in team ${query.source_team}]`) + return + } + sendJSON(res, 200, { + files: [ + { + path: 'data/train_manifest.json', + size: 15360, + modified: new Date(Date.now() - 7200000).toISOString(), + }, + { + path: 'models/model_final.pt', + size: 89128960, + modified: new Date(Date.now() - 3600000).toISOString(), + }, + ], + }) + return + } + + if (pathname === '/datasets' && req.method === 'GET') { + let filtered = state.datasets + if (activeTeam) { + filtered = filtered.filter((d) => !d.team_id || d.team_id === activeTeam) + } + sendJSON(res, 200, { + datasets: filtered, + upload_limit_bytes: state.storage.upload_limit_bytes || 5368709120, + }) + return + } + + if (pathname === '/datasets' && req.method === 'POST') { + const filename = query.filename || 'dataset.bin' + const name = query.name || filename + const scope = query.scope || currentUser?.id || 'common' + const activeTeamObj = state.teams.find((t) => t.id === activeTeam) + + let totalBytes = 0 + req.on('data', (chunk) => { + totalBytes += chunk.length + }) + + req.on('end', () => { + const newDs = { + id: 'ds-' + crypto.randomBytes(4).toString('hex'), + name, + filename, + size: totalBytes || 1048576, + files: query.format === 'zip' ? 12 : 1, + sha256: crypto.randomBytes(32).toString('hex'), + created: new Date().toISOString(), + state: 'ready', + team_id: activeTeam || 'legacy', + team_name: activeTeamObj?.name || 'Legacy Workspace', + scope, + member_name: currentUser?.name || 'Local Pilot', + shared: false, + } + state.datasets.unshift(newDs) + sendJSON(res, 200, newDs) + }) + return + } + + const datasetDeleteMatch = pathname.match(/^\/datasets\/([^/]+)$/) + if (datasetDeleteMatch && req.method === 'DELETE') { + const datasetId = datasetDeleteMatch[1] + state.datasets = state.datasets.filter((d) => d.id !== datasetId) + sendJSON(res, 200, { success: true }) + return + } + + const datasetFilesMatch = pathname.match(/^\/datasets\/([^/]+)\/files$/) + if (datasetFilesMatch && req.method === 'GET') { + sendJSON(res, 200, { + files: [ + { + path: 'metadata.json', + size: 2048, + modified: new Date().toISOString(), + }, + { + path: 'samples/sample_001.png', + size: 45056, + modified: new Date().toISOString(), + }, + ], + }) + return + } + + const datasetDownloadMatch = pathname.match(/^\/datasets\/([^/]+)\/files\/download$/) + if (datasetDownloadMatch && req.method === 'GET') { + const filePath = query.path || 'dataset-file.dat' + res.writeHead(200, { + 'Content-Type': 'application/octet-stream', + 'Content-Disposition': `attachment; filename="${filePath.split('/').pop()}"`, + 'Access-Control-Allow-Origin': '*', + }) + res.end(`[Mock content of dataset file ${filePath}]`) + return + } + + if (pathname === '/healthz' && req.method === 'GET') { + sendJSON(res, 200, { status: 'ok', executor: 'fake-backend' }) + return + } + + sendError(res, 404, `Endpoint not found: ${req.method} ${pathname}`) + } catch (err) { + console.error('[Fake Backend Error]', err) + sendError(res, 500, 'Internal Server Error: ' + err.message) + } +}) + +server.listen(PORT, HOST, () => { + console.log(`======================================================`) + console.log(`Mist Fake Backend running at http://${HOST}:${PORT}`) + console.log(`Active Scenario: '${state.activeScenario}'`) + console.log(`Simulated User: ${state.users[state.currentUserIndex]?.name} (${state.users[state.currentUserIndex]?.role})`) + console.log(`Machines: ${state.machines.map((m) => m.name).join(', ')}`) + console.log(`Teams: ${state.teams.map((t) => t.name).join(', ')}`) + console.log(`Jobs: ${state.jobs.length} in history`) + console.log(`Run 'node scripts/configure-fake-backend.mjs' to modify`) + console.log(`======================================================`) +}) + +process.on('SIGINT', () => { + server.close(() => { + console.log('\nFake backend stopped.') + process.exit(0) + }) +}) diff --git a/web-interface/package.json b/web-interface/package.json index dbb88b7..0783ac3 100644 --- a/web-interface/package.json +++ b/web-interface/package.json @@ -14,6 +14,8 @@ "preview": "vite preview", "test": "vitest run", "lint": "eslint", + "fake-backend": "node ../scripts/fake-backend.mjs", + "configure-fake-backend": "node ../scripts/configure-fake-backend.mjs", "format": "prettier --check .", "check": "prettier --write . && eslint --fix" }, diff --git a/web-interface/pnpm-lock.yaml b/web-interface/pnpm-lock.yaml new file mode 100644 index 0000000..08effeb --- /dev/null +++ b/web-interface/pnpm-lock.yaml @@ -0,0 +1,4599 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@tailwindcss/vite': + specifier: ^4.1.18 + version: 4.3.3(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)) + '@tanstack/react-devtools': + specifier: latest + version: 0.10.13(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(csstype@3.2.3)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(solid-js@1.9.17) + '@tanstack/react-router': + specifier: latest + version: 1.170.45(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@tanstack/react-router-devtools': + specifier: latest + version: 1.167.2(@tanstack/react-router@1.170.45(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(@tanstack/router-core@1.171.38)(csstype@3.2.3)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@tanstack/router-plugin': + specifier: ^1.132.0 + version: 1.168.47(@tanstack/react-router@1.170.45(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(esbuild@0.28.2)(rollup@4.64.7)(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)) + better-auth: + specifier: 1.7.7 + version: 1.7.7(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(solid-js@1.9.17)(vitest@5.0.5(@types/node@22.20.5)(jsdom@28.1.0(@noble/hashes@2.4.0))(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0))) + lucide-react: + specifier: ^0.545.0 + version: 0.545.0(react@19.3.1) + react: + specifier: ^19.2.0 + version: 19.3.1 + react-dom: + specifier: ^19.2.0 + version: 19.3.1(react@19.3.1) + tailwindcss: + specifier: ^4.1.18 + version: 4.3.3 + devDependencies: + '@tailwindcss/typography': + specifier: ^0.5.16 + version: 0.5.20(tailwindcss@4.3.3) + '@tanstack/devtools-vite': + specifier: latest + version: 0.8.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)) + '@tanstack/eslint-config': + specifier: latest + version: 0.4.0(@typescript-eslint/utils@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3))(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + '@testing-library/dom': + specifier: ^10.4.1 + version: 10.4.2 + '@testing-library/react': + specifier: ^16.3.0 + version: 16.3.3(@testing-library/dom@10.4.2)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@types/node': + specifier: ^22.10.2 + version: 22.20.5 + '@types/react': + specifier: ^19.2.0 + version: 19.3.0 + '@types/react-dom': + specifier: ^19.2.0 + version: 19.3.0(@types/react@19.3.0) + '@vitejs/plugin-react': + specifier: ^5.1.4 + version: 5.2.0(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)) + jsdom: + specifier: ^28.1.0 + version: 28.1.0(@noble/hashes@2.4.0) + prettier: + specifier: ^3.8.1 + version: 3.9.10 + typescript: + specifier: ^5.7.2 + version: 5.9.3 + vite: + specifier: ^7.3.1 + version: 7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)) + vitest: + specifier: ^5.0.3 + version: 5.0.5(@types/node@22.20.5)(jsdom@28.1.0(@noble/hashes@2.4.0))(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)) + +packages: + + '@acemir/cssom@0.9.32': + resolution: {integrity: sha512-OijrAUu7rrJhSIoHNg6LMPS5e344nwUHA+1EFYYjrh64D+GmytUsfBQjci45TjT+rd5Spsp8B5xsZDT+TgyXXQ==} + + '@asamuzakjp/css-color@5.1.11': + resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/dom-selector@6.8.1': + resolution: {integrity: sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==} + + '@asamuzakjp/generational-cache@1.0.1': + resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/nwsapi@2.3.9': + resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.7': + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.8': + resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.29.7': + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.29.7': + resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.10': + resolution: {integrity: sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.9': + resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.29.7': + resolution: {integrity: sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.29.7': + resolution: {integrity: sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.29.10': + resolution: {integrity: sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.10': + resolution: {integrity: sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} + + '@better-auth/core@1.7.7': + resolution: {integrity: sha512-srgFzHEjB2WWlokFz1i4BfG41sNhsA105Pukgqu6RrEh5A+LSkzf1mCHydVipkjt9l5qswtBMi7IL6ouHbZL4Q==} + peerDependencies: + '@better-auth/utils': 0.4.2 + '@better-fetch/fetch': 1.3.2 + '@opentelemetry/api': ^1.9.0 + better-call: 1.4.0 + jose: ^6.1.0 + kysely: ^0.28.5 || ^0.29.0 + nanostores: ^1.0.1 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + + '@better-auth/drizzle-adapter@1.7.7': + resolution: {integrity: sha512-qon0U94PR5FQysuyGoAlGVQpIIiNg5dtDpwjE63sN/HjoRWZadZzHPcS9mn7JsJyQZK6iTNhd7LD0AaXt2f78w==} + peerDependencies: + '@better-auth/core': ^1.7.7 + '@better-auth/utils': 0.4.2 + drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0 + peerDependenciesMeta: + drizzle-orm: + optional: true + + '@better-auth/kysely-adapter@1.7.7': + resolution: {integrity: sha512-9FONOCgOcrQI9wJ5v1oDGIg9sT7pa9RjZZQ4fsCTudo8R87SrIGNUvUxDFTJhZvUblvFfGaIBR9Vb8LA+8bqLQ==} + peerDependencies: + '@better-auth/core': ^1.7.7 + '@better-auth/utils': 0.4.2 + kysely: ^0.28.17 || ^0.29.0 + peerDependenciesMeta: + kysely: + optional: true + + '@better-auth/memory-adapter@1.7.7': + resolution: {integrity: sha512-FqKFEe+b5tXXV0gRbyirca+qXgMpLOeJ8Wk19yykb/scQKy0WJ4k22WzEV3TTPctQV9DZhwCXPlDtQhnlOv5Gg==} + peerDependencies: + '@better-auth/core': ^1.7.7 + '@better-auth/utils': 0.4.2 + + '@better-auth/mongo-adapter@1.7.7': + resolution: {integrity: sha512-ZnVDuRrXqbf0oHphrEN27oTImNH5NTO26dtWatq5cXyYAsH7goof9QIoTOmxTbBxUQahKBw9T6+9h6n+RtOE+g==} + peerDependencies: + '@better-auth/core': ^1.7.7 + '@better-auth/utils': 0.4.2 + mongodb: ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + mongodb: + optional: true + + '@better-auth/prisma-adapter@1.7.7': + resolution: {integrity: sha512-4YcnrcVdvWiAZw0sZl63tWUClPXg5r3QsLn7C2sG7kKEBY06zOng0ibecyxRBixKq1zE1ceHuEUqez5Rhi+nQA==} + peerDependencies: + '@better-auth/core': ^1.7.7 + '@better-auth/utils': 0.4.2 + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + '@prisma/client': + optional: true + prisma: + optional: true + + '@better-auth/telemetry@1.7.7': + resolution: {integrity: sha512-PaRA6i+kAioVYmza2gHPcdrxP0hAotph4KV9hft2GeNJq+AZXDiBu3FuLM9HxvcmiZeUT74Vufqd9ypmB8veTA==} + peerDependencies: + '@better-auth/core': ^1.7.7 + '@better-auth/utils': 0.4.2 + '@better-fetch/fetch': 1.3.2 + + '@better-auth/utils@0.4.2': + resolution: {integrity: sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A==} + + '@better-auth/utils@0.5.0': + resolution: {integrity: sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA==} + + '@better-fetch/fetch@1.3.2': + resolution: {integrity: sha512-Gs7n99b5tqUC6cQAPbV0uED3IraHB6xQbHLQ/C3l7ZFafHScOx9pQ+DYmP5blbLFShVWLqxNUlI9wi4xU/X+ow==} + + '@bramus/specificity@2.4.3': + resolution: {integrity: sha512-0GEz8qJWokkUVYQYRukmkSHIFNoBH8QTreeHrAFbvz1XFYc3Y+puhMs8PQ5x8GNugiC2l5jvDBXKLbBIByeSBw==} + hasBin: true + + '@cacheable/memory@2.2.0': + resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==} + + '@cacheable/utils@2.5.0': + resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==} + + '@csstools/color-helpers@6.1.2': + resolution: {integrity: sha512-grhRy3OKmniaAEKXMjua5z/EODX0MSqBGjunw8+j/3HQjOnahs2AGhvEOIYVUWcU6ScApbhLhVrQTX8XqrMrow==} + engines: {node: '>=20.19.0'} + + '@csstools/css-calc@3.4.3': + resolution: {integrity: sha512-iex20d8CHVkyvg6B7UKV7uHnI2Bqo9g+EFfT9E0y+GvTvhZ/DwONJ+9aKb1dlqm0ZiGsL5RXjp0fCoJYnkeDjA==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.2 + '@csstools/css-tokenizer': ^4.0.2 + + '@csstools/css-color-parser@4.2.6': + resolution: {integrity: sha512-iiPQ3iRWwnJkeEn6RIu6SJPr7hYrLz6XZ9s/QZl+2/LI5KQVjpl2fdmDSZKuD4xP6GMmMPgHFFXg6k1Wkz0Trg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.2 + '@csstools/css-tokenizer': ^4.0.2 + + '@csstools/css-parser-algorithms@4.0.2': + resolution: {integrity: sha512-40cSKyMvK+tq4qz6Awrlye2WGuOKt3FwPgtGg6KTfbHOWNw+Rk1rzbAtZnZ6IBhsY491HLRnDXwoyBAijmmILA==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-tokenizer': ^4.0.2 + + '@csstools/css-syntax-patches-for-csstree@1.1.15': + resolution: {integrity: sha512-J0u7HkVl2nzSlhsiTOp4AmwcUQ3D+mGEEKfBy/7To5/y7F2OHwyLrXfrhR0SMgr4p5Lo+eaMVSeai24zUcBIxA==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true + + '@csstools/css-tokenizer@4.0.2': + resolution: {integrity: sha512-OoKoR0f76dCY666JlcbhmVTs2drYj1GUXZTYTcbUgJjh9Nv41aFfZ21bPQTERm5+L5cBDo466NltB2lplS5GBw==} + engines: {node: '>=20.19.0'} + + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.23.5': + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-helpers@0.7.0': + resolution: {integrity: sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/core@1.2.1': + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/js@10.0.1': + resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + peerDependencies: + eslint: ^10.0.0 + peerDependenciesMeta: + eslint: + optional: true + + '@eslint/object-schema@3.0.5': + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/plugin-kit@0.7.3': + resolution: {integrity: sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@exodus/bytes@1.16.0': + resolution: {integrity: sha512-IcpW84uEn3N7ETtNZMlxKhfl6Pec8rUNGOTBtWbK1FKhJxIFAptZyVrvVRVBimAJxJCgc3PxepxkdWWG4DVzfA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@noble/hashes': ^1.8.0 || ^2.0.0 + peerDependenciesMeta: + '@noble/hashes': + optional: true + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@keyv/bigmap@1.3.1': + resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==} + engines: {node: '>= 18'} + peerDependencies: + keyv: ^5.6.0 + + '@keyv/serialize@1.1.1': + resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} + engines: {node: ^22.20 || ^24.12 || >=25} + cpu: [x64] + os: [linux] + + '@napi-rs/wasm-runtime@1.2.5': + resolution: {integrity: sha512-HshSvXzmBxNzqejd3k/KemgQ3hdREUYFRRrgxOZ+gPljDIsO2SDZrVZMd4Z/HsxudQbE62OVyVFE8z9BCurfjA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 + + '@neodrag/core@3.0.0-next.11': + resolution: {integrity: sha512-3WQWxyrbxiaK9zS5JU2wJsW2gpoQlZBXVghduBh61JpqaeE0T0cte8R0qYK2RuJo3J2TYQYqxO19CpG/C1i5eg==} + + '@neodrag/solid@3.0.0-next.11': + resolution: {integrity: sha512-vCBIn/pimjWMQ6vhTS2/O1XNAwzVtc4eUhdbQ91WykbZWWqQ5NocDXt/1OdYrEkeRzJcpCv8wEz5PnMkgKP81Q==} + peerDependencies: + '@neodrag/core': 3.0.0-next.11 + solid-js: ^1.0.0 + + '@noble/ciphers@2.4.0': + resolution: {integrity: sha512-AnjFn0Jv92laAkvMrghlFZq4qQCIN/4DxFV/eooqtC2YTjB7kBeLMS2T9KJX4Dn+ZVXLOwK0lSgqDtx9gvxtiw==} + engines: {node: '>= 20.19.0'} + + '@noble/hashes@2.4.0': + resolution: {integrity: sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==} + engines: {node: '>= 20.19.0'} + + '@opentelemetry/semantic-conventions@1.43.0': + resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} + engines: {node: '>=14'} + + '@oxc-parser/binding-android-arm-eabi@0.120.0': + resolution: {integrity: sha512-WU3qtINx802wOl8RxAF1v0VvmC2O4D9M8Sv486nLeQ7iPHVmncYZrtBhB4SYyX+XZxj2PNnCcN+PW21jHgiOxg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm64@0.120.0': + resolution: {integrity: sha512-SEf80EHdhlbjZEgzeWm0ZA/br4GKMenDW3QB/gtyeTV1gStvvZeFi40ioHDZvds2m4Z9J1bUAUL8yn1/+A6iGg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.120.0': + resolution: {integrity: sha512-xVrrbCai8R8CUIBu3CjryutQnEYhZqs1maIqDvtUCFZb8vY33H7uh9mHpL3a0JBIKoBUKjPH8+rzyAeXnS2d6A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.120.0': + resolution: {integrity: sha512-xyHBbnJ6mydnQUH7MAcafOkkrNzQC6T+LXgDH/3InEq2BWl/g424IMRiJVSpVqGjB+p2bd0h0WRR8iIwzjU7rw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-freebsd-x64@0.120.0': + resolution: {integrity: sha512-UMnVRllquXUYTeNfFKmxTTEdZ/ix1nLl0ducDzMSREoWYGVIHnOOxoKMWlCOvRr9Wk/HZqo2rh1jeumbPGPV9A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.120.0': + resolution: {integrity: sha512-tkvn2CQ7QdcsMnpfiX3fd3wA3EFsWKYlcQzq9cFw/xc89Al7W6Y4O0FgLVkVQpo0Tnq/qtE1XfkJOnRRA9S/NA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.120.0': + resolution: {integrity: sha512-WN5y135Ic42gQDk9grbwY9++fDhqf8knN6fnP+0WALlAUh4odY/BDK1nfTJRSfpJD9P3r1BwU0m3pW2DU89whQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.120.0': + resolution: {integrity: sha512-1GgQBCcXvFMw99EPdMy+4NZ3aYyXsxjf9kbUUg8HuAy3ZBXzOry5KfFEzT9nqmgZI1cuetvApkiJBZLAPo8uaw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-arm64-musl@0.120.0': + resolution: {integrity: sha512-gmMQ70gsPdDBgpcErvJEoWNBr7bJooSLlvOBVBSGfOzlP5NvJ3bFvnUeZZ9d+dPrqSngtonf7nyzWUTUj/U+lw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-ppc64-gnu@0.120.0': + resolution: {integrity: sha512-T/kZuU0ajop0xhzVMwH5r3srC9Nqup5HaIo+3uFjIN5uPxa0LvSxC1ZqP4aQGJVW5G0z8/nCkjIfSMS91P/wzw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@oxc-parser/binding-linux-riscv64-gnu@0.120.0': + resolution: {integrity: sha512-vn21KXLAXzaI3N5CZWlBr1iWeXLl9QFIMor7S1hUjUGTeUuWCoE6JZB040/ZNDwf+JXPX8Ao9KbmJq9FMC2iGw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + + '@oxc-parser/binding-linux-riscv64-musl@0.120.0': + resolution: {integrity: sha512-SUbUxlar007LTGmSLGIC5x/WJvwhdX+PwNzFJ9f/nOzZOrCFbOT4ikt7pJIRg1tXVsEfzk5mWpGO1NFiSs4PIw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + + '@oxc-parser/binding-linux-s390x-gnu@0.120.0': + resolution: {integrity: sha512-hYiPJTxyfJY2+lMBFk3p2bo0R9GN+TtpPFlRqVchL1qvLG+pznstramHNvJlw9AjaoRUHwp9IKR7UZQnRPGjgQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + + '@oxc-parser/binding-linux-x64-gnu@0.120.0': + resolution: {integrity: sha512-q+5jSVZkprJCIy3dzJpApat0InJaoxQLsJuD6DkX8hrUS61z2lHQ1Fe9L2+TYbKHXCLWbL0zXe7ovkIdopBGMQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-linux-x64-musl@0.120.0': + resolution: {integrity: sha512-D9QDDZNnH24e7X4ftSa6ar/2hCavETfW3uk0zgcMIrZNy459O5deTbWrjGzZiVrSWigGtlQwzs2McBP0QsfV1w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-openharmony-arm64@0.120.0': + resolution: {integrity: sha512-TBU8ZwOUWAOUWVfmI16CYWbvh4uQb9zHnGBHsw5Cp2JUVG044OIY1CSHODLifqzQIMTXvDvLzcL89GGdUIqNrA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-wasm32-wasi@0.120.0': + resolution: {integrity: sha512-WG/FOZgDJCpJnuF3ToG/K28rcOmSY7FmFmfBKYb2fmLyhDzPpUldFGV7/Fz4ru0Iz/v4KPmf8xVgO8N3lO4KHA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.120.0': + resolution: {integrity: sha512-1T0HKGcsz/BKo77t7+89L8Qvu4f9DoleKWHp3C5sJEcbCjDOLx3m9m722bWZTY+hANlUEs+yjlK+lBFsA+vrVQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.120.0': + resolution: {integrity: sha512-L7vfLzbOXsjBXV0rv/6Y3Jd9BRjPeCivINZAqrSyAOZN3moCopDN+Psq9ZrGNZtJzP8946MtlRFZ0Als0wBCOw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.120.0': + resolution: {integrity: sha512-ys+upfqNtSu58huAhJMBKl3XCkGzyVFBlMlGPzHeFKgpFF/OdgNs1MMf8oaJIbgMH8ZxgGF7qfue39eJohmKIg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.120.0': + resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==} + + '@rolldown/pluginutils@1.0.0-rc.3': + resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} + + '@rollup/rollup-android-arm-eabi@4.64.7': + resolution: {integrity: sha512-GFF2tHk0NqYVObrK0+/ps/LEXsV/v2q6Lyiy7mZr+Ej24fpQScvqK2ziz9NHeEQYnKWKym38Ml7dZbPtC9tuAw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.64.7': + resolution: {integrity: sha512-BOymcXJFYYXqluDidj6sLelNjXruC3u1BqVxLn2OPCXH9xaPSOTH+MS4uychsGI1NU7tJoiv9KvqijDHFe+hhQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.64.7': + resolution: {integrity: sha512-jgVpGweIbls2H5jfBB70tnX52abMd5pJr3xmtoDILx6JdmGl+Un+tMb9R+MbHPVB46tTBpY8emtn7M71SnQhEQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.64.7': + resolution: {integrity: sha512-AVMpt94mrXH7WjyWKmd9nT4RC5yM0AN3Lt6A89xVIsuLDi3dDX6dxMytLbW36FlppY9JsoqUoS3LUUpUrYxiMQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.64.7': + resolution: {integrity: sha512-Nje29c/MyajxRNFGU05oyeTDS6SWdMg/wWMSlZSBTBju5BKz2NVc0kFiFSQGzRELNiB+CBk/ZvAVsWsENgjGag==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.64.7': + resolution: {integrity: sha512-xxgN5/kMzCNz/NYJ4t49B0/WS6InNlWv6xvgwUQqNnWM9WJMMwMUGWrAxdNEgYWdHL0sMnuh8I87StGrIMTA+w==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.64.7': + resolution: {integrity: sha512-5U/9gVn/X657I8+NHoHO9Wnfyd0lEXwqbslobRoB9TC8SwYzOitcIr6TLE7531Q/NWs3L4mb+YOGzlf3vHIeYw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.64.7': + resolution: {integrity: sha512-hcDS0a/Y8ggM3dcOfzH7UpSaogCViWTtNDSl0EXpWIj8g8/r86ITqptjil2hayTXS0Umzb+Yt3mjgpQVFVf2+A==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.64.7': + resolution: {integrity: sha512-awbAr4N7Qd/yjZAQBEEPzgcPveYG2Gi5L6gq1/Bp+3SMRjn5F68Wv1zKsntzvvoioBR6yKvhLtWqu11am1TsxA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.64.7': + resolution: {integrity: sha512-Ut7xQJfeLhzu2yN3rHzVvL9ccyPJvN4aCdP1V7hJ5lGxX/eCzgB9SiMk/Md3J+rWWZgvoYsDW4BUFggJr32pBA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.64.7': + resolution: {integrity: sha512-trqoni/vHkuM5oo5iQhoKPh6fjjD7E80pMgCXWgGxU8vSRPUlwvG8GeYvEEcB6eJAxNa99WH9iVHPHelgtKiHA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.64.7': + resolution: {integrity: sha512-gvlUy0XFIwtUWiQmhc+4GT2Knm3KosinpUVhr7CtTFA78gFDnE5NWwMPzHrJsYpKkh2LlY7yvBIboN1FAV6Xeg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.64.7': + resolution: {integrity: sha512-8yS/kSXTJ/47Z62JW+C2AJ3vd/8zZw016vFjtNpZwmZlwJumLua4s1i78dkYuSSqQ+0aIMxJcBp/4uIwp2ehjA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.64.7': + resolution: {integrity: sha512-mxVSKvvty0hOP1AFo/l4Kpv3i3HK0zx4rYUrirZDToYlWhS3xzmIkq3vUJ7rtrM2cPyXveDyDT6M1FfXZ9hTRA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.64.7': + resolution: {integrity: sha512-lEse1zra1CagM+uHH2bl28GInDsZZ45NJzHei2OMaXQFzZWKBO1hFo07rS0xB6ayV4WU360UrSmPDSyCMpYsUQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.64.7': + resolution: {integrity: sha512-d/cqCoiG9WMZ5VuJZ5Qdlv9g97QyoGwnmvHccvGhKSacTy7xFrAS+jMcJSBdMNOw1oacSkl6p7K6O/DRYTKL3g==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.64.7': + resolution: {integrity: sha512-kVEA//CeDOZZP1XCH2JBgqXb9+ALlwuA/4civaazMVdgzaSQC9WM38w65zG/LLk0lA7F9Od19CSBZW7J9mCbNg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.64.7': + resolution: {integrity: sha512-14oLfDsOSr0TSntT/34jRg/V8B2XW/Jomh9zX9CjIM9gwwNlI1OCymS/GVn0DV32h67eRf7U0GGem0rvfXgNwQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.64.7': + resolution: {integrity: sha512-dFVtPfjZqAnUPpPY4Bfg+87yo1IBW9HiY8iCFtg49Pn46MfZTebSHZh8PL6SOsgyt9LQP8Nj/sE6jm3aWpySmQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.64.7': + resolution: {integrity: sha512-Dm9CZ2SM3u2NgvBj4awW/gGqkOwzH8f6MSYIJE6+bKcKLI+T0+LhpD6vtetTfrIIx+rLXDf5RJqBP6v7V5O+wg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.64.7': + resolution: {integrity: sha512-oaxsvS2mL6+78741CT2HCORBvy1USg3Wqpt5qvZwy3aMXRMl4zxyDo8maeFRWJkF3dp0Wbi71fKH5Gr9YI3vYA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.64.7': + resolution: {integrity: sha512-UKZz1Y4mxUqkWh60uH7B1aZn6UcAimPk4ipRktpb3wfZq7JrzZYyAXTwiafkb3T+kd5P3Sf+vzcRdsDks4WtjQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.64.7': + resolution: {integrity: sha512-WWkSuC1J+mZJnsDh0mRaCAFSWfQdl6y3fDjZeWElI6zHo8CcOSG5lY3yurKJjEq+FrX0WD60sFrVVpbHqzMmrw==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.64.7': + resolution: {integrity: sha512-u9bp2yXCI3/BUjUxY6uWknAY32pfvvDCPysyUTySotx0dj3ydlFHrRQYfn/b/kZgnfjyEwySMtI7Ga054uiysQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.64.7': + resolution: {integrity: sha512-EhX6N3XPMEnVU5cRfNgzPOKcSucsbu3nNNWuoAaEuKIqmddBKHN5b9d4rPe65T1I+FaOT176JKiZNsUBp3rqbA==} + cpu: [x64] + os: [win32] + + '@solid-primitives/event-listener@2.4.6': + resolution: {integrity: sha512-5I0YJcTVYIWoMmgBSROBZGcz+ymhew/pGTg2dHW74BUjFKsV8Li4bOZYl0YAGP4mHw5o4UBd9/BEesqBci3wxw==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/keyboard@1.3.7': + resolution: {integrity: sha512-558RPNYnXx4nGh537DSqAn4xMrC8iFipl/5+xzgzWoTNFst4RnUN3BOLmtDjJ0UGGoQXVMALYR3bNOHM0xnt1Q==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/resize-observer@2.2.0': + resolution: {integrity: sha512-9Fuu/EWBeGj+atGHRJp70HKhdfalmpjwxY8a32NZixdLNmfCJ45AfhLQNr6uOzETbbiMx4iCKlTrJ8KZCHC2Ww==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/rootless@1.5.4': + resolution: {integrity: sha512-TOIZa1VUfVJ+9nkCcRajw3U4t9vBOP1HxX1WHNTbXq32mXwlqTvUnC4CRIilohcryBkT9u2ZkhUDSHRTaGp55g==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/static-store@0.1.4': + resolution: {integrity: sha512-LgtVaVBtB7EbmS4+M0b8xY5Iq6pUWXBsIC4VgtrFKDGDdyCaDt88sHk0fUlx1Enxm/XZnZyLXJABRoa39RjJqA==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/utils@6.4.1': + resolution: {integrity: sha512-ISSB5QX1qP2ynrheIpYwc4oKR5Ny4siNuUyf1qZniy+Il+p/PtDB0QK1Dnle8noiHpwRD3gpPdubOC3qI/Zamg==} + peerDependencies: + solid-js: ^1.6.12 + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@stylistic/eslint-plugin@5.10.0': + resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + + '@tailwindcss/node@4.3.3': + resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} + + '@tailwindcss/oxide-android-arm64@4.3.3': + resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.3.3': + resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.3.3': + resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} + engines: {node: '>= 20'} + + '@tailwindcss/typography@0.5.20': + resolution: {integrity: sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw==} + peerDependencies: + tailwindcss: '>=3.0.0 || >=4.0.0 || insiders' + + '@tailwindcss/vite@4.3.3': + resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + + '@tanstack/devtools-bundler-core@0.1.3': + resolution: {integrity: sha512-F0tlxIyfFqXkZ1mJP1EjtkiSeJA+ztXY2AYOHf7r4goCIEAOp86N9PFJ/yv8vu1TnmxGS6vKsZCS3Kyls9xQQA==} + engines: {node: '>=18'} + + '@tanstack/devtools-client@0.0.8': + resolution: {integrity: sha512-cG3iZkGWCwN330bLBKa8+9r4Of2AXNoz2zUqcsy/4XsD3105ghVBx78cGyvJj9fSclNomPxoqAnDGXXhg1WLvA==} + engines: {node: '>=18'} + + '@tanstack/devtools-event-bus@0.4.3': + resolution: {integrity: sha512-NeegBt5/n2E5q4DbrXHqECBq42+kDi6JBOp8/+RNqkIE+P4hJpbM36kGyjnGQFMWOoku31qhMyX9/48VuTTdmg==} + engines: {node: '>=18'} + + '@tanstack/devtools-event-client@0.5.0': + resolution: {integrity: sha512-H+OH3zC6Vhu/K0NaVfQKknEKawc/+2PT+D3SB3Ox0V8SiMlTo0abbmH2rH0721R2aNYbjdMXA1oENOd8E2UVoA==} + engines: {node: '>=18'} + hasBin: true + + '@tanstack/devtools-ui@0.7.1': + resolution: {integrity: sha512-3xQ/ezZ2qVNszhjpCN2N3jn7uHc2J1PMgcyjHzH4XZBt9xAQyMMcPNoR2cd7rzReyxWoJpZUWiDBmOJiCtLj9A==} + engines: {node: '>=18'} + peerDependencies: + solid-js: '>=1.9.7' + + '@tanstack/devtools-vite@0.8.5': + resolution: {integrity: sha512-xaifCEmiwwzizlbp973oISXNsnmuU/BugLa66gryAZaPJJ/qo1kJd2DxY5X960eHwmyIS3SN0KYrL3/aRhucmA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@tanstack/devtools@0.15.0': + resolution: {integrity: sha512-KyS7Qi82Eq9yG8C+uae3ikAPb+D5rfzVhvOOjXVAHZ/64s6TWJlDWpREw1FrHIYZaI7paErpsExSSKlF5BKA/A==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + solid-js: '>=1.9.7' + + '@tanstack/eslint-config@0.4.0': + resolution: {integrity: sha512-V+Cd81W/f65dqKJKpytbwTGx9R+IwxKAHsG/uJ3nSLYEh36hlAr54lRpstUhggQB8nf/cP733cIw8DuD2dzQUg==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + + '@tanstack/history@1.162.5': + resolution: {integrity: sha512-w1+YvwmTkwt5n8yUqEH3IWZ9DsmorCZW/EQ3KYHnqEgIkOZpH54NvW6/Epq3Dzb8H0ifIeYX8PExvrNLIH5FIA==} + engines: {node: '>=20.19'} + + '@tanstack/react-devtools@0.10.13': + resolution: {integrity: sha512-r0cdB/14+st2Vxl/1Bodlyq4VC8pf9SykLQDYbGHDc1+V146WQo5B3KlYLkfyxD9Q/6+9NPRQHZyl8fvZVMdRA==} + engines: {node: '>=18'} + peerDependencies: + '@types/react': '>=16.8' + '@types/react-dom': '>=16.8' + react: '>=16.8' + react-dom: '>=16.8' + + '@tanstack/react-router-devtools@1.167.2': + resolution: {integrity: sha512-VuoqB7OhDUrBa4WOFSKiAQ8xI8sJpeZdo9sYE1hQa89iMuVFUQu1iWE4iCiQhB+6TYOZDZ9e+iHKxYjop4ZVYw==} + engines: {node: '>=20.19'} + peerDependencies: + '@tanstack/react-router': ^1.170.36 + '@tanstack/router-core': ^1.171.30 + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + peerDependenciesMeta: + '@tanstack/router-core': + optional: true + + '@tanstack/react-router@1.170.45': + resolution: {integrity: sha512-6tuiIAFb82zsk/YxveJRyGjbsm6kIfgUuoH7qCp2R2aSHveW6W0t/6j+Sn4m1iIlA2lLU4cvooqks08/YMOThw==} + engines: {node: '>=20.19'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-store@0.11.2': + resolution: {integrity: sha512-oj5O5DmiMWE+ih+SioX2ayC1kbK7d3fpLx0B75fPJr9nY3zU+hoW010yr64qXsY/9fyiLVE2bn5mGNV3owm8RQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/router-core@1.171.38': + resolution: {integrity: sha512-XRZVxiO6BIexICmEo3XfPmpoyyLhbjgaMJsONz4gIf5oYys0UiaG1BJGRyj9x8QZPDZcBhvAMuTYN70wSxV0gA==} + engines: {node: '>=20.19'} + + '@tanstack/router-devtools-core@1.168.2': + resolution: {integrity: sha512-pCCdQ5M/NUeWdiAbPmjyfcNdls6G4vaVlIQbPf1IqZk1FLYFr00aQvi578yUuWFBNM2KNS2QcwM1uPucbtGf5Q==} + engines: {node: '>=20.19'} + peerDependencies: + '@tanstack/router-core': ^1.171.30 + csstype: ^3.0.10 + peerDependenciesMeta: + csstype: + optional: true + + '@tanstack/router-generator@1.167.45': + resolution: {integrity: sha512-oCtNqtsMNcBJkPIOu1O7a68jnxt4TkVJj3jHrW3VgiZdBeaj/lBJQh50yvzmNRswRcyIkRg0g30g25bbLRrAGw==} + engines: {node: '>=20.19'} + + '@tanstack/router-plugin@1.168.47': + resolution: {integrity: sha512-1qvMto2Id0Uulux4qd+WttCbOFloIEQ5x82m68T4knt6NmUDQC66P/u/5yzN0FWGSO0u2U2nbDSIQoR6g7HNmQ==} + engines: {node: '>=20.19'} + peerDependencies: + '@rsbuild/core': '>=1.0.2 || ^2.0.0' + '@tanstack/react-router': ^1.170.45 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' + vite-plugin-solid: ^2.11.10 || ^3.0.0-0 + webpack: '>=5.92.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@tanstack/react-router': + optional: true + vite: + optional: true + vite-plugin-solid: + optional: true + webpack: + optional: true + + '@tanstack/router-utils@1.162.4': + resolution: {integrity: sha512-3TSH3rwAQTqQOtTBF8IXMFXmGNJWnjwIm+l87uguyC/of0pSRKcU9GJrozaf0fY9it8dLQvUZJA2MOlfqbW1sA==} + engines: {node: '>=20.19'} + + '@tanstack/store@0.11.2': + resolution: {integrity: sha512-sJ4mjol8uQsHV0gOJzzjwXfh2Fwm+Sz0+8deqiTm4jGbMdjzNSW+xZCFm0kUa870uhd8yi+DpKnZb5Kc4apa0Q==} + + '@tanstack/virtual-file-routes@1.162.0': + resolution: {integrity: sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==} + engines: {node: '>=20.19'} + + '@testing-library/dom@10.4.2': + resolution: {integrity: sha512-yzr2S9HyAIdhz2/6qHgbs665Q7PKVcDF05vsOlHPxG1mo36gKVesdYVeDLnXgfjJ03CrKRk08knc6+E/9m8v2Q==} + engines: {node: '>=18'} + + '@testing-library/react@16.3.3': + resolution: {integrity: sha512-Uo193NgQbPMz6lrrhtRQQFcMC6Re/ELLFbbuVL30WDlZxlpZf9/lMHTAVxPRLw1q1iu9OJmR1c2BLiENRstdBg==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@tybys/wasm-util@0.10.4': + resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@22.20.5': + resolution: {integrity: sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==} + + '@types/react-dom@19.3.0': + resolution: {integrity: sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==} + peerDependencies: + '@types/react': ^19.3.0 + + '@types/react@19.3.0': + resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==} + + '@typescript-eslint/eslint-plugin@8.71.2': + resolution: {integrity: sha512-K72/pvT7qpm8q3k8G5u93NCSN1RcLxX5h7Gw0bQpbMXviBHeY6Nx1WEwmk9wP+eKTSQ8ecxvcgt/ZX/rB938xQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.71.2 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.71.2': + resolution: {integrity: sha512-aTtmZjp/x3gsGHkDs04/1I8kNogBJkpQaeGaN0PfiG43NzDEmW2n+OP5im9wfsvyX0yP1UZWBrAGtDBfH9jEVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.71.2': + resolution: {integrity: sha512-Pd68GsLVh5ZXlcEccFPdhSOvtHZ/2WU0XsA8zmXOS3F158lVlcTLhfQ6qvtL1RzbMie0Kp8xtbVwAg4nejKPHw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.71.2': + resolution: {integrity: sha512-YF4wgg5iUX5Obywoac27B56FhozMNFhdJSbh11H5GBAwmBtfyRhmgTQqW9tRNNmHDvsZ2CX6UGzoz+YfYn2Leg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.71.2': + resolution: {integrity: sha512-jz49TAWokm/7yWD9/o837nYax9DyALxIPOImdImvVzo6canBCZYzin8zJyqNR5k1j9K1DE0bVvr0XYB+99uAdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.71.2': + resolution: {integrity: sha512-cC8UaalCViJkb3rH/xLIvidEwoFRtMZMUqDjjJMGEKaTFwYRHYBcoczlEGHuvkHEO8svRDrgZ0yQgOArFmwang==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.71.2': + resolution: {integrity: sha512-y5Ukl3oVp7e/VGxqIoEXoeb/Roj71PAJ4WG/N/RGj+eeDvKRLM15kGr9MijLbN0i03S52zxu31Z98E5gWChJKw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.71.2': + resolution: {integrity: sha512-DgNOEsl4pdYzwSL+N/Cl33tX1Hlw3FvId73LnKXfq7jnrF2viOEn7X+P7RBkkSWCVm92gnWd28GIC5vJuLREeA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.71.2': + resolution: {integrity: sha512-RyKa1G1M9rKHDhrk+HJtiF1MvLD5Ux2JW3TSkzw+02pRALdpJb+QzG1Y5em+LvCgzGwgg8H7mBRFKljNz7ImPw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.71.2': + resolution: {integrity: sha512-zozlN0UA32bSG2zkKAgQyRYSbEISVoyU6vvkKYo2aSny74D8Jh4e+POkJ6Lk0dlezZi5x7TtD+88Xb06IB8nhg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.12.2': + resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.12.2': + resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} + cpu: [loong64] + os: [linux] + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} + cpu: [loong64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} + cpu: [arm64] + os: [openharmony] + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==} + cpu: [x64] + os: [win32] + + '@vitejs/plugin-react@5.2.0': + resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@vitest/mocker@5.0.5': + resolution: {integrity: sha512-xLL3lkDegJZw+MGoGaCCsFayDZthGgpAtr3Vziyfc4p7xH89K7KRPcRBBh/kEYm0Aqkt5DtTmkYpBtRV/FrHZg==} + peerDependencies: + msw: ^2.4.9 || ^3.0.0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/spy@5.0.5': + resolution: {integrity: sha512-lwJRExuH417257Q5wv9QYugN9IMJkoxcrKrYxGPQkBzl7wlNpTUxD/5yNX4ESKVUIShKPgkGchYPFMWOOk0wzw==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansis@4.4.0: + resolution: {integrity: sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==} + engines: {node: '>=14'} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + babel-dead-code-elimination@1.0.12: + resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.11.29: + resolution: {integrity: sha512-YeesxhUmR4h5y5V8KF8iBCqJb8YFrBJ++XBTeGcWIaQOYXGN19JM0FoiOjAhwuDoln8owMgXcWBmgHtYSkky2w==} + engines: {node: '>=6.0.0'} + hasBin: true + + better-auth@1.7.7: + resolution: {integrity: sha512-Zhgxi/c5ylmfB/sX+nwnBbsFf/j6k0L8DvL6CJXZSrXgxc5pPMC/e7j812zNd4L4B4ELmdURCPw3X8nAOUdcjw==} + peerDependencies: + '@lynx-js/react': '*' + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 + '@sveltejs/kit': ^2.0.0 + '@tanstack/react-start': ^1.0.0 + '@tanstack/solid-start': ^1.0.0 + drizzle-kit: '>=0.31.4 || >=1.0.0-beta.1' + drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0 + mongodb: ^6.0.0 || ^7.0.0 + mysql2: ^3.0.0 + next: ^14.0.0 || ^15.0.0 || ^16.0.0 + pg: ^8.0.0 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + solid-js: ^1.0.0 + svelte: ^4.0.0 || ^5.0.0 + vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + vue: ^3.0.0 + peerDependenciesMeta: + '@lynx-js/react': + optional: true + '@prisma/client': + optional: true + '@sveltejs/kit': + optional: true + '@tanstack/react-start': + optional: true + '@tanstack/solid-start': + optional: true + drizzle-kit: + optional: true + drizzle-orm: + optional: true + mongodb: + optional: true + mysql2: + optional: true + next: + optional: true + pg: + optional: true + prisma: + optional: true + react: + optional: true + react-dom: + optional: true + solid-js: + optional: true + svelte: + optional: true + vitest: + optional: true + vue: + optional: true + + better-call@1.4.0: + resolution: {integrity: sha512-bBKOT4vv1kZLDgxVePdilk/Jwkn+dtRRsmi3DzHcDP+WnswyVl6dR59l2HEeP/0cB+bDoopASAesWDPIdd/zZA==} + peerDependencies: + zod: ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + + bidi-js@1.1.0: + resolution: {integrity: sha512-fX1Onk0tdVPC7obPWB5EbJ1z7NVhLq4m2xZLq2YXBkxzMXIGRpNMU88n0EPgWseKl12J7zXs7qrDxPK4sRs2fg==} + + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} + engines: {node: 20 || >=22} + + browserslist@4.29.3: + resolution: {integrity: sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + cacheable@2.5.0: + resolution: {integrity: sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==} + + caniuse-lite@1.0.30001816: + resolution: {integrity: sha512-+8Yx7BXCoqk6IF8yTicjfUR6D/ldJzdlsodlEOiOSPmhK844WIgk67/zIQaGAOxNkZyyvBlrRFnLvqKIoqbAFw==} + + chai@6.3.0: + resolution: {integrity: sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==} + engines: {node: '>=18'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + comment-parser@1.4.9: + resolution: {integrity: sha512-+2AvZKjJaNq9GQljm3tr0utwrig5BL+jgJGvz5rDpGKNIp+ojcRXWUwBbh/sGIi1QCprR6PsKFakub+w1v+4hQ==} + engines: {node: '>= 12.0.0'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssstyle@6.2.0: + resolution: {integrity: sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==} + engines: {node: '>=20'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + data-urls@7.0.0: + resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + dayjs@1.11.23: + resolution: {integrity: sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + diff@9.0.0: + resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==} + engines: {node: '>=0.3.1'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + electron-to-chromium@1.5.458: + resolution: {integrity: sha512-/hIH2gRSmxrf4/X4Nw/t/Wc8PVS22l8/3HnWjWTWsTOM5dsnMUPZF/+u+yr3LqweNuTBJE1rq6qAQzKkZVwMfA==} + + enhanced-resolve@5.26.0: + resolution: {integrity: sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==} + engines: {node: '>=10.13.0'} + + entities@8.1.0: + resolution: {integrity: sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==} + engines: {node: '>=20.19.0'} + + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} + + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-compat-utils@0.5.1: + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-import-context@0.1.9: + resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + + eslint-plugin-es-x@7.8.0: + resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-import-x@4.17.1: + resolution: {integrity: sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/utils': ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + eslint-import-resolver-node: '*' + peerDependenciesMeta: + '@typescript-eslint/utils': + optional: true + eslint-import-resolver-node: + optional: true + + eslint-plugin-n@17.24.0: + resolution: {integrity: sha512-/gC7/KAYmfNnPNOb3eu8vw+TdVnV0zhdQwexsw6FLXbhzroVj20vRn2qL8lDWDGnAQ2J8DhdfvXxX9EoxvERvw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.23.0' + + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@10.13.0: + resolution: {integrity: sha512-UohDjD4zSzEwhf58M3O7vc/ycc8O1I7dNlhtD0WxE8Px8EHNJKtUwzBqrzeGhisRuv2ag4sAYswszCJRgKXYUg==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} + engines: {node: '>=12.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@11.1.5: + resolution: {integrity: sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@6.1.23: + resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} + + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-tsconfig@4.14.3: + resolution: {integrity: sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + + globals@17.13.0: + resolution: {integrity: sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==} + engines: {node: '>=18'} + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + goober@2.1.19: + resolution: {integrity: sha512-U7veizMqxyKlM58+Z5j2ngJBH/r9siDmxpvNxSw0PylF6WQvrASJEZrxh1hidRBJc2jqoBVSyOban5u8m+6Rxg==} + peerDependencies: + csstype: ^3.0.10 + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + hashery@1.5.1: + resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==} + engines: {node: '>=20'} + + hookified@1.15.1: + resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} + + hookified@2.2.0: + resolution: {integrity: sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==} + + html-encoding-sniffer@6.0.0: + resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.12: + resolution: {integrity: sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg==} + engines: {node: '>= 4'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + isbot@5.2.2: + resolution: {integrity: sha512-iQcBXcd+Rv/pkubRyGh2utW2j1oPG5hZY6TUhVPpqK4G+o3IbxpJNx04hgksjc/N7GK5pEorUxDeg31cFgEk/w==} + engines: {node: '>=18'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + jose@6.2.12: + resolution: {integrity: sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsdom@28.1.0: + resolution: {integrity: sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + keyv@5.6.0: + resolution: {integrity: sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==} + + kysely@0.29.6: + resolution: {integrity: sha512-hHaB8C/rfzDDtr/t8YZwxAuPJTT0zHyaPoVzcXwDYhYNAgH/4sIfVhi/XLLIY+bL/FqaIJnjATDbi8ObSELmxg==} + engines: {node: '>=22.0.0'} + + launch-editor@2.14.2: + resolution: {integrity: sha512-NHJEb30MGBCkmZXLZwz25t37QR4aY03ZzPYUJXOJaOa92uWwExI9SBQUuIznBYc1xkD7cJNGX7oc3Nl3sq2kQQ==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lru-cache@11.5.3: + resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lucide-react@0.545.0: + resolution: {integrity: sha512-7r1/yUuflQDSt4f1bpn5ZAocyIxcTyVyBBChSVtBKn5M+392cPmI5YJMWOJKk/HUWGm5wg83chlAZtCcGbEZtw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magic-string@1.4.3: + resolution: {integrity: sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanostores@1.5.5: + resolution: {integrity: sha512-FixtE239Gl6Gz0ZGCK0WzvNwObNCIwVT+L7zQcf1QgcA6AzBxblzqe9OT88qiucNkhsjSOqiogSaF5jVbJiqSA==} + engines: {node: ^20.0.0 || >=22.0.0} + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-releases@2.0.59: + resolution: {integrity: sha512-5qr2okC4ItAI0hG5SaV0HoYMpnM/Y6+Oqr7AmPYy/2uEoGvS+GbSKLeRxSS1uAdu59yz0ouzcuXievSgg///WA==} + engines: {node: '>=18'} + + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} + engines: {node: '>=12.20.0'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + oxc-parser@0.120.0: + resolution: {integrity: sha512-WyPWZlcIm+Fkte63FGfgFB8mAAk33aH9h5N9lphXVOHSXEBFFsmYdOBedVKly363aWABjZdaj/m9lBfEY4wt+w==} + engines: {node: ^20.19.0 || >=22.12.0} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parse5@8.0.1: + resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + + postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + + postcss@8.5.30: + resolution: {integrity: sha512-zkd+e9S1AQHhmaBKye9zlFHWjOwVgqXl1q3ECYy8561K7qxR2cREf/STLskulBFd78k6AOFeA+ff1TtEzk9bAA==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.9.10: + resolution: {integrity: sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qified@0.10.1: + resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==} + engines: {node: '>=20'} + + react-dom@19.3.1: + resolution: {integrity: sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==} + peerDependencies: + react: ^19.3.1 + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + + react@19.3.1: + resolution: {integrity: sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==} + engines: {node: '>=0.10.0'} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + rollup@4.64.7: + resolution: {integrity: sha512-aCiJONoZp0lNGJ6sYqspLkh6UXaWEey/7Ko2TZyXQ4kgzAhDUxAgbt/oulXKmD+zFHXw1k+RF6ZZWOrjp7DZnQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rou3@0.9.2: + resolution: {integrity: sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.28.0: + resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + seroval-plugins@1.6.9: + resolution: {integrity: sha512-kiDK/Tb8IWZ61WEU8pA2PDmAuw37gKph9Y77OZlD56mg0Y2g0Bg7gZ1HeHhs5d40w+nRoUq/wj08V26ilbez9g==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.6.9: + resolution: {integrity: sha512-UeEzHwAK+yl0YLbsvROV1t5yMYEwZZ0CfKYxDvUgS2fO9Vxdf8djqVIB+OuVpuawRNPqw68LE1Du/GMsW2ZPqA==} + engines: {node: '>=10'} + + set-cookie-parser@3.1.4: + resolution: {integrity: sha512-iEmdEew+Tn1BwMGMP8LzGBEPC7Mf1sySjglCeEPb/Vchm9bnGezePvacYcId+fGprQzIng+TBkzqfJ/qS7AsBg==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.12.0: + resolution: {integrity: sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q==} + engines: {node: '>= 0.4'} + + solid-js@1.9.17: + resolution: {integrity: sha512-4GAmLOWPfNV8H9Jfn2LSFTpNEG6jiOKPiwd5lnLGQtehHaX6l3TOLzJqQ7mqwB/3k1Yy3zyumFVopmc/tm34ow==} + + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} + engines: {node: '>=0.10.0'} + + stable-hash-x@0.2.0: + resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + engines: {node: '>=12.0.0'} + + std-env@4.3.0: + resolution: {integrity: sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tailwindcss@4.3.3: + resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + tinybench@6.2.2: + resolution: {integrity: sha512-nIZ2N2dFpjBsg2hgitKu7mA+FvsIJuGJOwysRngmVRRmWgR/UyPjwJj8c/fT/dhm8EkHnF5EOogRf+0Z2qrimA==} + engines: {node: '>=20.0.0'} + + tinyexec@1.3.1: + resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tldts-core@7.4.18: + resolution: {integrity: sha512-KI2PKvCmvQI/xD6ypPqkU0i7oxNXR/O58RLRaHR4svsgVUQ2JE/XC8BtMbG6PSehD27I8sZJRcC1ASnCy6lp3g==} + + tldts@7.4.18: + resolution: {integrity: sha512-somxA8xKAUzlAxl0TX/jMSYIbRNFIVGnI96pVGJPeMc5BsHmfVXn6mOJT6U++ELnl04eGfzpfcEuZe8WiASkXg==} + hasBin: true + + tough-cookie@6.0.2: + resolution: {integrity: sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==} + engines: {node: '>=16'} + + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-declaration-location@1.0.7: + resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} + peerDependencies: + typescript: '>=4.0.0' + + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + deprecated: unmaintained + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.71.2: + resolution: {integrity: sha512-Rz4effbMy2g9wnvOJZG6SbVavX313Lap1vNEbk1RUochzickvzP8P4HB+bkNg5e50eVz1hQGjh9K1omI1xB4Bw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici@7.30.1: + resolution: {integrity: sha512-03KrMbjIFDWQR5RNPrSw3bd1r12JpyFQl9/yxjUbJtqkjmllqC5lFjZh6ujeuJCKr8EOQvRW872Oy/az+nLYxg==} + engines: {node: '>=20.18.1'} + + unplugin@3.4.0: + resolution: {integrity: sha512-9skdIFlCsPdFV7wUfZxNsFInlW+7nJmGu2gkTu0OUhF56aXGsHab9x52/QhdJ4lC7ZDPWTxbiC4ANqVlsuaW3w==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@farmfe/core': '*' + '@rsbuild/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rsbuild/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true + + unrs-resolver@1.12.2: + resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} + + update-browserslist-db@1.3.4: + resolution: {integrity: sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-sync-external-store@1.7.0: + resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vite-tsconfig-paths@5.1.4: + resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + vite@7.3.7: + resolution: {integrity: sha512-AHEzTORMbi7/7aXp7w7KZ5+DCUdSeLsJz0grY8xHpc9DHdYb0vQu6DqJfm2tOw3gDExNgPgnJTXxM6syYFHaCA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@5.0.5: + resolution: {integrity: sha512-cPODOMF8YnkiiYtDdHo6n4wWmBrOBBbOIYH2d33M4l3CdNn72h+qMmO6uXffUN6A5AZFXNND/d+krS9mgkXRfg==} + engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 5.0.5 + '@vitest/browser-preview': 5.0.5 + '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0 + '@vitest/coverage-istanbul': 5.0.5 + '@vitest/coverage-v8': 5.0.5 + '@vitest/ui': 5.0.5 + happy-dom: '*' + jsdom: '*' + vite: ^6.4.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vue-eslint-parser@10.4.1: + resolution: {integrity: sha512-Gk6gRDj0n/fkRa3C3l0bBheoBckUq/Rs0F/TvMWIS6nzzx67amAViMe9CkNgsP2tXyQONvGiHQESHwFtZ3aYDA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + webidl-conversions@8.0.1: + resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} + engines: {node: '>=20'} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-mimetype@5.0.0: + resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} + engines: {node: '>=20'} + + whatwg-url@16.0.1: + resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@3.2.1: + resolution: {integrity: sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==} + engines: {node: '>=20.11'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + ws@8.22.0: + resolution: {integrity: sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod@4.6.7: + resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==} + +snapshots: + + '@acemir/cssom@0.9.32': {} + + '@asamuzakjp/css-color@5.1.11': + dependencies: + '@asamuzakjp/generational-cache': 1.0.1 + '@csstools/css-calc': 3.4.3(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2) + '@csstools/css-color-parser': 4.2.6(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2) + '@csstools/css-parser-algorithms': 4.0.2(@csstools/css-tokenizer@4.0.2) + '@csstools/css-tokenizer': 4.0.2 + + '@asamuzakjp/dom-selector@6.8.1': + dependencies: + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.1.0 + css-tree: 3.2.1 + is-potential-custom-element-name: 1.0.1 + lru-cache: 11.5.3 + + '@asamuzakjp/generational-cache@1.0.1': {} + + '@asamuzakjp/nwsapi@2.3.9': {} + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.7': {} + + '@babel/core@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helpers': 7.29.10 + '@babel/parser': 7.29.9 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.10 + '@babel/types': 7.29.8 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.8': + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.29.7': + dependencies: + '@babel/compat-data': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + browserslist: 4.29.3 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.29.7': {} + + '@babel/helper-module-imports@7.29.7': + dependencies: + '@babel/traverse': 7.29.10 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.10 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.29.7': {} + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-option@7.29.7': {} + + '@babel/helpers@7.29.10': + dependencies: + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + + '@babel/parser@7.29.9': + dependencies: + '@babel/types': 7.29.8 + + '@babel/plugin-transform-react-jsx-self@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + + '@babel/plugin-transform-react-jsx-source@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + + '@babel/runtime@7.29.10': {} + + '@babel/template@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + + '@babel/traverse@7.29.10': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.9 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5)': + dependencies: + '@better-auth/utils': 0.4.2 + '@better-fetch/fetch': 1.3.2 + '@opentelemetry/semantic-conventions': 1.43.0 + '@standard-schema/spec': 1.1.0 + better-call: 1.4.0(zod@4.6.7) + jose: 6.2.12 + kysely: 0.29.6 + nanostores: 1.5.5 + zod: 4.6.7 + + '@better-auth/drizzle-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)': + dependencies: + '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5) + '@better-auth/utils': 0.4.2 + + '@better-auth/kysely-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(kysely@0.29.6)': + dependencies: + '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5) + '@better-auth/utils': 0.4.2 + optionalDependencies: + kysely: 0.29.6 + + '@better-auth/memory-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)': + dependencies: + '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5) + '@better-auth/utils': 0.4.2 + + '@better-auth/mongo-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)': + dependencies: + '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5) + '@better-auth/utils': 0.4.2 + + '@better-auth/prisma-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)': + dependencies: + '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5) + '@better-auth/utils': 0.4.2 + + '@better-auth/telemetry@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)': + dependencies: + '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5) + '@better-auth/utils': 0.4.2 + '@better-fetch/fetch': 1.3.2 + + '@better-auth/utils@0.4.2': + dependencies: + '@noble/hashes': 2.4.0 + + '@better-auth/utils@0.5.0': + dependencies: + '@noble/hashes': 2.4.0 + + '@better-fetch/fetch@1.3.2': {} + + '@bramus/specificity@2.4.3': + dependencies: + css-tree: 3.2.1 + + '@cacheable/memory@2.2.0': + dependencies: + '@cacheable/utils': 2.5.0 + '@keyv/bigmap': 1.3.1(keyv@5.6.0) + hookified: 1.15.1 + keyv: 5.6.0 + + '@cacheable/utils@2.5.0': + dependencies: + hashery: 1.5.1 + keyv: 5.6.0 + + '@csstools/color-helpers@6.1.2': {} + + '@csstools/css-calc@3.4.3(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.2(@csstools/css-tokenizer@4.0.2) + '@csstools/css-tokenizer': 4.0.2 + + '@csstools/css-color-parser@4.2.6(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2)': + dependencies: + '@csstools/color-helpers': 6.1.2 + '@csstools/css-calc': 3.4.3(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2) + '@csstools/css-parser-algorithms': 4.0.2(@csstools/css-tokenizer@4.0.2) + '@csstools/css-tokenizer': 4.0.2 + + '@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2)': + dependencies: + '@csstools/css-tokenizer': 4.0.2 + + '@csstools/css-syntax-patches-for-csstree@1.1.15(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 + + '@csstools/css-tokenizer@4.0.2': {} + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.28.2': + optional: true + + '@eslint-community/eslint-utils@4.10.1(eslint@10.13.0(jiti@2.7.0))': + dependencies: + eslint: 10.13.0(jiti@2.7.0) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.23.5': + dependencies: + '@eslint/object-schema': 3.0.5 + debug: 4.4.3 + minimatch: 10.2.6 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.7.0': + dependencies: + '@eslint/core': 1.2.1 + + '@eslint/core@1.2.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/js@10.0.1(eslint@10.13.0(jiti@2.7.0))': + optionalDependencies: + eslint: 10.13.0(jiti@2.7.0) + + '@eslint/object-schema@3.0.5': {} + + '@eslint/plugin-kit@0.7.3': + dependencies: + '@eslint/core': 1.2.1 + levn: 0.4.1 + + '@exodus/bytes@1.16.0(@noble/hashes@2.4.0)': + optionalDependencies: + '@noble/hashes': 2.4.0 + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@keyv/bigmap@1.3.1(keyv@5.6.0)': + dependencies: + hashery: 1.5.1 + hookified: 1.15.1 + keyv: 5.6.0 + + '@keyv/serialize@1.1.1': {} + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + optional: true + + '@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.4 + optional: true + + '@neodrag/core@3.0.0-next.11': {} + + '@neodrag/solid@3.0.0-next.11(@neodrag/core@3.0.0-next.11)(solid-js@1.9.17)': + dependencies: + '@neodrag/core': 3.0.0-next.11 + solid-js: 1.9.17 + + '@noble/ciphers@2.4.0': {} + + '@noble/hashes@2.4.0': {} + + '@opentelemetry/semantic-conventions@1.43.0': {} + + '@oxc-parser/binding-android-arm-eabi@0.120.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.120.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.120.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.120.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.120.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.120.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.120.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.120.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.120.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.120.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.120.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.120.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.120.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.120.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.120.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.120.0': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.120.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.120.0': + optional: true + + '@oxc-parser/binding-win32-ia32-msvc@0.120.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.120.0': + optional: true + + '@oxc-project/types@0.120.0': {} + + '@rolldown/pluginutils@1.0.0-rc.3': {} + + '@rollup/rollup-android-arm-eabi@4.64.7': + optional: true + + '@rollup/rollup-android-arm64@4.64.7': + optional: true + + '@rollup/rollup-darwin-arm64@4.64.7': + optional: true + + '@rollup/rollup-darwin-x64@4.64.7': + optional: true + + '@rollup/rollup-freebsd-arm64@4.64.7': + optional: true + + '@rollup/rollup-freebsd-x64@4.64.7': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.64.7': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.64.7': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.64.7': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.64.7': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.64.7': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.64.7': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.64.7': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.64.7': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.64.7': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.64.7': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.64.7': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.64.7': + optional: true + + '@rollup/rollup-linux-x64-musl@4.64.7': + optional: true + + '@rollup/rollup-openbsd-x64@4.64.7': + optional: true + + '@rollup/rollup-openharmony-arm64@4.64.7': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.64.7': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.64.7': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.64.7': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.64.7': + optional: true + + '@solid-primitives/event-listener@2.4.6(solid-js@1.9.17)': + dependencies: + '@solid-primitives/utils': 6.4.1(solid-js@1.9.17) + solid-js: 1.9.17 + + '@solid-primitives/keyboard@1.3.7(solid-js@1.9.17)': + dependencies: + '@solid-primitives/event-listener': 2.4.6(solid-js@1.9.17) + '@solid-primitives/rootless': 1.5.4(solid-js@1.9.17) + '@solid-primitives/utils': 6.4.1(solid-js@1.9.17) + solid-js: 1.9.17 + + '@solid-primitives/resize-observer@2.2.0(solid-js@1.9.17)': + dependencies: + '@solid-primitives/event-listener': 2.4.6(solid-js@1.9.17) + '@solid-primitives/rootless': 1.5.4(solid-js@1.9.17) + '@solid-primitives/static-store': 0.1.4(solid-js@1.9.17) + '@solid-primitives/utils': 6.4.1(solid-js@1.9.17) + solid-js: 1.9.17 + + '@solid-primitives/rootless@1.5.4(solid-js@1.9.17)': + dependencies: + '@solid-primitives/utils': 6.4.1(solid-js@1.9.17) + solid-js: 1.9.17 + + '@solid-primitives/static-store@0.1.4(solid-js@1.9.17)': + dependencies: + '@solid-primitives/utils': 6.4.1(solid-js@1.9.17) + solid-js: 1.9.17 + + '@solid-primitives/utils@6.4.1(solid-js@1.9.17)': + dependencies: + solid-js: 1.9.17 + + '@standard-schema/spec@1.1.0': {} + + '@stylistic/eslint-plugin@5.10.0(eslint@10.13.0(jiti@2.7.0))': + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)) + '@typescript-eslint/types': 8.71.2 + eslint: 10.13.0(jiti@2.7.0) + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + estraverse: 5.3.0 + picomatch: 4.0.7 + + '@tailwindcss/node@4.3.3': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.26.0 + jiti: 2.7.0 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.2 + tailwindcss: 4.3.3 + + '@tailwindcss/oxide-android-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide@4.3.3': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-x64': 4.3.3 + '@tailwindcss/oxide-freebsd-x64': 4.3.3 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-x64-musl': 4.3.3 + '@tailwindcss/oxide-wasm32-wasi': 4.3.3 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 + + '@tailwindcss/typography@0.5.20(tailwindcss@4.3.3)': + dependencies: + postcss-selector-parser: 6.0.10 + tailwindcss: 4.3.3 + + '@tailwindcss/vite@4.3.3(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0))': + dependencies: + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + tailwindcss: 4.3.3 + vite: 7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0) + + '@tanstack/devtools-bundler-core@0.1.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@tanstack/devtools-client': 0.0.8 + '@tanstack/devtools-event-bus': 0.4.3 + chalk: 5.6.2 + launch-editor: 2.14.2 + magic-string: 0.30.21 + oxc-parser: 0.120.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + picomatch: 4.0.7 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + - bufferutil + - utf-8-validate + + '@tanstack/devtools-client@0.0.8': + dependencies: + '@tanstack/devtools-event-client': 0.5.0 + + '@tanstack/devtools-event-bus@0.4.3': + dependencies: + ws: 8.22.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@tanstack/devtools-event-client@0.5.0': {} + + '@tanstack/devtools-ui@0.7.1(csstype@3.2.3)(solid-js@1.9.17)': + dependencies: + clsx: 2.1.1 + dayjs: 1.11.23 + goober: 2.1.19(csstype@3.2.3) + solid-js: 1.9.17 + transitivePeerDependencies: + - csstype + + '@tanstack/devtools-vite@0.8.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0))': + dependencies: + '@tanstack/devtools-bundler-core': 0.1.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@tanstack/devtools-client': 0.0.8 + '@tanstack/devtools-event-bus': 0.4.3 + chalk: 5.6.2 + vite: 7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + - bufferutil + - utf-8-validate + + '@tanstack/devtools@0.15.0(csstype@3.2.3)(solid-js@1.9.17)': + dependencies: + '@neodrag/core': 3.0.0-next.11 + '@neodrag/solid': 3.0.0-next.11(@neodrag/core@3.0.0-next.11)(solid-js@1.9.17) + '@solid-primitives/event-listener': 2.4.6(solid-js@1.9.17) + '@solid-primitives/keyboard': 1.3.7(solid-js@1.9.17) + '@solid-primitives/resize-observer': 2.2.0(solid-js@1.9.17) + '@tanstack/devtools-client': 0.0.8 + '@tanstack/devtools-event-bus': 0.4.3 + '@tanstack/devtools-ui': 0.7.1(csstype@3.2.3)(solid-js@1.9.17) + clsx: 2.1.1 + goober: 2.1.19(csstype@3.2.3) + solid-js: 1.9.17 + transitivePeerDependencies: + - bufferutil + - csstype + - utf-8-validate + + '@tanstack/eslint-config@0.4.0(@typescript-eslint/utils@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3))(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@eslint/js': 10.0.1(eslint@10.13.0(jiti@2.7.0)) + '@stylistic/eslint-plugin': 5.10.0(eslint@10.13.0(jiti@2.7.0)) + eslint: 10.13.0(jiti@2.7.0) + eslint-plugin-import-x: 4.17.1(@typescript-eslint/utils@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3))(eslint@10.13.0(jiti@2.7.0)) + eslint-plugin-n: 17.24.0(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + globals: 17.13.0 + typescript-eslint: 8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + vue-eslint-parser: 10.4.1(eslint@10.13.0(jiti@2.7.0)) + transitivePeerDependencies: + - '@typescript-eslint/utils' + - eslint-import-resolver-node + - supports-color + - typescript + + '@tanstack/history@1.162.5': {} + + '@tanstack/react-devtools@0.10.13(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(csstype@3.2.3)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(solid-js@1.9.17)': + dependencies: + '@tanstack/devtools': 0.15.0(csstype@3.2.3)(solid-js@1.9.17) + '@types/react': 19.3.0 + '@types/react-dom': 19.3.0(@types/react@19.3.0) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + transitivePeerDependencies: + - bufferutil + - csstype + - solid-js + - utf-8-validate + + '@tanstack/react-router-devtools@1.167.2(@tanstack/react-router@1.170.45(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(@tanstack/router-core@1.171.38)(csstype@3.2.3)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@tanstack/react-router': 1.170.45(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@tanstack/router-devtools-core': 1.168.2(@tanstack/router-core@1.171.38)(csstype@3.2.3) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + optionalDependencies: + '@tanstack/router-core': 1.171.38 + transitivePeerDependencies: + - csstype + + '@tanstack/react-router@1.170.45(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@tanstack/history': 1.162.5 + '@tanstack/react-store': 0.11.2(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@tanstack/router-core': 1.171.38 + isbot: 5.2.2 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@tanstack/react-store@0.11.2(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@tanstack/store': 0.11.2 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + use-sync-external-store: 1.7.0(react@19.3.1) + + '@tanstack/router-core@1.171.38': + dependencies: + '@tanstack/history': 1.162.5 + cookie-es: 3.1.1 + seroval: 1.6.9 + seroval-plugins: 1.6.9(seroval@1.6.9) + + '@tanstack/router-devtools-core@1.168.2(@tanstack/router-core@1.171.38)(csstype@3.2.3)': + dependencies: + '@tanstack/router-core': 1.171.38 + clsx: 2.1.1 + goober: 2.1.19(csstype@3.2.3) + optionalDependencies: + csstype: 3.2.3 + + '@tanstack/router-generator@1.167.45': + dependencies: + '@babel/types': 7.29.8 + '@tanstack/router-core': 1.171.38 + '@tanstack/router-utils': 1.162.4 + '@tanstack/virtual-file-routes': 1.162.0 + jiti: 2.7.0 + magic-string: 0.30.21 + prettier: 3.9.10 + zod: 4.6.7 + transitivePeerDependencies: + - supports-color + + '@tanstack/router-plugin@1.168.47(@tanstack/react-router@1.170.45(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(esbuild@0.28.2)(rollup@4.64.7)(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0))': + dependencies: + '@babel/core': 7.29.7 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + '@tanstack/router-core': 1.171.38 + '@tanstack/router-generator': 1.167.45 + '@tanstack/router-utils': 1.162.4 + chokidar: 5.0.0 + unplugin: 3.4.0(esbuild@0.28.2)(rollup@4.64.7)(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)) + zod: 4.6.7 + optionalDependencies: + '@tanstack/react-router': 1.170.45(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + vite: 7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - supports-color + - unloader + + '@tanstack/router-utils@1.162.4': + dependencies: + '@babel/generator': 7.29.8 + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + ansis: 4.4.0 + babel-dead-code-elimination: 1.0.12 + diff: 9.0.0 + pathe: 2.0.3 + tinyglobby: 0.2.17 + transitivePeerDependencies: + - supports-color + + '@tanstack/store@0.11.2': {} + + '@tanstack/virtual-file-routes@1.162.0': {} + + '@testing-library/dom@10.4.2': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/runtime': 7.29.10 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/react@16.3.3(@testing-library/dom@10.4.2)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@babel/runtime': 7.29.10 + '@testing-library/dom': 10.4.2 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + optionalDependencies: + '@types/react': 19.3.0 + '@types/react-dom': 19.3.0(@types/react@19.3.0) + + '@tybys/wasm-util@0.10.4': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/aria-query@5.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.8 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.8 + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/esrecurse@4.3.1': {} + + '@types/estree@1.0.9': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@22.20.5': + dependencies: + undici-types: 6.21.0 + + '@types/react-dom@19.3.0(@types/react@19.3.0)': + dependencies: + '@types/react': 19.3.0 + + '@types/react@19.3.0': + dependencies: + csstype: 3.2.3 + + '@typescript-eslint/eslint-plugin@8.71.2(@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3))(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.71.2 + '@typescript-eslint/type-utils': 8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/utils': 8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.71.2 + eslint: 10.13.0(jiti@2.7.0) + ignore: 7.0.12 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.71.2 + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/typescript-estree': 8.71.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.71.2 + debug: 4.4.3 + eslint: 10.13.0(jiti@2.7.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.71.2(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.71.2(typescript@5.9.3) + '@typescript-eslint/types': 8.71.2 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.71.2': + dependencies: + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/visitor-keys': 8.71.2 + + '@typescript-eslint/tsconfig-utils@8.71.2(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/typescript-estree': 8.71.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + debug: 4.4.3 + eslint: 10.13.0(jiti@2.7.0) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.71.2': {} + + '@typescript-eslint/typescript-estree@8.71.2(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.71.2(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.71.2(typescript@5.9.3) + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/visitor-keys': 8.71.2 + debug: 4.4.3 + minimatch: 10.2.6 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.71.2 + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/typescript-estree': 8.71.2(typescript@5.9.3) + eslint: 10.13.0(jiti@2.7.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.71.2': + dependencies: + '@typescript-eslint/types': 8.71.2 + eslint-visitor-keys: 5.0.1 + + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + optional: true + + '@unrs/resolver-binding-android-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + optional: true + + '@vitejs/plugin-react@5.2.0(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0))': + dependencies: + '@babel/core': 7.29.7 + '@babel/plugin-transform-react-jsx-self': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-react-jsx-source': 7.29.7(@babel/core@7.29.7) + '@rolldown/pluginutils': 1.0.0-rc.3 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0) + transitivePeerDependencies: + - supports-color + + '@vitest/mocker@5.0.5(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0))': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/spy': 5.0.5 + estree-walker: 3.0.3 + magic-string: 1.4.3 + optionalDependencies: + vite: 7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0) + + '@vitest/spy@5.0.5': {} + + acorn-jsx@5.3.2(acorn@8.19.0): + dependencies: + acorn: 8.19.0 + + acorn@8.19.0: {} + + agent-base@7.1.4: {} + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-styles@5.2.0: {} + + ansis@4.4.0: {} + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + assertion-error@2.0.1: {} + + babel-dead-code-elimination@1.0.12: + dependencies: + '@babel/core': 7.29.7 + '@babel/parser': 7.29.9 + '@babel/traverse': 7.29.10 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + balanced-match@4.0.4: {} + + baseline-browser-mapping@2.11.29: {} + + better-auth@1.7.7(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(solid-js@1.9.17)(vitest@5.0.5(@types/node@22.20.5)(jsdom@28.1.0(@noble/hashes@2.4.0))(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0))): + dependencies: + '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5) + '@better-auth/drizzle-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2) + '@better-auth/kysely-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(kysely@0.29.6) + '@better-auth/memory-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2) + '@better-auth/mongo-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2) + '@better-auth/prisma-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2) + '@better-auth/telemetry': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(better-call@1.4.0(zod@4.6.7))(jose@6.2.12)(kysely@0.29.6)(nanostores@1.5.5))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2) + '@better-auth/utils': 0.4.2 + '@better-fetch/fetch': 1.3.2 + '@noble/ciphers': 2.4.0 + '@noble/hashes': 2.4.0 + better-call: 1.4.0(zod@4.6.7) + defu: 6.1.7 + jose: 6.2.12 + kysely: 0.29.6 + nanostores: 1.5.5 + zod: 4.6.7 + optionalDependencies: + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + solid-js: 1.9.17 + vitest: 5.0.5(@types/node@22.20.5)(jsdom@28.1.0(@noble/hashes@2.4.0))(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)) + transitivePeerDependencies: + - '@opentelemetry/api' + + better-call@1.4.0(zod@4.6.7): + dependencies: + '@better-auth/utils': 0.5.0 + '@better-fetch/fetch': 1.3.2 + rou3: 0.9.2 + set-cookie-parser: 3.1.4 + optionalDependencies: + zod: 4.6.7 + + bidi-js@1.1.0: + dependencies: + require-from-string: 2.0.2 + + brace-expansion@5.0.12: + dependencies: + balanced-match: 4.0.4 + + browserslist@4.29.3: + dependencies: + baseline-browser-mapping: 2.11.29 + caniuse-lite: 1.0.30001816 + electron-to-chromium: 1.5.458 + node-releases: 2.0.59 + update-browserslist-db: 1.3.4(browserslist@4.29.3) + + cacheable@2.5.0: + dependencies: + '@cacheable/memory': 2.2.0 + '@cacheable/utils': 2.5.0 + hookified: 1.15.1 + keyv: 5.6.0 + qified: 0.10.1 + + caniuse-lite@1.0.30001816: {} + + chai@6.3.0: {} + + chalk@5.6.2: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + + clsx@2.1.1: {} + + comment-parser@1.4.9: {} + + convert-source-map@2.0.0: {} + + cookie-es@3.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.2 + + cssesc@3.0.0: {} + + cssstyle@6.2.0: + dependencies: + '@asamuzakjp/css-color': 5.1.11 + '@csstools/css-syntax-patches-for-csstree': 1.1.15(css-tree@3.2.1) + css-tree: 3.2.1 + lru-cache: 11.5.3 + + csstype@3.2.3: {} + + data-urls@7.0.0(@noble/hashes@2.4.0): + dependencies: + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1(@noble/hashes@2.4.0) + transitivePeerDependencies: + - '@noble/hashes' + + dayjs@1.11.23: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decimal.js@10.6.0: {} + + deep-is@0.1.4: {} + + defu@6.1.7: {} + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + diff@9.0.0: {} + + dom-accessibility-api@0.5.16: {} + + electron-to-chromium@1.5.458: {} + + enhanced-resolve@5.26.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + entities@8.1.0: {} + + es-module-lexer@2.3.2: {} + + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-compat-utils@0.5.1(eslint@10.13.0(jiti@2.7.0)): + dependencies: + eslint: 10.13.0(jiti@2.7.0) + semver: 7.8.5 + + eslint-import-context@0.1.9(unrs-resolver@1.12.2): + dependencies: + get-tsconfig: 4.14.3 + stable-hash-x: 0.2.0 + optionalDependencies: + unrs-resolver: 1.12.2 + + eslint-plugin-es-x@7.8.0(eslint@10.13.0(jiti@2.7.0)): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)) + '@eslint-community/regexpp': 4.12.2 + eslint: 10.13.0(jiti@2.7.0) + eslint-compat-utils: 0.5.1(eslint@10.13.0(jiti@2.7.0)) + + eslint-plugin-import-x@4.17.1(@typescript-eslint/utils@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3))(eslint@10.13.0(jiti@2.7.0)): + dependencies: + '@typescript-eslint/types': 8.71.2 + comment-parser: 1.4.9 + debug: 4.4.3 + eslint: 10.13.0(jiti@2.7.0) + eslint-import-context: 0.1.9(unrs-resolver@1.12.2) + is-glob: 4.0.3 + minimatch: 10.2.6 + semver: 7.8.5 + stable-hash-x: 0.2.0 + unrs-resolver: 1.12.2 + optionalDependencies: + '@typescript-eslint/utils': 8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + + eslint-plugin-n@17.24.0(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)) + enhanced-resolve: 5.26.0 + eslint: 10.13.0(jiti@2.7.0) + eslint-plugin-es-x: 7.8.0(eslint@10.13.0(jiti@2.7.0)) + get-tsconfig: 4.14.3 + globals: 15.15.0 + globrex: 0.1.2 + ignore: 5.3.2 + semver: 7.8.5 + ts-declaration-location: 1.0.7(typescript@5.9.3) + transitivePeerDependencies: + - typescript + + eslint-scope@9.1.2: + dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.9 + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@10.13.0(jiti@2.7.0): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5 + '@eslint/config-helpers': 0.7.0 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.3 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 11.1.5 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.6 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.7.0 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) + eslint-visitor-keys: 4.2.1 + + espree@11.2.0: + dependencies: + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) + eslint-visitor-keys: 5.0.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + esutils@2.0.3: {} + + expect-type@1.4.0: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fdir@6.5.0(picomatch@4.0.7): + optionalDependencies: + picomatch: 4.0.7 + + file-entry-cache@11.1.5: + dependencies: + flat-cache: 6.1.23 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@6.1.23: + dependencies: + cacheable: 2.5.0 + flatted: 3.4.4 + hookified: 1.15.1 + + flatted@3.4.4: {} + + fsevents@2.3.3: + optional: true + + gensync@1.0.0-beta.2: {} + + get-tsconfig@4.14.3: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@15.15.0: {} + + globals@17.13.0: {} + + globrex@0.1.2: {} + + goober@2.1.19(csstype@3.2.3): + dependencies: + csstype: 3.2.3 + + graceful-fs@4.2.11: {} + + hashery@1.5.1: + dependencies: + hookified: 1.15.1 + + hookified@1.15.1: {} + + hookified@2.2.0: {} + + html-encoding-sniffer@6.0.0(@noble/hashes@2.4.0): + dependencies: + '@exodus/bytes': 1.16.0(@noble/hashes@2.4.0) + transitivePeerDependencies: + - '@noble/hashes' + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + ignore@5.3.2: {} + + ignore@7.0.12: {} + + imurmurhash@0.1.4: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-potential-custom-element-name@1.0.1: {} + + isbot@5.2.2: {} + + isexe@2.0.0: {} + + jiti@2.7.0: {} + + jose@6.2.12: {} + + js-tokens@4.0.0: {} + + jsdom@28.1.0(@noble/hashes@2.4.0): + dependencies: + '@acemir/cssom': 0.9.32 + '@asamuzakjp/dom-selector': 6.8.1 + '@bramus/specificity': 2.4.3 + '@exodus/bytes': 1.16.0(@noble/hashes@2.4.0) + cssstyle: 6.2.0 + data-urls: 7.0.0(@noble/hashes@2.4.0) + decimal.js: 10.6.0 + html-encoding-sniffer: 6.0.0(@noble/hashes@2.4.0) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + parse5: 8.0.1 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 6.0.2 + undici: 7.30.1 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 8.0.1 + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1(@noble/hashes@2.4.0) + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - '@noble/hashes' + - supports-color + + jsesc@3.1.0: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + keyv@5.6.0: + dependencies: + '@keyv/serialize': 1.1.1 + + kysely@0.29.6: {} + + launch-editor@2.14.2: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.12.0 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lru-cache@11.5.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lucide-react@0.545.0(react@19.3.1): + dependencies: + react: 19.3.1 + + lz-string@1.5.0: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + magic-string@1.4.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + mdn-data@2.27.1: {} + + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.12 + + ms@2.1.3: {} + + nanoid@3.3.20: {} + + nanostores@1.5.5: {} + + napi-postinstall@0.3.4: {} + + natural-compare@1.4.0: {} + + node-releases@2.0.59: {} + + obug@3.0.0: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + oxc-parser@0.120.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): + dependencies: + '@oxc-project/types': 0.120.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.120.0 + '@oxc-parser/binding-android-arm64': 0.120.0 + '@oxc-parser/binding-darwin-arm64': 0.120.0 + '@oxc-parser/binding-darwin-x64': 0.120.0 + '@oxc-parser/binding-freebsd-x64': 0.120.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.120.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.120.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.120.0 + '@oxc-parser/binding-linux-arm64-musl': 0.120.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.120.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.120.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.120.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.120.0 + '@oxc-parser/binding-linux-x64-gnu': 0.120.0 + '@oxc-parser/binding-linux-x64-musl': 0.120.0 + '@oxc-parser/binding-openharmony-arm64': 0.120.0 + '@oxc-parser/binding-wasm32-wasi': 0.120.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@oxc-parser/binding-win32-arm64-msvc': 0.120.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.120.0 + '@oxc-parser/binding-win32-x64-msvc': 0.120.0 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parse5@8.0.1: + dependencies: + entities: 8.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.7: {} + + postcss-selector-parser@6.0.10: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.30: + dependencies: + nanoid: 3.3.20 + picocolors: 1.1.1 + source-map-js: 1.2.2 + + prelude-ls@1.2.1: {} + + prettier@3.9.10: {} + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + punycode@2.3.1: {} + + qified@0.10.1: + dependencies: + hookified: 2.2.0 + + react-dom@19.3.1(react@19.3.1): + dependencies: + react: 19.3.1 + scheduler: 0.28.0 + + react-is@17.0.2: {} + + react-refresh@0.18.0: {} + + react@19.3.1: {} + + readdirp@5.1.1: {} + + require-from-string@2.0.2: {} + + resolve-pkg-maps@1.0.0: {} + + rollup@4.64.7: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@napi-rs/lzma-linux-x64-gnu': 1.5.1 + '@rollup/rollup-android-arm-eabi': 4.64.7 + '@rollup/rollup-android-arm64': 4.64.7 + '@rollup/rollup-darwin-arm64': 4.64.7 + '@rollup/rollup-darwin-x64': 4.64.7 + '@rollup/rollup-freebsd-arm64': 4.64.7 + '@rollup/rollup-freebsd-x64': 4.64.7 + '@rollup/rollup-linux-arm-gnueabihf': 4.64.7 + '@rollup/rollup-linux-arm-musleabihf': 4.64.7 + '@rollup/rollup-linux-arm64-gnu': 4.64.7 + '@rollup/rollup-linux-arm64-musl': 4.64.7 + '@rollup/rollup-linux-loong64-gnu': 4.64.7 + '@rollup/rollup-linux-loong64-musl': 4.64.7 + '@rollup/rollup-linux-ppc64-gnu': 4.64.7 + '@rollup/rollup-linux-ppc64-musl': 4.64.7 + '@rollup/rollup-linux-riscv64-gnu': 4.64.7 + '@rollup/rollup-linux-riscv64-musl': 4.64.7 + '@rollup/rollup-linux-s390x-gnu': 4.64.7 + '@rollup/rollup-linux-x64-gnu': 4.64.7 + '@rollup/rollup-linux-x64-musl': 4.64.7 + '@rollup/rollup-openbsd-x64': 4.64.7 + '@rollup/rollup-openharmony-arm64': 4.64.7 + '@rollup/rollup-win32-arm64-msvc': 4.64.7 + '@rollup/rollup-win32-ia32-msvc': 4.64.7 + '@rollup/rollup-win32-x64-gnu': 4.64.7 + '@rollup/rollup-win32-x64-msvc': 4.64.7 + fsevents: 2.3.3 + + rou3@0.9.2: {} + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.28.0: {} + + semver@6.3.1: {} + + semver@7.8.5: {} + + seroval-plugins@1.6.9(seroval@1.6.9): + dependencies: + seroval: 1.6.9 + + seroval@1.6.9: {} + + set-cookie-parser@3.1.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.12.0: {} + + solid-js@1.9.17: + dependencies: + csstype: 3.2.3 + seroval: 1.6.9 + seroval-plugins: 1.6.9(seroval@1.6.9) + + source-map-js@1.2.2: {} + + stable-hash-x@0.2.0: {} + + std-env@4.3.0: {} + + symbol-tree@3.2.4: {} + + tailwindcss@4.3.3: {} + + tapable@2.3.3: {} + + tinybench@6.2.2: {} + + tinyexec@1.3.1: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + + tldts-core@7.4.18: {} + + tldts@7.4.18: + dependencies: + tldts-core: 7.4.18 + + tough-cookie@6.0.2: + dependencies: + tldts: 7.4.18 + + tr46@6.0.0: + dependencies: + punycode: 2.3.1 + + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-declaration-location@1.0.7(typescript@5.9.3): + dependencies: + picomatch: 4.0.7 + typescript: 5.9.3 + + tsconfck@3.1.6(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + tslib@2.8.1: + optional: true + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.71.2(@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3))(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.71.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.71.2(eslint@10.13.0(jiti@2.7.0))(typescript@5.9.3) + eslint: 10.13.0(jiti@2.7.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + undici-types@6.21.0: {} + + undici@7.30.1: {} + + unplugin@3.4.0(esbuild@0.28.2)(rollup@4.64.7)(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)): + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.7 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + esbuild: 0.28.2 + rollup: 4.64.7 + vite: 7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0) + + unrs-resolver@1.12.2: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.12.2 + '@unrs/resolver-binding-android-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-x64': 1.12.2 + '@unrs/resolver-binding-freebsd-x64': 1.12.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.12.2 + '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-loong64-musl': 1.12.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-musl': 1.12.2 + '@unrs/resolver-binding-openharmony-arm64': 1.12.2 + '@unrs/resolver-binding-wasm32-wasi': 1.12.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 + + update-browserslist-db@1.3.4(browserslist@4.29.3): + dependencies: + browserslist: 4.29.3 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + use-sync-external-store@1.7.0(react@19.3.1): + dependencies: + react: 19.3.1 + + util-deprecate@1.0.2: {} + + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)): + dependencies: + debug: 4.4.3 + globrex: 0.1.2 + tsconfck: 3.1.6(typescript@5.9.3) + optionalDependencies: + vite: 7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0) + transitivePeerDependencies: + - supports-color + - typescript + + vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0): + dependencies: + esbuild: 0.28.2 + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + postcss: 8.5.30 + rollup: 4.64.7 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 22.20.5 + fsevents: 2.3.3 + jiti: 2.7.0 + lightningcss: 1.32.0 + + vitest@5.0.5(@types/node@22.20.5)(jsdom@28.1.0(@noble/hashes@2.4.0))(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)): + dependencies: + '@types/chai': 5.2.3 + '@vitest/mocker': 5.0.5(vite@7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0)) + chai: 6.3.0 + es-module-lexer: 2.3.2 + expect-type: 1.4.0 + magic-string: 1.4.3 + obug: 3.0.0 + picomatch: 4.0.7 + std-env: 4.3.0 + tinybench: 6.2.2 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + vite: 7.3.7(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.32.0) + why-is-node-running: 3.2.1 + optionalDependencies: + '@types/node': 22.20.5 + jsdom: 28.1.0(@noble/hashes@2.4.0) + transitivePeerDependencies: + - msw + + vue-eslint-parser@10.4.1(eslint@10.13.0(jiti@2.7.0)): + dependencies: + debug: 4.4.3 + eslint: 10.13.0(jiti@2.7.0) + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + semver: 7.8.5 + transitivePeerDependencies: + - supports-color + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + webidl-conversions@8.0.1: {} + + webpack-virtual-modules@0.6.2: {} + + whatwg-mimetype@5.0.0: {} + + whatwg-url@16.0.1(@noble/hashes@2.4.0): + dependencies: + '@exodus/bytes': 1.16.0(@noble/hashes@2.4.0) + tr46: 6.0.0 + webidl-conversions: 8.0.1 + transitivePeerDependencies: + - '@noble/hashes' + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@3.2.1: {} + + word-wrap@1.2.5: {} + + ws@8.22.0: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + yallist@3.1.1: {} + + yocto-queue@0.1.0: {} + + zod@4.6.7: {} diff --git a/web-interface/public/favicon.ico b/web-interface/public/favicon.ico index a11777c..bd48292 100644 Binary files a/web-interface/public/favicon.ico and b/web-interface/public/favicon.ico differ diff --git a/web-interface/public/favicon.svg b/web-interface/public/favicon.svg new file mode 100644 index 0000000..a526ef2 --- /dev/null +++ b/web-interface/public/favicon.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + M + + diff --git a/web-interface/public/logo192.png b/web-interface/public/logo192.png index fc44b0a..51ffbf3 100644 Binary files a/web-interface/public/logo192.png and b/web-interface/public/logo192.png differ diff --git a/web-interface/public/logo512.png b/web-interface/public/logo512.png index a4e47a6..b3bf8bb 100644 Binary files a/web-interface/public/logo512.png and b/web-interface/public/logo512.png differ