diff --git a/docs/defect-fixing-plan.md b/docs/defect-fixing-plan.md new file mode 100644 index 0000000..db19521 --- /dev/null +++ b/docs/defect-fixing-plan.md @@ -0,0 +1,212 @@ +# Helix Engage — Defect Fixing Plan + +**Date**: 2026-03-31 +**Status**: Analysis complete, implementation pending + +--- + +## Item 1: Sidebar navigation during ongoing calls +**Status**: NOT A BUG +**Finding**: Sidebar is fully functional during calls. No code blocks navigation. Call state persists via Jotai atoms (`sipCallStateAtom`, `sipCallerNumberAtom`, `sipCallUcidAtom`) regardless of which page the agent navigates to. `CallWidget` in `app-shell.tsx` (line 80) renders on non-call-desk pages when a call is active, ensuring the agent can return. + +--- + +## Item 2: Appointment form / Enquiry form visibility during calls +**Status**: APPROVED REDESIGN — Convert to modals +**Root Cause**: `active-call-card.tsx` renders AppointmentForm and EnquiryForm inside a `max-h-[50vh] overflow-y-auto` container (line 292). After the call header + controls take ~100px, the form is squeezed. + +**Approved approach**: Convert both forms to modal dialogs (like TransferDialog already is). + +**Flow**: +``` +Agent clicks "Book Appt" → Modal opens → Log intent to LeadActivity → Agent fills form + → Save succeeds → setSuggestedDisposition('APPOINTMENT_BOOKED') → Modal closes + → Save abandoned → No disposition change → Intent logged for supervisor analytics +``` + +Same for Enquiry → `INFO_PROVIDED` on save, intent logged on open. + +**Files to change**: +- `src/components/call-desk/active-call-card.tsx` — replace inline form expansion with modal triggers +- `src/components/call-desk/appointment-form.tsx` — wrap in Modal/ModalOverlay from `src/components/application/modals/modal` +- `src/components/call-desk/enquiry-form.tsx` — wrap in Modal/ModalOverlay + +**Benefits**: Solves Item 2 (form visibility), Item 10a (returning patient checkbox shift), keeps call card clean. + +**Effort**: Medium (3-4h) + +--- + +## Item 3: Enquiry form disposition + modal disposition context +**Status**: REAL ISSUE (two parts) + +### 3a: Remove disposition from enquiry form +`enquiry-form.tsx` (lines 19-26, 195-198) has its own disposition field with 6 options (CONVERTED, FOLLOW_UP, GENERAL_QUERY, NO_ANSWER, INVALID_NUMBER, CALL_DROPPED). During an active call, NO_ANSWER and INVALID_NUMBER are nonsensical — the caller is connected. + +**Fix**: Remove disposition field from enquiry form entirely. Disposition is captured in the disposition modal after the call ends. The enquiry form's job is to log the enquiry, not to classify the call outcome. + +**Files**: `src/components/call-desk/enquiry-form.tsx` — remove disposition Select + validation + +### 3b: Context-aware disposition options in modal +`disposition-modal.tsx` (lines 15-57) shows all 6 options regardless of call context. During an inbound answered call, "No Answer" and "Wrong Number" don't apply. + +**Fix**: Accept a `callContext` prop ('inbound-answered' | 'outbound' | 'missed-callback') and filter options accordingly: +- Inbound answered: show APPOINTMENT_BOOKED, FOLLOW_UP_SCHEDULED, INFO_PROVIDED, CALLBACK_REQUESTED +- Outbound: show all +- Missed callback: show all + +**Files**: `src/components/call-desk/disposition-modal.tsx`, `src/components/call-desk/active-call-card.tsx` + +**Effort**: Low (2h) + +--- + +## Item 4: Edit future appointment during inbound call +**Status**: DONE (2026-03-30) +**Implementation**: Context panel (`context-panel.tsx` lines 172-197) shows upcoming appointments with Edit button → opens `AppointmentForm` in edit mode with `existingAppointment` prop. Appointments fetched via `APPOINTMENTS_QUERY` in DataProvider. + +--- + +## Item 5: My Performance page +**Status**: THREE SUB-ISSUES + +### 5a: From/To date range filter +**Current**: Only Today/Yesterday presets + single date picker in `my-performance.tsx` (lines 95-135). +**Fix**: Add two DatePicker components (From/To) or a date range picker. Update API call to accept date range. Update chart/KPI computations to use range. +**Effort**: Medium (3-4h) + +### 5b: Time Utilisation not displayed +**Current**: Section renders conditionally at line 263 — only if `timeUtilization` is not null. If sidecar API returns null (Ozonetel getAgentSummary fails or VPN blocks), section silently disappears. +**Fix**: Add placeholder/error state when null: "Time utilisation data unavailable — check Ozonetel connection" +**Effort**: Low (30min) + +### 5c: Data loading slow +**Current**: Fetches from `/api/ozonetel/performance` on every date change, no caching. +**Fix**: Add response caching (memoize by date key), show skeleton loader during fetch, debounce date changes. +**Effort**: Medium (2h) + +--- + +## Item 6: Break and Training status not working +**Status**: REAL ISSUE — likely Ozonetel API parameter mismatch + +**Root Cause**: `agent-status-toggle.tsx` (lines 41-64) calls `/api/ozonetel/agent-state` with `{ state: 'Pause', pauseReason: 'Break' }` or `'Training'`. Ozonetel's `changeAgentState` API may expect different pause reason enum values. Errors are caught and shown as generic toast — no specific failure reason. + +**Investigation needed**: +1. Check sidecar logs for the actual Ozonetel API response when Break/Training is selected +2. Verify Ozonetel API docs for valid `pauseReason` values (may need `BREAK`, `TRAINING`, or numeric codes) +3. Check if the agent must be in `Ready` state before transitioning to `Pause` + +**Fix**: Correct pause reason values, add specific error messages. +**Effort**: Low-Medium (2-3h including investigation) + +--- + +## Item 7: Auto-refresh for Call Desk, Call History, Appointments +**Status**: REAL ISSUE + +| Page | Current | Fix | +|---|---|---| +| Call Desk worklist | YES (30s via `use-worklist.ts`) | Working | +| DataProvider (calls, leads, etc.) | NO — `useEffect([fetchData])` runs once | Add `setInterval(fetchData, 30000)` | +| Call History | NO — uses `useData()` | Automatic once DataProvider fixed | +| Appointments | NO — `useEffect([])` runs once | Add interval or move to DataProvider | + +**Files**: `src/providers/data-provider.tsx` (lines 117-119), `src/pages/appointments.tsx` (lines 76-81) +**Effort**: Low (1-2h) + +--- + +## Item 8: Appointments page improvements +**Status**: THREE SUB-ISSUES + +### 8a: Appointment ID as primary field +**Current**: No ID column in table. `appointments.tsx` shows Patient, Date, Time, Doctor, Department, Branch, Status, Chief Complaint. +**Fix**: Add ID column (first column) showing appointment ID or a short reference number. +**Effort**: Low (30min) + +### 8b: Edit Appointment option +**Current**: No edit button on appointments page (only exists in call desk context panel). +**Fix**: Add per-row Edit button → opens AppointmentForm in edit mode (same component, reuse `existingAppointment` prop). +**Pending**: Confirmation from Meghana +**Effort**: Low (1-2h) + +### 8c: Sort by status +**Current**: Tabs filter by status but no column-level sorting. +**Fix**: Add `allowsSorting` to table headers + `sortDescriptor`/`onSortChange` (same pattern as worklist). +**Pending**: Confirmation from Meghana +**Effort**: Low (1h) + +--- + +## Item 9: AI Surface enlargement + patient historical data +**Status**: PARTIALLY DONE + +### 9a: Panel width +**Current**: Context panel is `w-[400px]` in `call-desk.tsx` (line 218). +**Fix**: Increase to `w-[440px]` or `w-[460px]`. +**Effort**: Trivial + +### 9b: Patient historical data +**Current**: We added calls, follow-ups, and appointments to context panel (2026-03-30). Shows in "Upcoming" and "Recent" sections. Data requires `patientId` on the lead — populated by caller resolution service. +**Verify**: Test with real inbound call to confirmed patient. If lead has no `patientId`, nothing shows. +**Effort**: Done — verify only + +--- + +## Item 10: Multiple issues + +### 10a: Returning Patient checkbox shifts form upward +**Status**: WILL BE FIXED by Item 2 (modal conversion). Form in modal has its own layout — checkbox toggle won't affect call card. + +### 10b: Patients page table not scrollable +**File**: `src/pages/patients.tsx` +**Fix**: Add `overflow-auto` to table container wrapper. Check if outer div has proper `min-h-0` for flex overflow. +**Effort**: Trivial (15min) + +### 10c: Call log data not appearing in worklist tabs +**Status**: INVESTIGATION NEEDED +**Possible causes**: +1. Sidecar `/api/worklist` not returning data — check endpoint response +2. Calls created via Ozonetel disposition lack `leadId` linkage — can't match to worklist +3. Call records created but `callStatus` not set correctly (need `MISSED` for missed tab) +**Action**: Check sidecar logs and `/api/worklist` response payload + +### 10d: Missed calls appearing in wrong sub-tabs (Attempted/Completed/Invalid instead of Pending) +**Status**: INVESTIGATION NEEDED +**Possible cause**: `callbackstatus` field being set to non-null value during call creation. `worklist-panel.tsx` (line 246) routes to Pending when `callbackstatus === 'PENDING_CALLBACK' || !callbackstatus`. If the sidecar sets a status during ingestion, it may skip Pending. +**Action**: Check missed call ingestion code in sidecar — what `callbackstatus` is set on creation + +--- + +## Item 11: Patient column filter in Call Desk +**Status**: NOT A BUG +**Finding**: The PATIENT column has `allowsSorting` (added 2026-03-30) which shows a sort arrow. This is a sort control, not a filter. The search box at the top of the worklist filters across name + phone. No separate column-level filter exists. Functionally correct. + +--- + +## Priority Matrix + +| Priority | Items | Total Effort | +|---|---|---| +| **P0 — Do first** | #2 (modal conversion — solves 2, 10a), #7 (auto-refresh), #3 (disposition context) | ~7h | +| **P1 — Quick wins** | #8a (appt ID), #8c (sort), #9a (panel width), #10b (scroll fix), #5b (time util placeholder) | ~3h | +| **P2 — Medium** | #5a (date range), #5c (loading perf), #6 (break/training debug), #8b (edit appt) | ~8h | +| **P3 — Investigation** | #10c (call log data), #10d (missed call routing) | ~2h investigation | +| **Done** | #1, #4, #9b, #11 | — | + +## Data Seeding (separate from defects) + +### Patient/Lead seeding +| Name | Phone | Action | +|---|---|---| +| Ganesh Bandi | 8885540404 | Create patient + lead, interestedService: "Back Pain" | +| Meghana | 7702055204 | Update existing "Unknown" patient + lead, interestedService: "Hair Loss" | + +### CC Agent profiles (completed) +``` +Agent Email Password Ozonetel ID SIP Ext Campaign +-------- ---------------------------- --------- -------------- -------- ---------------------- +Rekha S rekha.cc@globalhospital.com Test123$ global 523590 Inbound_918041763265 +Ganesh ganesh.cc@globalhospital.com Test123$ globalhealthx 523591 Inbound_918041763265 +``` diff --git a/docs/developer-operations-runbook.md b/docs/developer-operations-runbook.md new file mode 100644 index 0000000..98ff151 --- /dev/null +++ b/docs/developer-operations-runbook.md @@ -0,0 +1,431 @@ +# Helix Engage — Developer Operations Runbook + +## Architecture + +``` +Browser (India) + ↓ HTTPS +Caddy (reverse proxy, TLS, static files) + ├── engage.srv1477139.hstgr.cloud → /srv/engage (static frontend) + ├── engage-api.srv1477139.hstgr.cloud → sidecar:4100 + └── *.srv1477139.hstgr.cloud → server:4000 (platform) + +Docker Compose stack: + ├── caddy — Reverse proxy + TLS + ├── server — FortyTwo platform (ECR image) + ├── worker — Background jobs + ├── sidecar — Helix Engage NestJS API (ECR image) + ├── db — PostgreSQL 16 + ├── redis — Session + cache + ├── clickhouse — Analytics + ├── minio — Object storage + └── redpanda — Event bus (Kafka) +``` + +## VPS Access + +```bash +# SSH into the VPS +sshpass -p 'SasiSuman@2007' ssh -o StrictHostKeyChecking=no root@148.230.67.184 + +# Or with SSH key (if configured) +ssh -i ~/Downloads/fortytwoai_hostinger root@148.230.67.184 +``` + +| Detail | Value | +|---|---| +| Host | 148.230.67.184 | +| User | root | +| Password | SasiSuman@2007 | +| Docker compose dir | /opt/fortytwo | +| Frontend static files | /opt/fortytwo/helix-engage-frontend | +| Caddyfile | /opt/fortytwo/Caddyfile | + +## URLs + +| Service | URL | +|---|---| +| Frontend | https://engage.srv1477139.hstgr.cloud | +| Sidecar API | https://engage-api.srv1477139.hstgr.cloud | +| Platform | https://fortytwo-dev.srv1477139.hstgr.cloud | + +## Login Credentials + +| Role | Email | Password | +|---|---|---| +| CC Agent | rekha.cc@globalhospital.com | Global@123 | +| CC Agent | ganesh.cc@globalhospital.com | Global@123 | +| Marketing | sanjay.marketing@globalhospital.com | Global@123 | +| Admin/Supervisor | dr.ramesh@globalhospital.com | Global@123 | + +--- + +## Local Testing + +Always test locally before deploying to staging. + +### Frontend (Vite dev server) + +```bash +cd helix-engage + +# Start dev server (hot reload) +npm run dev +# → http://localhost:5173 + +# Type check (catches production build errors) +npx tsc --noEmit + +# Production build (same as deploy) +npm run build +``` + +The `.env.local` controls which sidecar the frontend talks to: +```bash +# Remote sidecar (default — uses deployed backend) +VITE_API_URL=https://engage-api.srv1477139.hstgr.cloud +VITE_SIDECAR_URL=https://engage-api.srv1477139.hstgr.cloud + +# Local sidecar (for testing sidecar changes) +# VITE_API_URL=http://localhost:4100 +# VITE_SIDECAR_URL=http://localhost:4100 + +# Split — theme endpoint local, everything else remote +# VITE_THEME_API_URL=http://localhost:4100 +``` + +**Important:** When `VITE_API_URL` points to `localhost:4100`, login and GraphQL only work if the local sidecar can reach the platform. The local sidecar's `.env` must have valid `PLATFORM_GRAPHQL_URL` and `PLATFORM_API_KEY`. + +### Sidecar (NestJS dev server) + +```bash +cd helix-engage-server + +# Start with watch mode (auto-restart on changes) +npm run start:dev +# → http://localhost:4100 + +# Build only (no run) +npm run build + +# Production start +npm run start:prod +``` + +The sidecar `.env` must have: +```bash +PLATFORM_GRAPHQL_URL=... # Platform GraphQL endpoint +PLATFORM_API_KEY=... # Platform API key for server-to-server calls +PLATFORM_WORKSPACE_SUBDOMAIN=fortytwo-dev +REDIS_URL=redis://localhost:6379 # Local Redis required +``` + +### Local Docker stack (full environment) + +For testing with a local platform + database + Redis: + +```bash +cd helix-engage-local + +# First time — pull images + start +./deploy-local.sh up + +# Deploy frontend to local stack +./deploy-local.sh frontend + +# Deploy sidecar to local stack +./deploy-local.sh sidecar + +# Both +./deploy-local.sh all + +# Logs +./deploy-local.sh logs + +# Stop +./deploy-local.sh down +``` + +Local stack URLs: +- Platform: `http://localhost:5001` +- Sidecar: `http://localhost:5100` +- Frontend: `http://localhost:5080` + +### Pre-deploy checklist + +Before running `deploy.sh`: + +1. `npx tsc --noEmit` — passes with no errors (frontend) +2. `npm run build` — succeeds (sidecar) +3. Test the changed feature locally (dev server or local stack) +4. Check `package.json` for new dependencies → decides quick vs full deploy + +--- + +## Deployment + +### Prerequisites (local machine) + +```bash +# Required tools +brew install sshpass # SSH with password +aws configure # AWS CLI (for ECR) +docker desktop # Docker with buildx + +# Verify AWS access +aws sts get-caller-identity # Should show account 043728036361 +``` + +### Path 1: Quick Deploy (no new dependencies) + +Use when only code changes — no new npm packages. + +```bash +cd /path/to/fortytwo-eap + +# Deploy frontend only +bash deploy.sh frontend + +# Deploy sidecar only +bash deploy.sh sidecar + +# Deploy both +bash deploy.sh all +``` + +**What it does:** +- Frontend: `npm run build` → tar `dist/` → SCP to VPS → extract to `/opt/fortytwo/helix-engage-frontend` +- Sidecar: `nest build` → tar `dist/` + `src/` → docker cp into running container → `docker compose restart sidecar` + +### Path 2: Full Deploy (new dependencies) + +Use when `package.json` changed (new npm packages added). + +```bash +cd /path/to/fortytwo-eap/helix-engage-server + +# 1. Login to ECR +aws ecr get-login-password --region ap-south-1 | docker login --username AWS --password-stdin 043728036361.dkr.ecr.ap-south-1.amazonaws.com + +# 2. Build cross-platform image and push +docker buildx build --platform linux/amd64 \ + -t 043728036361.dkr.ecr.ap-south-1.amazonaws.com/fortytwo-eap/helix-engage-sidecar:alpha \ + --push . + +# 3. Pull and restart on VPS +ECR_TOKEN=$(aws ecr get-login-password --region ap-south-1) +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 " + echo '$ECR_TOKEN' | docker login --username AWS --password-stdin 043728036361.dkr.ecr.ap-south-1.amazonaws.com + cd /opt/fortytwo + docker compose pull sidecar + docker compose up -d sidecar +" +``` + +### How to decide which path + +``` +Did package.json change? + ├── YES → Path 2 (ECR build + push + pull) + └── NO → Path 1 (deploy.sh) +``` + +--- + +## Checking Logs + +### Sidecar logs + +```bash +# SSH into VPS first, or run remotely: +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker logs fortytwo-staging-sidecar-1 --tail 30" + +# Follow live +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker logs fortytwo-staging-sidecar-1 -f --tail 10" + +# Filter for errors +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker logs fortytwo-staging-sidecar-1 --tail 100 2>&1 | grep -i error" + +# Via deploy.sh +bash deploy.sh logs +``` + +### Caddy logs + +```bash +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker logs fortytwo-staging-caddy-1 --tail 30" +``` + +### Platform server logs + +```bash +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker logs fortytwo-staging-server-1 --tail 30" +``` + +### All container status + +```bash +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'" +``` + +--- + +## Health Checks + +### Sidecar healthy startup + +Look for these lines in sidecar logs: +``` +[NestApplication] Nest application successfully started +Helix Engage Server running on port 4100 +[SessionService] Redis connected +[ThemeService] Theme loaded from file (or "Using default theme") +[RulesStorageService] Initialized empty rules config +``` + +### Common failure patterns + +| Log pattern | Meaning | Fix | +|---|---|---| +| `Cannot find module 'xxx'` | Missing npm dependency | Path 2 deploy (rebuild ECR image) | +| `UndefinedModuleException` | Circular dependency or missing import | Fix code, redeploy | +| `ECONNREFUSED redis:6379` | Redis not ready | `docker compose restart redis sidecar` | +| `Forbidden resource` | Platform permission issue | Check user roles | +| `429 Too Many Requests` | Ozonetel rate limit | Wait, reduce polling frequency | + +--- + +## Redis Cache Operations + +### Clear caller resolution cache + +```bash +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker exec fortytwo-staging-redis-1 redis-cli KEYS 'caller:*'" + +# Clear all caller cache +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker exec fortytwo-staging-redis-1 redis-cli --scan --pattern 'caller:*' | xargs -r docker exec -i fortytwo-staging-redis-1 redis-cli DEL" +``` + +### Clear recording analysis cache + +```bash +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker exec fortytwo-staging-redis-1 redis-cli --scan --pattern 'call:analysis:*' | xargs -r docker exec -i fortytwo-staging-redis-1 redis-cli DEL" +``` + +### Clear agent name cache + +```bash +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker exec fortytwo-staging-redis-1 redis-cli --scan --pattern 'agent:name:*' | xargs -r docker exec -i fortytwo-staging-redis-1 redis-cli DEL" +``` + +### Clear all session/cache keys + +```bash +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker exec fortytwo-staging-redis-1 redis-cli FLUSHDB" +``` + +--- + +## Database Access + +```bash +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 "docker exec fortytwo-staging-db-1 psql -U fortytwo -d fortytwo_staging" +``` + +### Useful queries + +```sql +-- List workspace schemas +SELECT schema_name FROM information_schema.schemata WHERE schema_name LIKE 'workspace_%'; + +-- List custom entities +SELECT "nameSingular", "isCustom" FROM core."objectMetadata" ORDER BY "nameSingular"; + +-- List users +SELECT u.email, u."firstName", u."lastName", uw.id as workspace_id +FROM core."user" u +JOIN core."userWorkspace" uw ON uw."userId" = u.id; + +-- List roles +SELECT r.label, rt."userWorkspaceId" +FROM core."roleTarget" rt +JOIN core."role" r ON r.id = rt."roleId"; +``` + +--- + +## Rollback + +### Frontend rollback + +The previous frontend build is overwritten. To rollback: +1. Checkout the previous git commit +2. `npm run build` +3. `bash deploy.sh frontend` + +### Sidecar rollback (quick deploy) + +Same as frontend — checkout previous commit, rebuild, redeploy. + +### Sidecar rollback (ECR) + +```bash +# Tag the current image as rollback +# Then re-tag the previous image as :alpha +# Or use a specific tag/digest + +# On VPS: +sshpass -p 'SasiSuman@2007' ssh root@148.230.67.184 " + cd /opt/fortytwo + docker compose restart sidecar +" +``` + +--- + +## Theme Management + +### View current theme +```bash +curl -s https://engage-api.srv1477139.hstgr.cloud/api/config/theme | python3 -m json.tool +``` + +### Reset theme to defaults +```bash +curl -s -X POST https://engage-api.srv1477139.hstgr.cloud/api/config/theme/reset | python3 -m json.tool +``` + +### Theme backups +Stored on the sidecar container at `/app/data/theme-backups/`. Each save creates a timestamped backup. + +--- + +## Git Repositories + +| Repo | Azure DevOps URL | Branch | +|---|---|---| +| Frontend | `https://dev.azure.com/globalhealthx/EMR/_git/helix-engage` | `dev` | +| Sidecar | `https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server` | `dev` | +| SDK App | `FortyTwoApps/helix-engage/` (in fortytwo-eap monorepo) | `dev` | + +### Commit and push pattern +```bash +# Frontend +cd helix-engage +git add -A && git commit -m "feat: description" && git push origin dev + +# Sidecar +cd helix-engage-server +git add -A && git commit -m "feat: description" && git push origin dev +``` + +--- + +## ECR Details + +| Detail | Value | +|---|---| +| Registry | 043728036361.dkr.ecr.ap-south-1.amazonaws.com | +| Repository | fortytwo-eap/helix-engage-sidecar | +| Tag | alpha | +| Region | ap-south-1 (Mumbai) | diff --git a/docs/generate-pptx.cjs b/docs/generate-pptx.cjs new file mode 100644 index 0000000..3977483 --- /dev/null +++ b/docs/generate-pptx.cjs @@ -0,0 +1,680 @@ +/** + * Helix Engage — Weekly Update (Mar 18–25, 2026) + * Light Mode PowerPoint Generator via PptxGenJS + */ +const PptxGenJS = require("pptxgenjs"); + +// ── Design Tokens (Light Mode) ───────────────────────────────────────── +const C = { + bg: "FFFFFF", + bgSubtle: "F8FAFC", + bgCard: "F1F5F9", + bgCardAlt: "E2E8F0", + text: "1E293B", + textSec: "475569", + textMuted: "94A3B8", + accent1: "0EA5E9", // Sky blue (telephony) + accent2: "8B5CF6", // Violet (server/backend) + accent3: "10B981", // Emerald (UX) + accent4: "F59E0B", // Amber (features) + accent5: "EF4444", // Rose (ops) + accent6: "6366F1", // Indigo (timeline) + white: "FFFFFF", + border: "CBD5E1", +}; + +const FONT = { + heading: "Arial", + body: "Arial", +}; + +// ── Helpers ────────────────────────────────────────────────────────────── +function addSlideNumber(slide, num, total) { + slide.addText(`${num} / ${total}`, { + x: 8.8, y: 5.2, w: 1.2, h: 0.3, + fontSize: 8, color: C.textMuted, + fontFace: FONT.body, + align: "right", + }); +} + +function addAccentBar(slide, color) { + slide.addShape("rect", { + x: 0, y: 0, w: 10, h: 0.06, + fill: { color }, + }); +} + +function addLabel(slide, text, color, x, y) { + slide.addShape("roundRect", { + x, y, w: text.length * 0.09 + 0.4, h: 0.3, + fill: { color, transparency: 88 }, + rectRadius: 0.15, + }); + slide.addText(text.toUpperCase(), { + x, y, w: text.length * 0.09 + 0.4, h: 0.3, + fontSize: 7, fontFace: FONT.heading, bold: true, + color, align: "center", valign: "middle", + letterSpacing: 2, + }); +} + +function addCard(slide, opts) { + const { x, y, w, h, title, titleColor, items, badge } = opts; + // Card background + slide.addShape("roundRect", { + x, y, w, h, + fill: { color: C.bgCard }, + line: { color: C.border, width: 0.5 }, + rectRadius: 0.1, + }); + // Title + const titleText = badge + ? [{ text: title + " ", options: { bold: true, color: titleColor, fontSize: 11 } }, + { text: badge, options: { bold: true, color: C.white, fontSize: 7, highlight: titleColor } }] + : title; + slide.addText(titleText, { + x: x + 0.2, y: y + 0.08, w: w - 0.4, h: 0.35, + fontSize: 11, fontFace: FONT.heading, bold: true, + color: titleColor, + }); + // Items as bullet list + if (items && items.length > 0) { + slide.addText( + items.map(item => ({ + text: item, + options: { + fontSize: 8.5, fontFace: FONT.body, color: C.textSec, + bullet: { type: "bullet", style: "arabicPeriod" }, + paraSpaceAfter: 2, + breakLine: true, + }, + })), + { + x: x + 0.2, y: y + 0.4, w: w - 0.4, h: h - 0.5, + valign: "top", + bullet: { type: "bullet" }, + lineSpacingMultiple: 1.1, + } + ); + } +} + +// ── Build Presentation ────────────────────────────────────────────────── +async function build() { + const pptx = new PptxGenJS(); + pptx.layout = "LAYOUT_16x9"; + pptx.author = "Satya Suman Sari"; + pptx.company = "FortyTwo Platform"; + pptx.title = "Helix Engage — Weekly Update (Mar 18–25, 2026)"; + pptx.subject = "Engineering Progress Report"; + + const TOTAL = 9; + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 1 — Title + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + + // Accent bar top + addAccentBar(slide, C.accent1); + + // Decorative side stripe + slide.addShape("rect", { + x: 0, y: 0, w: 0.12, h: 5.63, + fill: { color: C.accent1 }, + }); + + // Label + addLabel(slide, "Weekly Engineering Update", C.accent1, 3.0, 1.2); + + // Title + slide.addText("Helix Engage", { + x: 1.0, y: 1.8, w: 8, h: 1.2, + fontSize: 44, fontFace: FONT.heading, bold: true, + color: C.accent1, align: "center", + }); + + // Subtitle + slide.addText("Contact Center CRM · Real-time Telephony · AI Copilot", { + x: 1.5, y: 2.9, w: 7, h: 0.5, + fontSize: 14, fontFace: FONT.body, + color: C.textSec, align: "center", + }); + + // Date + slide.addText("March 18 – 25, 2026", { + x: 3, y: 3.6, w: 4, h: 0.4, + fontSize: 12, fontFace: FONT.heading, bold: true, + color: C.textMuted, align: "center", + letterSpacing: 3, + }); + + // Bottom decoration + slide.addShape("rect", { + x: 3.5, y: 4.2, w: 3, h: 0.04, + fill: { color: C.accent2 }, + }); + + // Author + slide.addText("Satya Suman Sari · FortyTwo Platform", { + x: 2, y: 4.5, w: 6, h: 0.35, + fontSize: 9, fontFace: FONT.body, + color: C.textMuted, align: "center", + }); + + addSlideNumber(slide, 1, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 2 — At a Glance + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent2); + + addLabel(slide, "At a Glance", C.accent2, 0.5, 0.3); + + slide.addText("Week in Numbers", { + x: 0.5, y: 0.65, w: 5, h: 0.5, + fontSize: 24, fontFace: FONT.heading, bold: true, + color: C.text, + }); + + // Stat cards + const stats = [ + { value: "78", label: "Total Commits", color: C.accent1 }, + { value: "3", label: "Repositories", color: C.accent2 }, + { value: "8", label: "Days Active", color: C.accent3 }, + { value: "50", label: "Frontend Commits", color: C.accent4 }, + ]; + + stats.forEach((s, i) => { + const x = 0.5 + i * 2.35; + // Card bg + slide.addShape("roundRect", { + x, y: 1.3, w: 2.1, h: 1.7, + fill: { color: C.bgCard }, + line: { color: C.border, width: 0.5 }, + rectRadius: 0.12, + }); + // Accent top line + slide.addShape("rect", { + x: x + 0.2, y: 1.35, w: 1.7, h: 0.035, + fill: { color: s.color }, + }); + // Number + slide.addText(s.value, { + x, y: 1.5, w: 2.1, h: 0.9, + fontSize: 36, fontFace: FONT.heading, bold: true, + color: s.color, align: "center", valign: "middle", + }); + // Label + slide.addText(s.label, { + x, y: 2.4, w: 2.1, h: 0.4, + fontSize: 9, fontFace: FONT.body, + color: C.textSec, align: "center", + }); + }); + + // Repo breakdown pills + const repos = [ + { name: "helix-engage", count: "50", clr: C.accent1 }, + { name: "helix-engage-server", count: "27", clr: C.accent2 }, + { name: "FortyTwoApps/SDK", count: "1", clr: C.accent3 }, + ]; + repos.forEach((r, i) => { + const x = 1.5 + i * 2.8; + slide.addShape("roundRect", { + x, y: 3.4, w: 2.5, h: 0.4, + fill: { color: C.bgCard }, + line: { color: r.clr, width: 1 }, + rectRadius: 0.2, + }); + slide.addText(`${r.name} ${r.count}`, { + x, y: 3.4, w: 2.5, h: 0.4, + fontSize: 9, fontFace: FONT.heading, bold: true, + color: r.clr, align: "center", valign: "middle", + }); + }); + + // Summary text + slide.addText("3 repos · 7 working days · 78 commits shipped to production", { + x: 1, y: 4.2, w: 8, h: 0.35, + fontSize: 10, fontFace: FONT.body, italic: true, + color: C.textMuted, align: "center", + }); + + addSlideNumber(slide, 2, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 3 — Telephony & SIP + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent1); + + addLabel(slide, "Core Infrastructure", C.accent1, 0.5, 0.3); + + slide.addText([ + { text: "☎ ", options: { fontSize: 22 } }, + { text: "Telephony & SIP Overhaul", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 4.5, h: 2.0, + title: "Outbound Calling", titleColor: C.accent1, badge: "Frontend", + items: [ + "Direct SIP call from browser — no Kookoo bridge", + "Immediate call card UI with auto-answer SIP bridge", + "End Call label fix, force active state after auto-answer", + "Reset outboundPending on call end", + ], + }); + + addCard(slide, { + x: 5.2, y: 1.35, w: 4.5, h: 2.0, + title: "Ozonetel Integration", titleColor: C.accent2, badge: "Server", + items: [ + "Ozonetel V3 dial endpoint + webhook handler", + "Set Disposition API for ACW release", + "Force Ready endpoint for agent state mgmt", + "Token: 10-min cache, 401 invalidation, refresh on login", + ], + }); + + addCard(slide, { + x: 0.3, y: 3.55, w: 4.5, h: 1.8, + title: "SIP & Agent State", titleColor: C.accent1, badge: "Frontend", + items: [ + "SIP driven by Agent entity with token refresh", + "Centralised outbound dial into useSip().dialOutbound()", + "UCID tracking from SIP headers for disposition", + "Network indicator for connection health", + ], + }); + + addCard(slide, { + x: 5.2, y: 3.55, w: 4.5, h: 1.8, + title: "Multi-Agent & Sessions", titleColor: C.accent2, badge: "Server", + items: [ + "Multi-agent SIP with Redis session lockout", + "Strict duplicate login — one device per agent", + "Session lock stores IP + timestamp for debugging", + "SSE agent state broadcast for supervisor view", + ], + }); + + addSlideNumber(slide, 3, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 4 — Call Desk & Agent UX + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent3); + + addLabel(slide, "User Experience", C.accent3, 0.5, 0.3); + + slide.addText([ + { text: "🖥 ", options: { fontSize: 22 } }, + { text: "Call Desk & Agent UX", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 3.05, h: 2.6, + title: "Call Desk Redesign", titleColor: C.accent3, + items: [ + "2-panel layout with collapsible sidebar & inline AI", + "Collapsible context panel, worklist/calls tabs", + "Pinned header & chat input, numpad dialler", + "Ringtone support for incoming calls", + ], + }); + + addCard(slide, { + x: 3.55, y: 1.35, w: 3.05, h: 2.6, + title: "Post-Call Workflow", titleColor: C.accent3, + items: [ + "Disposition → appointment booking → follow-up", + "Disposition returns straight to worklist", + "Send disposition to sidecar with UCID for ACW", + "Enquiry in post-call, appointment skip button", + ], + }); + + addCard(slide, { + x: 6.8, y: 1.35, w: 2.9, h: 2.6, + title: "UI Polish", titleColor: C.accent3, + items: [ + "FontAwesome Pro Duotone icon migration", + "Tooltips, sticky headers, roles, search", + "Fix React error #520 in prod tables", + "AI scroll containment, brand tokens refresh", + ], + }); + + addSlideNumber(slide, 4, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 5 — Features Shipped + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent4); + + addLabel(slide, "Features Shipped", C.accent4, 0.5, 0.3); + + slide.addText([ + { text: "🚀 ", options: { fontSize: 22 } }, + { text: "Major Features", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 4.5, h: 2.0, + title: "Supervisor Module", titleColor: C.accent4, + items: [ + "Team performance analytics page", + "Live monitor with active calls visibility", + "Master data management pages", + "Server: team perf + active calls endpoints", + ], + }); + + addCard(slide, { + x: 5.2, y: 1.35, w: 4.5, h: 2.0, + title: "Missed Call Queue (Phase 2)", titleColor: C.accent4, + items: [ + "Missed call queue ingestion & worklist", + "Auto-assignment engine for agents", + "Login redesign with role-based routing", + "Lead lookup for missed callers", + ], + }); + + addCard(slide, { + x: 0.3, y: 3.55, w: 4.5, h: 1.8, + title: "Agent Features (Phase 1)", titleColor: C.accent4, + items: [ + "Agent status toggle (Ready / Not Ready / Break)", + "Global search across patients, leads, calls", + "Enquiry form for new patient intake", + "My Performance page + logout modal", + ], + }); + + addCard(slide, { + x: 5.2, y: 3.55, w: 4.5, h: 1.8, + title: "Recording Analysis", titleColor: C.accent4, + items: [ + "Deepgram diarization + AI insights", + "Redis caching layer for analysis results", + "Full-stack: frontend player + server module", + ], + }); + + addSlideNumber(slide, 5, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 6 — Backend & Data + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent2); + + addLabel(slide, "Backend & Data", C.accent2, 0.5, 0.3); + + slide.addText([ + { text: "⚙ ", options: { fontSize: 22 } }, + { text: "Backend & Data Layer", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 4.5, h: 2.0, + title: "Platform Data Wiring", titleColor: C.accent2, + items: [ + "Migrated frontend to Jotai + Vercel AI SDK", + "Corrected all 7 GraphQL queries (fields, LINKS/PHONES)", + "Webhook handler for Ozonetel call records", + "Complete seeder: 5 doctors, appointments linked", + ], + }); + + addCard(slide, { + x: 5.2, y: 1.35, w: 4.5, h: 2.0, + title: "Server Endpoints", titleColor: C.accent2, + items: [ + "Call control, recording, CDR, missed calls, live assist", + "Agent summary, AHT, performance aggregation", + "Token refresh endpoint for auto-renewal", + "Search module with full-text capabilities", + ], + }); + + addCard(slide, { + x: 0.3, y: 3.55, w: 4.5, h: 1.8, + title: "Data Pages Built", titleColor: C.accent2, + items: [ + "Worklist table, call history, patients, dashboard", + "Reports, team dashboard, campaigns, settings", + "Agent detail page, campaign edit slideout", + "Appointments page with data refresh on login", + ], + }); + + addCard(slide, { + x: 5.2, y: 3.55, w: 4.5, h: 1.8, + title: "SDK App", titleColor: C.accent3, badge: "FortyTwoApps", + items: [ + "Helix Engage SDK app entity definitions", + "Call center CRM object model for platform", + "Foundation for platform-native data integration", + ], + }); + + addSlideNumber(slide, 6, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 7 — Deployment & Ops + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent5); + + addLabel(slide, "Operations", C.accent5, 0.5, 0.3); + + slide.addText([ + { text: "🛠 ", options: { fontSize: 22 } }, + { text: "Deployment & DevOps", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 3.05, h: 2.2, + title: "Deployment", titleColor: C.accent5, + items: [ + "Deployed to Hostinger VPS with Docker", + "Switched to global_healthx Ozonetel account", + "Dockerfile for server-side containerization", + ], + }); + + addCard(slide, { + x: 3.55, y: 1.35, w: 3.05, h: 2.2, + title: "AI & Testing", titleColor: C.accent5, + items: [ + "Migrated AI to Vercel AI SDK + OpenAI provider", + "AI flow test script — validates full pipeline", + "Live call assist integration", + ], + }); + + addCard(slide, { + x: 6.8, y: 1.35, w: 2.9, h: 2.2, + title: "Documentation", titleColor: C.accent5, + items: [ + "Team onboarding README with arch guide", + "Supervisor module spec + plan", + "Multi-agent spec + plan", + "Next session plans in commits", + ], + }); + + addSlideNumber(slide, 7, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 8 — Timeline + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent6); + + addLabel(slide, "Day by Day", C.accent6, 0.5, 0.3); + + slide.addText([ + { text: "📅 ", options: { fontSize: 22 } }, + { text: "Development Timeline", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + const timeline = [ + { date: "MAR 18 (Tue)", title: "Foundation Day", desc: "Call desk redesign, Jotai + AI SDK migration, seeder, AI flow test, VPS deploy" }, + { date: "MAR 19 (Wed)", title: "Data Layer Sprint", desc: "All data pages, post-call workflow, GraphQL fixes, Kookoo IVR, outbound UI" }, + { date: "MAR 20 (Thu)", title: "Telephony Breakthrough", desc: "Direct SIP replacing Kookoo, UCID tracking, Force Ready, Set Disposition" }, + { date: "MAR 21 (Fri)", title: "Agent Experience", desc: "Phase 1: status toggle, search, enquiry form, My Performance, FA icons, AHT" }, + { date: "MAR 23 (Sun)", title: "Scale & Reliability", desc: "Phase 2: missed call queue, auto-assign, Redis lockout, Patient 360, SDK defs" }, + { date: "MAR 24 (Mon)", title: "Supervisor Module", desc: "Team perf, live monitor, master data, SSE, UUID fix, maintenance, QA sweep" }, + { date: "MAR 25 (Tue)", title: "Intelligence Layer", desc: "Deepgram diarization, AI insights, SIP via Agent entity, token refresh, network" }, + ]; + + // Vertical line + slide.addShape("rect", { + x: 1.4, y: 1.3, w: 0.025, h: 4.0, + fill: { color: C.accent6, transparency: 60 }, + }); + + timeline.forEach((entry, i) => { + const y = 1.3 + i * 0.56; + + // Dot + slide.addShape("ellipse", { + x: 1.32, y: y + 0.08, w: 0.18, h: 0.18, + fill: { color: C.accent6 }, + line: { color: C.bg, width: 2 }, + }); + + // Date + slide.addText(entry.date, { + x: 1.7, y: y, w: 1.6, h: 0.22, + fontSize: 7, fontFace: FONT.heading, bold: true, + color: C.accent6, + }); + + // Title + slide.addText(entry.title, { + x: 3.3, y: y, w: 2.0, h: 0.22, + fontSize: 9, fontFace: FONT.heading, bold: true, + color: C.text, + }); + + // Description + slide.addText(entry.desc, { + x: 5.3, y: y, w: 4.2, h: 0.45, + fontSize: 8, fontFace: FONT.body, + color: C.textSec, + valign: "top", + }); + }); + + addSlideNumber(slide, 8, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 9 — Closing + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent3); + + // Big headline + slide.addText("78 commits. 8 days. Ship mode.", { + x: 0.5, y: 1.4, w: 9, h: 0.8, + fontSize: 32, fontFace: FONT.heading, bold: true, + color: C.accent3, align: "center", + }); + + // Ship emoji + slide.addText("🚢", { + x: 4.2, y: 2.3, w: 1.6, h: 0.6, + fontSize: 28, align: "center", + }); + + // Description + slide.addText( + "From browser-native SIP calling to AI-powered recording analysis — Helix Engage is becoming a production contact center platform.", + { + x: 1.5, y: 3.0, w: 7, h: 0.6, + fontSize: 11, fontFace: FONT.body, + color: C.textSec, align: "center", + lineSpacingMultiple: 1.3, + } + ); + + // Achievement pills + const achievements = [ + { text: "SIP Calling ✓", color: C.accent1 }, + { text: "Multi-Agent ✓", color: C.accent2 }, + { text: "Supervisor ✓", color: C.accent3 }, + { text: "AI Copilot ✓", color: C.accent4 }, + { text: "Recording Analysis ✓", color: C.accent5 }, + ]; + + achievements.forEach((a, i) => { + const x = 0.8 + i * 1.8; + slide.addShape("roundRect", { + x, y: 3.9, w: 1.6, h: 0.35, + fill: { color: C.bgCard }, + line: { color: a.color, width: 1 }, + rectRadius: 0.17, + }); + slide.addText(a.text, { + x, y: 3.9, w: 1.6, h: 0.35, + fontSize: 8, fontFace: FONT.heading, bold: true, + color: a.color, align: "center", valign: "middle", + }); + }); + + // Author + slide.addText("Satya Suman Sari · FortyTwo Platform", { + x: 2, y: 4.7, w: 6, h: 0.3, + fontSize: 9, fontFace: FONT.body, + color: C.textMuted, align: "center", + }); + + addSlideNumber(slide, 9, TOTAL); + } + + // ── Save ────────────────────────────────────────────────────────────── + const outPath = "weekly-update-mar18-25.pptx"; + await pptx.writeFile({ fileName: outPath }); + console.log(`✅ Presentation saved: ${outPath}`); +} + +build().catch(err => { + console.error("❌ Failed:", err.message); + process.exit(1); +}); diff --git a/docs/generate-pptx.js b/docs/generate-pptx.js new file mode 100644 index 0000000..3977483 --- /dev/null +++ b/docs/generate-pptx.js @@ -0,0 +1,680 @@ +/** + * Helix Engage — Weekly Update (Mar 18–25, 2026) + * Light Mode PowerPoint Generator via PptxGenJS + */ +const PptxGenJS = require("pptxgenjs"); + +// ── Design Tokens (Light Mode) ───────────────────────────────────────── +const C = { + bg: "FFFFFF", + bgSubtle: "F8FAFC", + bgCard: "F1F5F9", + bgCardAlt: "E2E8F0", + text: "1E293B", + textSec: "475569", + textMuted: "94A3B8", + accent1: "0EA5E9", // Sky blue (telephony) + accent2: "8B5CF6", // Violet (server/backend) + accent3: "10B981", // Emerald (UX) + accent4: "F59E0B", // Amber (features) + accent5: "EF4444", // Rose (ops) + accent6: "6366F1", // Indigo (timeline) + white: "FFFFFF", + border: "CBD5E1", +}; + +const FONT = { + heading: "Arial", + body: "Arial", +}; + +// ── Helpers ────────────────────────────────────────────────────────────── +function addSlideNumber(slide, num, total) { + slide.addText(`${num} / ${total}`, { + x: 8.8, y: 5.2, w: 1.2, h: 0.3, + fontSize: 8, color: C.textMuted, + fontFace: FONT.body, + align: "right", + }); +} + +function addAccentBar(slide, color) { + slide.addShape("rect", { + x: 0, y: 0, w: 10, h: 0.06, + fill: { color }, + }); +} + +function addLabel(slide, text, color, x, y) { + slide.addShape("roundRect", { + x, y, w: text.length * 0.09 + 0.4, h: 0.3, + fill: { color, transparency: 88 }, + rectRadius: 0.15, + }); + slide.addText(text.toUpperCase(), { + x, y, w: text.length * 0.09 + 0.4, h: 0.3, + fontSize: 7, fontFace: FONT.heading, bold: true, + color, align: "center", valign: "middle", + letterSpacing: 2, + }); +} + +function addCard(slide, opts) { + const { x, y, w, h, title, titleColor, items, badge } = opts; + // Card background + slide.addShape("roundRect", { + x, y, w, h, + fill: { color: C.bgCard }, + line: { color: C.border, width: 0.5 }, + rectRadius: 0.1, + }); + // Title + const titleText = badge + ? [{ text: title + " ", options: { bold: true, color: titleColor, fontSize: 11 } }, + { text: badge, options: { bold: true, color: C.white, fontSize: 7, highlight: titleColor } }] + : title; + slide.addText(titleText, { + x: x + 0.2, y: y + 0.08, w: w - 0.4, h: 0.35, + fontSize: 11, fontFace: FONT.heading, bold: true, + color: titleColor, + }); + // Items as bullet list + if (items && items.length > 0) { + slide.addText( + items.map(item => ({ + text: item, + options: { + fontSize: 8.5, fontFace: FONT.body, color: C.textSec, + bullet: { type: "bullet", style: "arabicPeriod" }, + paraSpaceAfter: 2, + breakLine: true, + }, + })), + { + x: x + 0.2, y: y + 0.4, w: w - 0.4, h: h - 0.5, + valign: "top", + bullet: { type: "bullet" }, + lineSpacingMultiple: 1.1, + } + ); + } +} + +// ── Build Presentation ────────────────────────────────────────────────── +async function build() { + const pptx = new PptxGenJS(); + pptx.layout = "LAYOUT_16x9"; + pptx.author = "Satya Suman Sari"; + pptx.company = "FortyTwo Platform"; + pptx.title = "Helix Engage — Weekly Update (Mar 18–25, 2026)"; + pptx.subject = "Engineering Progress Report"; + + const TOTAL = 9; + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 1 — Title + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + + // Accent bar top + addAccentBar(slide, C.accent1); + + // Decorative side stripe + slide.addShape("rect", { + x: 0, y: 0, w: 0.12, h: 5.63, + fill: { color: C.accent1 }, + }); + + // Label + addLabel(slide, "Weekly Engineering Update", C.accent1, 3.0, 1.2); + + // Title + slide.addText("Helix Engage", { + x: 1.0, y: 1.8, w: 8, h: 1.2, + fontSize: 44, fontFace: FONT.heading, bold: true, + color: C.accent1, align: "center", + }); + + // Subtitle + slide.addText("Contact Center CRM · Real-time Telephony · AI Copilot", { + x: 1.5, y: 2.9, w: 7, h: 0.5, + fontSize: 14, fontFace: FONT.body, + color: C.textSec, align: "center", + }); + + // Date + slide.addText("March 18 – 25, 2026", { + x: 3, y: 3.6, w: 4, h: 0.4, + fontSize: 12, fontFace: FONT.heading, bold: true, + color: C.textMuted, align: "center", + letterSpacing: 3, + }); + + // Bottom decoration + slide.addShape("rect", { + x: 3.5, y: 4.2, w: 3, h: 0.04, + fill: { color: C.accent2 }, + }); + + // Author + slide.addText("Satya Suman Sari · FortyTwo Platform", { + x: 2, y: 4.5, w: 6, h: 0.35, + fontSize: 9, fontFace: FONT.body, + color: C.textMuted, align: "center", + }); + + addSlideNumber(slide, 1, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 2 — At a Glance + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent2); + + addLabel(slide, "At a Glance", C.accent2, 0.5, 0.3); + + slide.addText("Week in Numbers", { + x: 0.5, y: 0.65, w: 5, h: 0.5, + fontSize: 24, fontFace: FONT.heading, bold: true, + color: C.text, + }); + + // Stat cards + const stats = [ + { value: "78", label: "Total Commits", color: C.accent1 }, + { value: "3", label: "Repositories", color: C.accent2 }, + { value: "8", label: "Days Active", color: C.accent3 }, + { value: "50", label: "Frontend Commits", color: C.accent4 }, + ]; + + stats.forEach((s, i) => { + const x = 0.5 + i * 2.35; + // Card bg + slide.addShape("roundRect", { + x, y: 1.3, w: 2.1, h: 1.7, + fill: { color: C.bgCard }, + line: { color: C.border, width: 0.5 }, + rectRadius: 0.12, + }); + // Accent top line + slide.addShape("rect", { + x: x + 0.2, y: 1.35, w: 1.7, h: 0.035, + fill: { color: s.color }, + }); + // Number + slide.addText(s.value, { + x, y: 1.5, w: 2.1, h: 0.9, + fontSize: 36, fontFace: FONT.heading, bold: true, + color: s.color, align: "center", valign: "middle", + }); + // Label + slide.addText(s.label, { + x, y: 2.4, w: 2.1, h: 0.4, + fontSize: 9, fontFace: FONT.body, + color: C.textSec, align: "center", + }); + }); + + // Repo breakdown pills + const repos = [ + { name: "helix-engage", count: "50", clr: C.accent1 }, + { name: "helix-engage-server", count: "27", clr: C.accent2 }, + { name: "FortyTwoApps/SDK", count: "1", clr: C.accent3 }, + ]; + repos.forEach((r, i) => { + const x = 1.5 + i * 2.8; + slide.addShape("roundRect", { + x, y: 3.4, w: 2.5, h: 0.4, + fill: { color: C.bgCard }, + line: { color: r.clr, width: 1 }, + rectRadius: 0.2, + }); + slide.addText(`${r.name} ${r.count}`, { + x, y: 3.4, w: 2.5, h: 0.4, + fontSize: 9, fontFace: FONT.heading, bold: true, + color: r.clr, align: "center", valign: "middle", + }); + }); + + // Summary text + slide.addText("3 repos · 7 working days · 78 commits shipped to production", { + x: 1, y: 4.2, w: 8, h: 0.35, + fontSize: 10, fontFace: FONT.body, italic: true, + color: C.textMuted, align: "center", + }); + + addSlideNumber(slide, 2, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 3 — Telephony & SIP + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent1); + + addLabel(slide, "Core Infrastructure", C.accent1, 0.5, 0.3); + + slide.addText([ + { text: "☎ ", options: { fontSize: 22 } }, + { text: "Telephony & SIP Overhaul", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 4.5, h: 2.0, + title: "Outbound Calling", titleColor: C.accent1, badge: "Frontend", + items: [ + "Direct SIP call from browser — no Kookoo bridge", + "Immediate call card UI with auto-answer SIP bridge", + "End Call label fix, force active state after auto-answer", + "Reset outboundPending on call end", + ], + }); + + addCard(slide, { + x: 5.2, y: 1.35, w: 4.5, h: 2.0, + title: "Ozonetel Integration", titleColor: C.accent2, badge: "Server", + items: [ + "Ozonetel V3 dial endpoint + webhook handler", + "Set Disposition API for ACW release", + "Force Ready endpoint for agent state mgmt", + "Token: 10-min cache, 401 invalidation, refresh on login", + ], + }); + + addCard(slide, { + x: 0.3, y: 3.55, w: 4.5, h: 1.8, + title: "SIP & Agent State", titleColor: C.accent1, badge: "Frontend", + items: [ + "SIP driven by Agent entity with token refresh", + "Centralised outbound dial into useSip().dialOutbound()", + "UCID tracking from SIP headers for disposition", + "Network indicator for connection health", + ], + }); + + addCard(slide, { + x: 5.2, y: 3.55, w: 4.5, h: 1.8, + title: "Multi-Agent & Sessions", titleColor: C.accent2, badge: "Server", + items: [ + "Multi-agent SIP with Redis session lockout", + "Strict duplicate login — one device per agent", + "Session lock stores IP + timestamp for debugging", + "SSE agent state broadcast for supervisor view", + ], + }); + + addSlideNumber(slide, 3, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 4 — Call Desk & Agent UX + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent3); + + addLabel(slide, "User Experience", C.accent3, 0.5, 0.3); + + slide.addText([ + { text: "🖥 ", options: { fontSize: 22 } }, + { text: "Call Desk & Agent UX", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 3.05, h: 2.6, + title: "Call Desk Redesign", titleColor: C.accent3, + items: [ + "2-panel layout with collapsible sidebar & inline AI", + "Collapsible context panel, worklist/calls tabs", + "Pinned header & chat input, numpad dialler", + "Ringtone support for incoming calls", + ], + }); + + addCard(slide, { + x: 3.55, y: 1.35, w: 3.05, h: 2.6, + title: "Post-Call Workflow", titleColor: C.accent3, + items: [ + "Disposition → appointment booking → follow-up", + "Disposition returns straight to worklist", + "Send disposition to sidecar with UCID for ACW", + "Enquiry in post-call, appointment skip button", + ], + }); + + addCard(slide, { + x: 6.8, y: 1.35, w: 2.9, h: 2.6, + title: "UI Polish", titleColor: C.accent3, + items: [ + "FontAwesome Pro Duotone icon migration", + "Tooltips, sticky headers, roles, search", + "Fix React error #520 in prod tables", + "AI scroll containment, brand tokens refresh", + ], + }); + + addSlideNumber(slide, 4, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 5 — Features Shipped + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent4); + + addLabel(slide, "Features Shipped", C.accent4, 0.5, 0.3); + + slide.addText([ + { text: "🚀 ", options: { fontSize: 22 } }, + { text: "Major Features", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 4.5, h: 2.0, + title: "Supervisor Module", titleColor: C.accent4, + items: [ + "Team performance analytics page", + "Live monitor with active calls visibility", + "Master data management pages", + "Server: team perf + active calls endpoints", + ], + }); + + addCard(slide, { + x: 5.2, y: 1.35, w: 4.5, h: 2.0, + title: "Missed Call Queue (Phase 2)", titleColor: C.accent4, + items: [ + "Missed call queue ingestion & worklist", + "Auto-assignment engine for agents", + "Login redesign with role-based routing", + "Lead lookup for missed callers", + ], + }); + + addCard(slide, { + x: 0.3, y: 3.55, w: 4.5, h: 1.8, + title: "Agent Features (Phase 1)", titleColor: C.accent4, + items: [ + "Agent status toggle (Ready / Not Ready / Break)", + "Global search across patients, leads, calls", + "Enquiry form for new patient intake", + "My Performance page + logout modal", + ], + }); + + addCard(slide, { + x: 5.2, y: 3.55, w: 4.5, h: 1.8, + title: "Recording Analysis", titleColor: C.accent4, + items: [ + "Deepgram diarization + AI insights", + "Redis caching layer for analysis results", + "Full-stack: frontend player + server module", + ], + }); + + addSlideNumber(slide, 5, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 6 — Backend & Data + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent2); + + addLabel(slide, "Backend & Data", C.accent2, 0.5, 0.3); + + slide.addText([ + { text: "⚙ ", options: { fontSize: 22 } }, + { text: "Backend & Data Layer", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 4.5, h: 2.0, + title: "Platform Data Wiring", titleColor: C.accent2, + items: [ + "Migrated frontend to Jotai + Vercel AI SDK", + "Corrected all 7 GraphQL queries (fields, LINKS/PHONES)", + "Webhook handler for Ozonetel call records", + "Complete seeder: 5 doctors, appointments linked", + ], + }); + + addCard(slide, { + x: 5.2, y: 1.35, w: 4.5, h: 2.0, + title: "Server Endpoints", titleColor: C.accent2, + items: [ + "Call control, recording, CDR, missed calls, live assist", + "Agent summary, AHT, performance aggregation", + "Token refresh endpoint for auto-renewal", + "Search module with full-text capabilities", + ], + }); + + addCard(slide, { + x: 0.3, y: 3.55, w: 4.5, h: 1.8, + title: "Data Pages Built", titleColor: C.accent2, + items: [ + "Worklist table, call history, patients, dashboard", + "Reports, team dashboard, campaigns, settings", + "Agent detail page, campaign edit slideout", + "Appointments page with data refresh on login", + ], + }); + + addCard(slide, { + x: 5.2, y: 3.55, w: 4.5, h: 1.8, + title: "SDK App", titleColor: C.accent3, badge: "FortyTwoApps", + items: [ + "Helix Engage SDK app entity definitions", + "Call center CRM object model for platform", + "Foundation for platform-native data integration", + ], + }); + + addSlideNumber(slide, 6, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 7 — Deployment & Ops + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent5); + + addLabel(slide, "Operations", C.accent5, 0.5, 0.3); + + slide.addText([ + { text: "🛠 ", options: { fontSize: 22 } }, + { text: "Deployment & DevOps", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + addCard(slide, { + x: 0.3, y: 1.35, w: 3.05, h: 2.2, + title: "Deployment", titleColor: C.accent5, + items: [ + "Deployed to Hostinger VPS with Docker", + "Switched to global_healthx Ozonetel account", + "Dockerfile for server-side containerization", + ], + }); + + addCard(slide, { + x: 3.55, y: 1.35, w: 3.05, h: 2.2, + title: "AI & Testing", titleColor: C.accent5, + items: [ + "Migrated AI to Vercel AI SDK + OpenAI provider", + "AI flow test script — validates full pipeline", + "Live call assist integration", + ], + }); + + addCard(slide, { + x: 6.8, y: 1.35, w: 2.9, h: 2.2, + title: "Documentation", titleColor: C.accent5, + items: [ + "Team onboarding README with arch guide", + "Supervisor module spec + plan", + "Multi-agent spec + plan", + "Next session plans in commits", + ], + }); + + addSlideNumber(slide, 7, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 8 — Timeline + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent6); + + addLabel(slide, "Day by Day", C.accent6, 0.5, 0.3); + + slide.addText([ + { text: "📅 ", options: { fontSize: 22 } }, + { text: "Development Timeline", options: { fontSize: 22, bold: true, color: C.text } }, + ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading }); + + const timeline = [ + { date: "MAR 18 (Tue)", title: "Foundation Day", desc: "Call desk redesign, Jotai + AI SDK migration, seeder, AI flow test, VPS deploy" }, + { date: "MAR 19 (Wed)", title: "Data Layer Sprint", desc: "All data pages, post-call workflow, GraphQL fixes, Kookoo IVR, outbound UI" }, + { date: "MAR 20 (Thu)", title: "Telephony Breakthrough", desc: "Direct SIP replacing Kookoo, UCID tracking, Force Ready, Set Disposition" }, + { date: "MAR 21 (Fri)", title: "Agent Experience", desc: "Phase 1: status toggle, search, enquiry form, My Performance, FA icons, AHT" }, + { date: "MAR 23 (Sun)", title: "Scale & Reliability", desc: "Phase 2: missed call queue, auto-assign, Redis lockout, Patient 360, SDK defs" }, + { date: "MAR 24 (Mon)", title: "Supervisor Module", desc: "Team perf, live monitor, master data, SSE, UUID fix, maintenance, QA sweep" }, + { date: "MAR 25 (Tue)", title: "Intelligence Layer", desc: "Deepgram diarization, AI insights, SIP via Agent entity, token refresh, network" }, + ]; + + // Vertical line + slide.addShape("rect", { + x: 1.4, y: 1.3, w: 0.025, h: 4.0, + fill: { color: C.accent6, transparency: 60 }, + }); + + timeline.forEach((entry, i) => { + const y = 1.3 + i * 0.56; + + // Dot + slide.addShape("ellipse", { + x: 1.32, y: y + 0.08, w: 0.18, h: 0.18, + fill: { color: C.accent6 }, + line: { color: C.bg, width: 2 }, + }); + + // Date + slide.addText(entry.date, { + x: 1.7, y: y, w: 1.6, h: 0.22, + fontSize: 7, fontFace: FONT.heading, bold: true, + color: C.accent6, + }); + + // Title + slide.addText(entry.title, { + x: 3.3, y: y, w: 2.0, h: 0.22, + fontSize: 9, fontFace: FONT.heading, bold: true, + color: C.text, + }); + + // Description + slide.addText(entry.desc, { + x: 5.3, y: y, w: 4.2, h: 0.45, + fontSize: 8, fontFace: FONT.body, + color: C.textSec, + valign: "top", + }); + }); + + addSlideNumber(slide, 8, TOTAL); + } + + // ═══════════════════════════════════════════════════════════════════════ + // SLIDE 9 — Closing + // ═══════════════════════════════════════════════════════════════════════ + { + const slide = pptx.addSlide(); + slide.background = { color: C.bg }; + addAccentBar(slide, C.accent3); + + // Big headline + slide.addText("78 commits. 8 days. Ship mode.", { + x: 0.5, y: 1.4, w: 9, h: 0.8, + fontSize: 32, fontFace: FONT.heading, bold: true, + color: C.accent3, align: "center", + }); + + // Ship emoji + slide.addText("🚢", { + x: 4.2, y: 2.3, w: 1.6, h: 0.6, + fontSize: 28, align: "center", + }); + + // Description + slide.addText( + "From browser-native SIP calling to AI-powered recording analysis — Helix Engage is becoming a production contact center platform.", + { + x: 1.5, y: 3.0, w: 7, h: 0.6, + fontSize: 11, fontFace: FONT.body, + color: C.textSec, align: "center", + lineSpacingMultiple: 1.3, + } + ); + + // Achievement pills + const achievements = [ + { text: "SIP Calling ✓", color: C.accent1 }, + { text: "Multi-Agent ✓", color: C.accent2 }, + { text: "Supervisor ✓", color: C.accent3 }, + { text: "AI Copilot ✓", color: C.accent4 }, + { text: "Recording Analysis ✓", color: C.accent5 }, + ]; + + achievements.forEach((a, i) => { + const x = 0.8 + i * 1.8; + slide.addShape("roundRect", { + x, y: 3.9, w: 1.6, h: 0.35, + fill: { color: C.bgCard }, + line: { color: a.color, width: 1 }, + rectRadius: 0.17, + }); + slide.addText(a.text, { + x, y: 3.9, w: 1.6, h: 0.35, + fontSize: 8, fontFace: FONT.heading, bold: true, + color: a.color, align: "center", valign: "middle", + }); + }); + + // Author + slide.addText("Satya Suman Sari · FortyTwo Platform", { + x: 2, y: 4.7, w: 6, h: 0.3, + fontSize: 9, fontFace: FONT.body, + color: C.textMuted, align: "center", + }); + + addSlideNumber(slide, 9, TOTAL); + } + + // ── Save ────────────────────────────────────────────────────────────── + const outPath = "weekly-update-mar18-25.pptx"; + await pptx.writeFile({ fileName: outPath }); + console.log(`✅ Presentation saved: ${outPath}`); +} + +build().catch(err => { + console.error("❌ Failed:", err.message); + process.exit(1); +}); diff --git a/docs/superpowers/plans/2026-03-31-csv-lead-import.md b/docs/superpowers/plans/2026-03-31-csv-lead-import.md new file mode 100644 index 0000000..151b74e --- /dev/null +++ b/docs/superpowers/plans/2026-03-31-csv-lead-import.md @@ -0,0 +1,735 @@ +# CSV Lead Import — Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Allow supervisors to import leads from CSV into an existing campaign via a modal wizard with column mapping and patient matching. + +**Architecture:** Client-side CSV parsing with a 3-step modal wizard (select campaign → upload/map/preview → import). Leads created via existing GraphQL proxy. No new sidecar endpoints needed. + +**Tech Stack:** React modal (Untitled UI), native FileReader + string split for CSV parsing, existing DataProvider for patient/lead matching, platform GraphQL mutations for lead creation. + +--- + +## File Map + +| File | Action | Responsibility | +|---|---|---| +| `src/lib/csv-utils.ts` | Create | CSV parsing, phone normalization, fuzzy column matching | +| `src/components/campaigns/lead-import-wizard.tsx` | Create | Modal wizard: campaign select → upload/preview → import | +| `src/pages/campaigns.tsx` | Modify | Add "Import Leads" button | + +--- + +### Task 1: CSV Parsing & Column Matching Utility + +**Files:** +- Create: `src/lib/csv-utils.ts` + +- [ ] **Step 1: Create csv-utils.ts with parseCSV function** + +```typescript +// src/lib/csv-utils.ts + +export type CSVRow = Record; + +export type CSVParseResult = { + headers: string[]; + rows: CSVRow[]; +}; + +export const parseCSV = (text: string): CSVParseResult => { + const lines = text.split(/\r?\n/).filter(line => line.trim()); + if (lines.length === 0) return { headers: [], rows: [] }; + + const parseLine = (line: string): string[] => { + const result: string[] = []; + let current = ''; + let inQuotes = false; + + for (let i = 0; i < line.length; i++) { + const char = line[i]; + if (char === '"') { + if (inQuotes && line[i + 1] === '"') { + current += '"'; + i++; + } else { + inQuotes = !inQuotes; + } + } else if (char === ',' && !inQuotes) { + result.push(current.trim()); + current = ''; + } else { + current += char; + } + } + result.push(current.trim()); + return result; + }; + + const headers = parseLine(lines[0]); + const rows = lines.slice(1).map(line => { + const values = parseLine(line); + const row: CSVRow = {}; + headers.forEach((header, i) => { + row[header] = values[i] ?? ''; + }); + return row; + }); + + return { headers, rows }; +}; +``` + +- [ ] **Step 2: Add normalizePhone function** + +```typescript +export const normalizePhone = (raw: string): string => { + const digits = raw.replace(/\D/g, ''); + const stripped = digits.length >= 12 && digits.startsWith('91') ? digits.slice(2) : digits; + return stripped.slice(-10); +}; +``` + +- [ ] **Step 3: Add fuzzy column matching** + +```typescript +export type LeadFieldMapping = { + csvHeader: string; + leadField: string | null; + label: string; +}; + +const LEAD_FIELDS = [ + { field: 'contactName.firstName', label: 'First Name', patterns: ['first name', 'firstname', 'name', 'patient name', 'patient'] }, + { field: 'contactName.lastName', label: 'Last Name', patterns: ['last name', 'lastname', 'surname'] }, + { field: 'contactPhone', label: 'Phone', patterns: ['phone', 'mobile', 'contact number', 'cell', 'phone number', 'mobile number'] }, + { field: 'contactEmail', label: 'Email', patterns: ['email', 'email address', 'mail'] }, + { field: 'interestedService', label: 'Interested Service', patterns: ['service', 'interested in', 'department', 'specialty', 'interest'] }, + { field: 'priority', label: 'Priority', patterns: ['priority', 'urgency'] }, + { field: 'utmSource', label: 'UTM Source', patterns: ['utm_source', 'utmsource', 'source'] }, + { field: 'utmMedium', label: 'UTM Medium', patterns: ['utm_medium', 'utmmedium', 'medium'] }, + { field: 'utmCampaign', label: 'UTM Campaign', patterns: ['utm_campaign', 'utmcampaign'] }, + { field: 'utmTerm', label: 'UTM Term', patterns: ['utm_term', 'utmterm', 'term'] }, + { field: 'utmContent', label: 'UTM Content', patterns: ['utm_content', 'utmcontent'] }, +]; + +export const fuzzyMatchColumns = (csvHeaders: string[]): LeadFieldMapping[] => { + const used = new Set(); + + return csvHeaders.map(header => { + const normalized = header.toLowerCase().trim().replace(/[^a-z0-9 ]/g, ''); + let bestMatch: string | null = null; + + for (const field of LEAD_FIELDS) { + if (used.has(field.field)) continue; + if (field.patterns.some(p => normalized === p || normalized.includes(p))) { + bestMatch = field.field; + used.add(field.field); + break; + } + } + + return { + csvHeader: header, + leadField: bestMatch, + label: bestMatch ? LEAD_FIELDS.find(f => f.field === bestMatch)!.label : '', + }; + }); +}; + +export { LEAD_FIELDS }; +``` + +- [ ] **Step 4: Add buildLeadPayload helper** + +```typescript +export const buildLeadPayload = ( + row: CSVRow, + mapping: LeadFieldMapping[], + campaignId: string, + patientId: string | null, + platform: string | null, +) => { + const getValue = (field: string): string => { + const entry = mapping.find(m => m.leadField === field); + return entry ? (row[entry.csvHeader] ?? '').trim() : ''; + }; + + const firstName = getValue('contactName.firstName') || 'Unknown'; + const lastName = getValue('contactName.lastName'); + const phone = normalizePhone(getValue('contactPhone')); + + if (!phone || phone.length < 10) return null; + + const sourceMap: Record = { + FACEBOOK: 'FACEBOOK_AD', + GOOGLE: 'GOOGLE_AD', + INSTAGRAM: 'INSTAGRAM', + MANUAL: 'OTHER', + }; + + return { + name: `${firstName} ${lastName}`.trim(), + contactName: { firstName, lastName }, + contactPhone: { primaryPhoneNumber: `+91${phone}` }, + ...(getValue('contactEmail') ? { contactEmail: { primaryEmail: getValue('contactEmail') } } : {}), + ...(getValue('interestedService') ? { interestedService: getValue('interestedService') } : {}), + ...(getValue('utmSource') ? { utmSource: getValue('utmSource') } : {}), + ...(getValue('utmMedium') ? { utmMedium: getValue('utmMedium') } : {}), + ...(getValue('utmCampaign') ? { utmCampaign: getValue('utmCampaign') } : {}), + ...(getValue('utmTerm') ? { utmTerm: getValue('utmTerm') } : {}), + ...(getValue('utmContent') ? { utmContent: getValue('utmContent') } : {}), + source: sourceMap[platform ?? ''] ?? 'OTHER', + status: 'NEW', + campaignId, + ...(patientId ? { patientId } : {}), + }; +}; +``` + +- [ ] **Step 5: Commit** + +```bash +git add src/lib/csv-utils.ts +git commit -m "feat: CSV parsing, phone normalization, and fuzzy column matching utility" +``` + +--- + +### Task 2: Lead Import Wizard Component + +**Files:** +- Create: `src/components/campaigns/lead-import-wizard.tsx` + +- [ ] **Step 1: Create wizard component with campaign selection step** + +```typescript +// src/components/campaigns/lead-import-wizard.tsx +import { useState, useMemo, useCallback } from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faFileImport, faCheck, faSpinner, faTriangleExclamation, faCloudArrowUp } from '@fortawesome/pro-duotone-svg-icons'; +import { Dialog, Modal, ModalOverlay } from '@/components/application/modals/modal'; +import { Button } from '@/components/base/buttons/button'; +import { Badge } from '@/components/base/badges/badges'; +import { Table } from '@/components/application/table/table'; +import { FeaturedIcon } from '@/components/foundations/featured-icon/featured-icon'; +import { Select } from '@/components/base/select/select'; +import { useData } from '@/providers/data-provider'; +import { apiClient } from '@/lib/api-client'; +import { parseCSV, fuzzyMatchColumns, buildLeadPayload, normalizePhone, LEAD_FIELDS, type LeadFieldMapping, type CSVRow } from '@/lib/csv-utils'; +import { cx } from '@/utils/cx'; +import type { Campaign } from '@/types/entities'; +import type { FC } from 'react'; + +const FileImportIcon: FC<{ className?: string }> = ({ className }) => ( + +); + +type ImportStep = 'select-campaign' | 'upload-preview' | 'importing' | 'done'; + +type ImportResult = { + created: number; + linkedToPatient: number; + skippedDuplicate: number; + skippedNoPhone: number; + failed: number; + total: number; +}; + +interface LeadImportWizardProps { + isOpen: boolean; + onOpenChange: (open: boolean) => void; +} + +export const LeadImportWizard = ({ isOpen, onOpenChange }: LeadImportWizardProps) => { + const { campaigns, leads, patients, refresh } = useData(); + const [step, setStep] = useState('select-campaign'); + const [selectedCampaign, setSelectedCampaign] = useState(null); + const [csvRows, setCsvRows] = useState([]); + const [csvHeaders, setCsvHeaders] = useState([]); + const [mapping, setMapping] = useState([]); + const [result, setResult] = useState(null); + const [importProgress, setImportProgress] = useState(0); + + const activeCampaigns = useMemo(() => + campaigns.filter(c => c.campaignStatus === 'ACTIVE' || c.campaignStatus === 'PAUSED'), + [campaigns], + ); + + const handleClose = () => { + onOpenChange(false); + // Reset state after close animation + setTimeout(() => { + setStep('select-campaign'); + setSelectedCampaign(null); + setCsvRows([]); + setCsvHeaders([]); + setMapping([]); + setResult(null); + setImportProgress(0); + }, 300); + }; + + const handleCampaignSelect = (campaign: Campaign) => { + setSelectedCampaign(campaign); + setStep('upload-preview'); + }; + + const handleFileUpload = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + + const reader = new FileReader(); + reader.onload = (event) => { + const text = event.target?.result as string; + const { headers, rows } = parseCSV(text); + setCsvHeaders(headers); + setCsvRows(rows); + setMapping(fuzzyMatchColumns(headers)); + }; + reader.readAsText(file); + }; + + const handleMappingChange = (csvHeader: string, leadField: string | null) => { + setMapping(prev => prev.map(m => + m.csvHeader === csvHeader ? { ...m, leadField, label: leadField ? LEAD_FIELDS.find(f => f.field === leadField)?.label ?? '' : '' } : m, + )); + }; + + // Patient matching for preview + const rowsWithMatch = useMemo(() => { + const phoneMapping = mapping.find(m => m.leadField === 'contactPhone'); + if (!phoneMapping || csvRows.length === 0) return []; + + const existingLeadPhones = new Set( + leads.map(l => normalizePhone(l.contactPhone?.[0]?.number ?? '')).filter(p => p.length === 10), + ); + + const patientByPhone = new Map( + patients + .filter(p => p.phones?.primaryPhoneNumber) + .map(p => [normalizePhone(p.phones!.primaryPhoneNumber), p]), + ); + + return csvRows.map(row => { + const rawPhone = row[phoneMapping.csvHeader] ?? ''; + const phone = normalizePhone(rawPhone); + const matchedPatient = phone.length === 10 ? patientByPhone.get(phone) : null; + const isDuplicate = phone.length === 10 && existingLeadPhones.has(phone); + const hasPhone = phone.length === 10; + + return { row, phone, matchedPatient, isDuplicate, hasPhone }; + }); + }, [csvRows, mapping, leads, patients]); + + const phoneIsMapped = mapping.some(m => m.leadField === 'contactPhone'); + const validCount = rowsWithMatch.filter(r => r.hasPhone && !r.isDuplicate).length; + const duplicateCount = rowsWithMatch.filter(r => r.isDuplicate).length; + const noPhoneCount = rowsWithMatch.filter(r => !r.hasPhone).length; + const patientMatchCount = rowsWithMatch.filter(r => r.matchedPatient).length; + + const handleImport = async () => { + if (!selectedCampaign) return; + setStep('importing'); + + const importResult: ImportResult = { created: 0, linkedToPatient: 0, skippedDuplicate: 0, skippedNoPhone: 0, failed: 0, total: rowsWithMatch.length }; + + for (let i = 0; i < rowsWithMatch.length; i++) { + const { row, isDuplicate, hasPhone, matchedPatient } = rowsWithMatch[i]; + + if (!hasPhone) { importResult.skippedNoPhone++; setImportProgress(i + 1); continue; } + if (isDuplicate) { importResult.skippedDuplicate++; setImportProgress(i + 1); continue; } + + const payload = buildLeadPayload(row, mapping, selectedCampaign.id, matchedPatient?.id ?? null, selectedCampaign.platform); + if (!payload) { importResult.skippedNoPhone++; setImportProgress(i + 1); continue; } + + try { + await apiClient.graphql( + `mutation($data: LeadCreateInput!) { createLead(data: $data) { id } }`, + { data: payload }, + { silent: true }, + ); + importResult.created++; + if (matchedPatient) importResult.linkedToPatient++; + } catch { + importResult.failed++; + } + + setImportProgress(i + 1); + } + + setResult(importResult); + setStep('done'); + refresh(); + }; + + // Available lead fields for mapping dropdown (exclude already-mapped ones) + const availableFields = useMemo(() => { + const usedFields = new Set(mapping.filter(m => m.leadField).map(m => m.leadField)); + return LEAD_FIELDS.map(f => ({ + id: f.field, + name: f.label, + isDisabled: usedFields.has(f.field), + })); + }, [mapping]); + + return ( + { if (!open) handleClose(); }}> + + + {() => ( +
+ {/* Header */} +
+
+ +
+

Import Leads

+

+ {step === 'select-campaign' && 'Select a campaign to import leads into'} + {step === 'upload-preview' && `Importing into: ${selectedCampaign?.campaignName}`} + {step === 'importing' && 'Importing leads...'} + {step === 'done' && 'Import complete'} +

+
+
+ +
+ + {/* Content */} +
+ + {/* Step 1: Campaign Cards */} + {step === 'select-campaign' && ( +
+ {activeCampaigns.length === 0 ? ( +

No active campaigns. Create a campaign first.

+ ) : ( + activeCampaigns.map(campaign => ( + + )) + )} +
+ )} + + {/* Step 2: Upload + Preview */} + {step === 'upload-preview' && ( +
+ {/* File upload */} + {csvRows.length === 0 ? ( + + ) : ( + <> + {/* Validation banner */} + {!phoneIsMapped && ( +
+ + Phone column must be mapped to proceed +
+ )} + + {/* Summary */} +
+ {csvRows.length} rows + {validCount} ready + {patientMatchCount > 0 && {patientMatchCount} existing patients} + {duplicateCount > 0 && {duplicateCount} duplicates} + {noPhoneCount > 0 && {noPhoneCount} no phone} +
+ + {/* Column mapping + preview table */} +
+ + {/* Mapping row */} + + + {mapping.map(m => ( + + ))} + + + + + {rowsWithMatch.slice(0, 20).map((item, i) => ( + + {mapping.map(m => ( + + ))} + + + ))} + +
+
+ {m.csvHeader} + +
+
+ Patient Match +
+ {item.row[m.csvHeader] ?? ''} + + {item.matchedPatient ? ( + + {item.matchedPatient.fullName?.firstName ?? 'Patient'} + + ) : item.isDuplicate ? ( + Duplicate + ) : !item.hasPhone ? ( + No phone + ) : ( + New + )} +
+ {csvRows.length > 20 && ( +
+ Showing 20 of {csvRows.length} rows +
+ )} +
+ + )} +
+ )} + + {/* Step 3: Importing */} + {step === 'importing' && ( +
+ +

Importing leads...

+

{importProgress} of {rowsWithMatch.length}

+
+
+
+
+ )} + + {/* Step 4: Done */} + {step === 'done' && result && ( +
+ } color="success" theme="light" size="lg" /> +

Import Complete

+
+
+

{result.created}

+

Created

+
+
+

{result.linkedToPatient}

+

Linked to Patients

+
+ {result.skippedDuplicate > 0 && ( +
+

{result.skippedDuplicate}

+

Duplicates

+
+ )} + {result.failed > 0 && ( +
+

{result.failed}

+

Failed

+
+ )} +
+
+ )} +
+ + {/* Footer */} +
+ {step === 'select-campaign' && ( + + )} + {step === 'upload-preview' && ( + <> + + + + )} + {step === 'done' && ( + + )} +
+
+ )} +
+
+
+ ); +}; +``` + +- [ ] **Step 2: Commit** + +```bash +git add src/components/campaigns/lead-import-wizard.tsx +git commit -m "feat: lead import wizard with campaign selection, CSV preview, and patient matching" +``` + +--- + +### Task 3: Add Import Button to Campaigns Page + +**Files:** +- Modify: `src/pages/campaigns.tsx` + +- [ ] **Step 1: Import LeadImportWizard and add state + button** + +Add import at top of `campaigns.tsx`: + +```typescript +import { LeadImportWizard } from '@/components/campaigns/lead-import-wizard'; +``` + +Add state inside `CampaignsPage` component: + +```typescript +const [importOpen, setImportOpen] = useState(false); +``` + +Add button next to the TopBar or in the header area. Replace the existing `TopBar` line: + +```typescript + +``` + +with: + +```typescript + + + +``` + +Add the import for `faFileImport`: + +```typescript +import { faPenToSquare, faFileImport } from '@fortawesome/pro-duotone-svg-icons'; +``` + +Add the wizard component before the closing `` of the return, after the CampaignEditSlideout: + +```typescript + +``` + +- [ ] **Step 2: Check if TopBar accepts children** + +Read `src/components/layout/top-bar.tsx` to verify it renders `children`. If not, place the button differently — inside the existing header div in campaigns.tsx. + +- [ ] **Step 3: Type check** + +Run: `npx tsc --noEmit --pretty` +Expected: Clean (no errors) + +- [ ] **Step 4: Build** + +Run: `npm run build` +Expected: Build succeeds + +- [ ] **Step 5: Commit** + +```bash +git add src/pages/campaigns.tsx +git commit -m "feat: add Import Leads button to campaigns page" +``` + +--- + +### Task 4: Integration Verification + +- [ ] **Step 1: Verify full build** + +```bash +npm run build +``` + +Expected: Build succeeds with no type errors. + +- [ ] **Step 2: Manual test checklist** + +1. Navigate to Campaigns page as admin +2. "Import Leads" button visible +3. Click → modal opens with campaign cards +4. Select a campaign → proceeds to upload step +5. Upload a test CSV → column mapping appears with fuzzy matches +6. Phone column auto-detected +7. Patient match column shows "Existing" or "New" badges +8. Duplicate leads highlighted +9. Click Import → progress bar → summary +10. Close modal → campaign lead count updated + +- [ ] **Step 3: Create a test CSV file for verification** + +```csv +First Name,Last Name,Phone,Email,Service,Priority +Ganesh,Bandi,8885540404,ganesh@email.com,Back Pain,HIGH +Meghana,,7702055204,meghana@email.com,Hair Loss,NORMAL +Priya,Sharma,9949879837,,Prenatal Care,NORMAL +New,Patient,9876500001,,General Checkup,LOW +``` + +- [ ] **Step 4: Final commit with test data** + +```bash +git add -A +git commit -m "feat: CSV lead import — complete wizard with campaign selection, mapping, and patient matching" +``` + +--- + +## Execution Notes + +- The wizard uses the existing `ModalOverlay`/`Modal`/`Dialog` pattern from Untitled UI (same as disposition modal) +- CSV parsing is native (no npm dependency) — handles quoted fields and commas +- Patient matching uses DataProvider data already in memory — no additional API calls for matching +- Lead creation uses existing GraphQL proxy — no new sidecar endpoint +- The `useData().refresh()` call after import updates all DataProvider consumers (campaign lead counts, lead master, etc.) diff --git a/docs/superpowers/plans/2026-03-31-rules-engine.md b/docs/superpowers/plans/2026-03-31-rules-engine.md new file mode 100644 index 0000000..a89839e --- /dev/null +++ b/docs/superpowers/plans/2026-03-31-rules-engine.md @@ -0,0 +1,1374 @@ +# Rules Engine — Implementation Plan (v2) + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Build a configurable rules engine in the sidecar with a Priority Rules UI that lets supervisors configure worklist scoring via sliders, replacing the hardcoded priority sort. + +**Architecture:** Self-contained NestJS module using `json-rules-engine` with Redis storage + JSON file backup. Priority config (weights/SLA) edited via supervisor UI. Automation rules schema defined but stubs only. + +**Tech Stack:** json-rules-engine, NestJS, Redis (ioredis), TypeScript, React + Untitled UI Slider + +**Sidecar path:** `helix-engage-server/src/rules-engine/` +**Frontend path:** `helix-engage/src/pages/rules-settings.tsx` + `src/components/rules/` + +**Spec:** `helix-engage/docs/superpowers/specs/2026-03-31-rules-engine-design.md` + +--- + +## File Map + +### Backend (helix-engage-server) +| File | Action | Responsibility | +|---|---|---| +| `package.json` | Modify | Add json-rules-engine | +| `src/rules-engine/types/rule.types.ts` | Create | Rule, RuleTrigger, RuleCondition, RuleAction, PriorityConfig | +| `src/rules-engine/types/fact.types.ts` | Create | FactProvider interface, computed facts | +| `src/rules-engine/types/action.types.ts` | Create | ActionHandler interface | +| `src/rules-engine/rules-storage.service.ts` | Create | Redis CRUD + JSON backup + PriorityConfig | +| `src/rules-engine/facts/lead-facts.provider.ts` | Create | Lead fact resolver | +| `src/rules-engine/facts/call-facts.provider.ts` | Create | Call/SLA facts + computeSlaMultiplier + computeSlaStatus | +| `src/rules-engine/facts/agent-facts.provider.ts` | Create | Agent fact resolver | +| `src/rules-engine/actions/score.action.ts` | Create | Priority scoring action | +| `src/rules-engine/actions/assign.action.ts` | Create | Stub | +| `src/rules-engine/actions/escalate.action.ts` | Create | Stub | +| `src/rules-engine/rules-engine.service.ts` | Create | json-rules-engine wrapper, evaluate, scoreWorklist | +| `src/rules-engine/rules-engine.controller.ts` | Create | REST API: CRUD + priority-config + evaluate + templates | +| `src/rules-engine/rules-engine.module.ts` | Create | NestJS module | +| `src/rules-engine/consumers/worklist.consumer.ts` | Create | Scoring integration | +| `src/rules-engine/templates/hospital-starter.json` | Create | Default rules + priority config | +| `src/app.module.ts` | Modify | Import RulesEngineModule | +| `src/worklist/worklist.service.ts` | Modify | Integrate scoring | +| `src/worklist/worklist.module.ts` | Modify | Import RulesEngineModule | + +### Frontend (helix-engage) +| File | Action | Responsibility | +|---|---|---| +| `src/pages/rules-settings.tsx` | Create | Supervisor rules settings page | +| `src/components/rules/priority-config-panel.tsx` | Create | Task weights + SLA sliders | +| `src/components/rules/campaign-weights-panel.tsx` | Create | Campaign weight sliders | +| `src/components/rules/source-weights-panel.tsx` | Create | Source weight sliders | +| `src/components/rules/worklist-preview.tsx` | Create | Live preview of scored worklist | +| `src/components/rules/weight-slider-row.tsx` | Create | Reusable slider row (label + slider + value) | +| `src/components/layout/sidebar.tsx` | Modify | Add Rules Settings nav item | +| `src/components/call-desk/worklist-panel.tsx` | Modify | Display scores + SLA dots | +| `src/lib/scoring.ts` | Create | Client-side scoring formula (shared for preview) | + +--- + +### Task 1: Install dependency + create types + +**Files:** +- Modify: `helix-engage-server/package.json` +- Create: `helix-engage-server/src/rules-engine/types/rule.types.ts` +- Create: `helix-engage-server/src/rules-engine/types/fact.types.ts` +- Create: `helix-engage-server/src/rules-engine/types/action.types.ts` + +- [ ] **Step 1: Install json-rules-engine** + +```bash +cd helix-engage-server && npm install json-rules-engine +``` + +- [ ] **Step 2: Create directory structure** + +```bash +mkdir -p src/rules-engine/{types,facts,actions,consumers,templates} +``` + +- [ ] **Step 3: Create rule.types.ts** + +```typescript +// src/rules-engine/types/rule.types.ts + +export type RuleType = 'priority' | 'automation'; + +export type RuleTrigger = + | { type: 'on_request'; request: 'worklist' | 'assignment' } + | { type: 'on_event'; event: string } + | { type: 'on_schedule'; interval: string } + | { type: 'always' }; + +export type RuleCategory = 'priority' | 'assignment' | 'escalation' | 'lifecycle' | 'qualification'; + +export type RuleOperator = + | 'equal' | 'notEqual' + | 'greaterThan' | 'greaterThanInclusive' + | 'lessThan' | 'lessThanInclusive' + | 'in' | 'notIn' + | 'contains' | 'doesNotContain' + | 'exists' | 'doesNotExist'; + +export type RuleCondition = { + fact: string; + operator: RuleOperator; + value: any; + path?: string; +}; + +export type RuleConditionGroup = { + all?: (RuleCondition | RuleConditionGroup)[]; + any?: (RuleCondition | RuleConditionGroup)[]; +}; + +export type RuleActionType = 'score' | 'assign' | 'escalate' | 'update' | 'notify'; + +export type ScoreActionParams = { + weight: number; + slaMultiplier?: boolean; + campaignMultiplier?: boolean; +}; + +export type AssignActionParams = { + agentId?: string; + agentPool?: string[]; + strategy: 'specific' | 'round-robin' | 'least-loaded' | 'skill-based'; +}; + +export type EscalateActionParams = { + channel: 'toast' | 'notification' | 'sms' | 'email'; + recipients: 'supervisor' | 'agent' | string[]; + message: string; + severity: 'warning' | 'critical'; +}; + +export type UpdateActionParams = { + entity: string; + field: string; + value: any; +}; + +export type RuleAction = { + type: RuleActionType; + params: ScoreActionParams | AssignActionParams | EscalateActionParams | UpdateActionParams; +}; + +export type Rule = { + id: string; + ruleType: RuleType; + name: string; + description?: string; + enabled: boolean; + priority: number; + trigger: RuleTrigger; + conditions: RuleConditionGroup; + action: RuleAction; + status?: 'draft' | 'published'; + metadata: { + createdAt: string; + updatedAt: string; + createdBy: string; + category: RuleCategory; + tags?: string[]; + }; +}; + +export type ScoreBreakdown = { + baseScore: number; + slaMultiplier: number; + campaignMultiplier: number; + rulesApplied: string[]; +}; + +export type ScoredItem = { + id: string; + score: number; + scoreBreakdown: ScoreBreakdown; + slaStatus: 'low' | 'medium' | 'high' | 'critical'; + slaElapsedPercent: number; +}; + +// Priority config — what the supervisor edits via sliders +export type TaskWeightConfig = { + weight: number; // 0-10 + slaMinutes: number; // SLA in minutes + enabled: boolean; +}; + +export type PriorityConfig = { + taskWeights: Record; + campaignWeights: Record; // campaignId → 0-10 + sourceWeights: Record; // leadSource → 0-10 +}; + +export const DEFAULT_PRIORITY_CONFIG: PriorityConfig = { + taskWeights: { + missed_call: { weight: 9, slaMinutes: 720, enabled: true }, + follow_up: { weight: 8, slaMinutes: 1440, enabled: true }, + campaign_lead: { weight: 7, slaMinutes: 2880, enabled: true }, + attempt_2: { weight: 6, slaMinutes: 1440, enabled: true }, + attempt_3: { weight: 4, slaMinutes: 2880, enabled: true }, + }, + campaignWeights: {}, + sourceWeights: { + WHATSAPP: 9, PHONE: 8, FACEBOOK_AD: 7, GOOGLE_AD: 7, + INSTAGRAM: 5, WEBSITE: 7, REFERRAL: 6, WALK_IN: 5, OTHER: 5, + }, +}; +``` + +- [ ] **Step 4: Create fact.types.ts** + +```typescript +// src/rules-engine/types/fact.types.ts + +export type FactValue = string | number | boolean | string[] | null; + +export type FactContext = { + lead?: Record; + call?: Record; + agent?: Record; + campaign?: Record; +}; + +export interface FactProvider { + name: string; + resolveFacts(entityData: any): Promise>; +} +``` + +- [ ] **Step 5: Create action.types.ts** + +```typescript +// src/rules-engine/types/action.types.ts + +import type { RuleAction } from './rule.types'; + +export interface ActionHandler { + type: string; + execute(action: RuleAction, context: Record): Promise; +} + +export type ActionResult = { + success: boolean; + data?: Record; + error?: string; +}; +``` + +- [ ] **Step 6: Commit** + +```bash +cd helix-engage-server +git add package.json package-lock.json src/rules-engine/types/ +git commit -m "feat: rules engine types — Rule, Fact, Action, PriorityConfig schemas" +``` + +--- + +### Task 2: Rules Storage Service + +**Files:** +- Create: `helix-engage-server/src/rules-engine/rules-storage.service.ts` + +- [ ] **Step 1: Create rules-storage.service.ts** + +```typescript +// src/rules-engine/rules-storage.service.ts + +import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import Redis from 'ioredis'; +import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs'; +import { dirname, join } from 'path'; +import { randomUUID } from 'crypto'; +import type { Rule, PriorityConfig } from './types/rule.types'; +import { DEFAULT_PRIORITY_CONFIG } from './types/rule.types'; + +const RULES_KEY = 'rules:config'; +const PRIORITY_CONFIG_KEY = 'rules:priority-config'; +const VERSION_KEY = 'rules:scores:version'; + +@Injectable() +export class RulesStorageService implements OnModuleInit { + private readonly logger = new Logger(RulesStorageService.name); + private readonly redis: Redis; + private readonly backupDir: string; + + constructor(private config: ConfigService) { + this.redis = new Redis(config.get('REDIS_URL') ?? 'redis://localhost:6379'); + this.backupDir = config.get('RULES_BACKUP_DIR') ?? join(process.cwd(), 'data'); + } + + async onModuleInit() { + // Restore rules from backup if Redis is empty + const existing = await this.redis.get(RULES_KEY); + if (!existing) { + const rulesBackup = join(this.backupDir, 'rules-config.json'); + if (existsSync(rulesBackup)) { + const data = readFileSync(rulesBackup, 'utf8'); + await this.redis.set(RULES_KEY, data); + this.logger.log(`Restored ${JSON.parse(data).length} rules from backup`); + } else { + await this.redis.set(RULES_KEY, '[]'); + this.logger.log('Initialized empty rules config'); + } + } + + // Restore priority config from backup if Redis is empty + const existingConfig = await this.redis.get(PRIORITY_CONFIG_KEY); + if (!existingConfig) { + const configBackup = join(this.backupDir, 'priority-config.json'); + if (existsSync(configBackup)) { + const data = readFileSync(configBackup, 'utf8'); + await this.redis.set(PRIORITY_CONFIG_KEY, data); + this.logger.log('Restored priority config from backup'); + } else { + await this.redis.set(PRIORITY_CONFIG_KEY, JSON.stringify(DEFAULT_PRIORITY_CONFIG)); + this.logger.log('Initialized default priority config'); + } + } + } + + // --- Priority Config --- + + async getPriorityConfig(): Promise { + const data = await this.redis.get(PRIORITY_CONFIG_KEY); + return data ? JSON.parse(data) : DEFAULT_PRIORITY_CONFIG; + } + + async updatePriorityConfig(config: PriorityConfig): Promise { + await this.redis.set(PRIORITY_CONFIG_KEY, JSON.stringify(config)); + await this.redis.incr(VERSION_KEY); + this.backupFile('priority-config.json', config); + return config; + } + + // --- Rules CRUD --- + + async getAll(): Promise { + const data = await this.redis.get(RULES_KEY); + return data ? JSON.parse(data) : []; + } + + async getById(id: string): Promise { + const rules = await this.getAll(); + return rules.find(r => r.id === id) ?? null; + } + + async getByTrigger(triggerType: string, triggerValue?: string): Promise { + const rules = await this.getAll(); + return rules.filter(r => { + if (!r.enabled) return false; + if (r.trigger.type !== triggerType) return false; + if (triggerValue && 'request' in r.trigger && r.trigger.request !== triggerValue) return false; + if (triggerValue && 'event' in r.trigger && r.trigger.event !== triggerValue) return false; + return true; + }).sort((a, b) => a.priority - b.priority); + } + + async create(rule: Omit & { createdBy?: string }): Promise { + const rules = await this.getAll(); + const newRule: Rule = { + ...rule, + id: randomUUID(), + metadata: { + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + createdBy: rule.createdBy ?? 'system', + category: this.inferCategory(rule.action.type), + tags: [], + }, + }; + rules.push(newRule); + await this.saveRules(rules); + return newRule; + } + + async update(id: string, updates: Partial): Promise { + const rules = await this.getAll(); + const index = rules.findIndex(r => r.id === id); + if (index === -1) return null; + rules[index] = { + ...rules[index], + ...updates, + id, + metadata: { ...rules[index].metadata, updatedAt: new Date().toISOString(), ...(updates.metadata ?? {}) }, + }; + await this.saveRules(rules); + return rules[index]; + } + + async delete(id: string): Promise { + const rules = await this.getAll(); + const filtered = rules.filter(r => r.id !== id); + if (filtered.length === rules.length) return false; + await this.saveRules(filtered); + return true; + } + + async toggle(id: string): Promise { + const rule = await this.getById(id); + if (!rule) return null; + return this.update(id, { enabled: !rule.enabled }); + } + + async reorder(ids: string[]): Promise { + const rules = await this.getAll(); + const reorderedIds = new Set(ids); + const reordered = ids.map((id, i) => { + const rule = rules.find(r => r.id === id); + if (rule) rule.priority = i; + return rule; + }).filter(Boolean) as Rule[]; + const remaining = rules.filter(r => !reorderedIds.has(r.id)); + const final = [...reordered, ...remaining]; + await this.saveRules(final); + return final; + } + + async getVersion(): Promise { + const v = await this.redis.get(VERSION_KEY); + return v ? parseInt(v, 10) : 0; + } + + // --- Internal --- + + private async saveRules(rules: Rule[]) { + const json = JSON.stringify(rules, null, 2); + await this.redis.set(RULES_KEY, json); + await this.redis.incr(VERSION_KEY); + this.backupFile('rules-config.json', rules); + } + + private backupFile(filename: string, data: any) { + try { + if (!existsSync(this.backupDir)) mkdirSync(this.backupDir, { recursive: true }); + writeFileSync(join(this.backupDir, filename), JSON.stringify(data, null, 2), 'utf8'); + } catch (err) { + this.logger.warn(`Failed to write backup ${filename}: ${err}`); + } + } + + private inferCategory(actionType: string): Rule['metadata']['category'] { + switch (actionType) { + case 'score': return 'priority'; + case 'assign': return 'assignment'; + case 'escalate': return 'escalation'; + case 'update': return 'lifecycle'; + default: return 'priority'; + } + } +} +``` + +- [ ] **Step 2: Commit** + +```bash +git add src/rules-engine/rules-storage.service.ts +git commit -m "feat: rules storage service — Redis + JSON backup + PriorityConfig" +``` + +--- + +### Task 3: Fact Providers + +**Files:** +- Create: `helix-engage-server/src/rules-engine/facts/lead-facts.provider.ts` +- Create: `helix-engage-server/src/rules-engine/facts/call-facts.provider.ts` +- Create: `helix-engage-server/src/rules-engine/facts/agent-facts.provider.ts` + +- [ ] **Step 1: Create lead-facts.provider.ts** + +```typescript +// src/rules-engine/facts/lead-facts.provider.ts + +import type { FactProvider, FactValue } from '../types/fact.types'; + +export class LeadFactsProvider implements FactProvider { + name = 'lead'; + + async resolveFacts(lead: any): Promise> { + const createdAt = lead.createdAt ? new Date(lead.createdAt).getTime() : Date.now(); + const lastContacted = lead.lastContacted ? new Date(lead.lastContacted).getTime() : null; + + return { + 'lead.source': lead.leadSource ?? lead.source ?? null, + 'lead.status': lead.leadStatus ?? lead.status ?? null, + 'lead.priority': lead.priority ?? 'NORMAL', + 'lead.campaignId': lead.campaignId ?? null, + 'lead.campaignName': lead.campaignName ?? null, + 'lead.interestedService': lead.interestedService ?? null, + 'lead.contactAttempts': lead.contactAttempts ?? 0, + 'lead.ageMinutes': Math.round((Date.now() - createdAt) / 60000), + 'lead.ageDays': Math.round((Date.now() - createdAt) / 86400000), + 'lead.lastContactedMinutes': lastContacted ? Math.round((Date.now() - lastContacted) / 60000) : null, + 'lead.hasPatient': !!lead.patientId, + 'lead.isDuplicate': lead.isDuplicate ?? false, + 'lead.isSpam': lead.isSpam ?? false, + 'lead.spamScore': lead.spamScore ?? 0, + 'lead.leadScore': lead.leadScore ?? 0, + }; + } +} +``` + +- [ ] **Step 2: Create call-facts.provider.ts** + +```typescript +// src/rules-engine/facts/call-facts.provider.ts + +import type { FactProvider, FactValue } from '../types/fact.types'; +import type { PriorityConfig } from '../types/rule.types'; + +export class CallFactsProvider implements FactProvider { + name = 'call'; + + async resolveFacts(call: any, priorityConfig?: PriorityConfig): Promise> { + const taskType = this.inferTaskType(call); + const slaMinutes = priorityConfig?.taskWeights[taskType]?.slaMinutes ?? 1440; + const createdAt = call.createdAt ? new Date(call.createdAt).getTime() : Date.now(); + const elapsedMinutes = Math.round((Date.now() - createdAt) / 60000); + const slaElapsedPercent = Math.round((elapsedMinutes / slaMinutes) * 100); + + return { + 'call.direction': call.callDirection ?? call.direction ?? null, + 'call.status': call.callStatus ?? null, + 'call.disposition': call.disposition ?? null, + 'call.durationSeconds': call.durationSeconds ?? call.durationSec ?? 0, + 'call.callbackStatus': call.callbackstatus ?? call.callbackStatus ?? null, + 'call.slaElapsedPercent': slaElapsedPercent, + 'call.slaBreached': slaElapsedPercent > 100, + 'call.missedCount': call.missedcallcount ?? call.missedCount ?? 0, + 'call.taskType': taskType, + }; + } + + private inferTaskType(call: any): string { + if (call.callStatus === 'MISSED' || call.type === 'missed') return 'missed_call'; + if (call.followUpType === 'CALLBACK' || call.type === 'callback') return 'follow_up'; + if (call.type === 'follow-up') return 'follow_up'; + if (call.contactAttempts >= 3) return 'attempt_3'; + if (call.contactAttempts >= 2) return 'attempt_2'; + if (call.campaignId || call.type === 'lead') return 'campaign_lead'; + return 'campaign_lead'; + } +} + +// Exported scoring functions — used by both sidecar and frontend (via scoring.ts) +export function computeSlaMultiplier(slaElapsedPercent: number): number { + const elapsed = slaElapsedPercent / 100; + if (elapsed > 1) return 1.0 + (elapsed - 1) * 0.5; + return Math.pow(elapsed, 1.6); +} + +export function computeSlaStatus(slaElapsedPercent: number): 'low' | 'medium' | 'high' | 'critical' { + if (slaElapsedPercent > 100) return 'critical'; + if (slaElapsedPercent >= 80) return 'high'; + if (slaElapsedPercent >= 50) return 'medium'; + return 'low'; +} +``` + +- [ ] **Step 3: Create agent-facts.provider.ts** + +```typescript +// src/rules-engine/facts/agent-facts.provider.ts + +import type { FactProvider, FactValue } from '../types/fact.types'; + +export class AgentFactsProvider implements FactProvider { + name = 'agent'; + + async resolveFacts(agent: any): Promise> { + return { + 'agent.status': agent.status ?? 'OFFLINE', + 'agent.activeCallCount': agent.activeCallCount ?? 0, + 'agent.todayCallCount': agent.todayCallCount ?? 0, + 'agent.skills': agent.skills ?? [], + 'agent.campaigns': agent.campaigns ?? [], + 'agent.idleMinutes': agent.idleMinutes ?? 0, + }; + } +} +``` + +- [ ] **Step 4: Commit** + +```bash +git add src/rules-engine/facts/ +git commit -m "feat: fact providers — lead, call (with SLA), agent resolvers" +``` + +--- + +### Task 4: Action Handlers + Hospital Starter Template + +**Files:** +- Create: `helix-engage-server/src/rules-engine/actions/score.action.ts` +- Create: `helix-engage-server/src/rules-engine/actions/assign.action.ts` +- Create: `helix-engage-server/src/rules-engine/actions/escalate.action.ts` +- Create: `helix-engage-server/src/rules-engine/templates/hospital-starter.json` + +- [ ] **Step 1: Create score.action.ts** + +```typescript +// src/rules-engine/actions/score.action.ts + +import type { ActionHandler, ActionResult } from '../types/action.types'; +import type { RuleAction, ScoreActionParams } from '../types/rule.types'; +import { computeSlaMultiplier } from '../facts/call-facts.provider'; + +export class ScoreActionHandler implements ActionHandler { + type = 'score'; + + async execute(action: RuleAction, context: Record): Promise { + const params = action.params as ScoreActionParams; + let score = params.weight; + let slaApplied = false; + let campaignApplied = false; + + if (params.slaMultiplier && context['call.slaElapsedPercent'] != null) { + score *= computeSlaMultiplier(context['call.slaElapsedPercent']); + slaApplied = true; + } + + if (params.campaignMultiplier) { + const campaignWeight = (context['_campaignWeight'] ?? 5) / 10; + const sourceWeight = (context['_sourceWeight'] ?? 5) / 10; + score *= campaignWeight * sourceWeight; + campaignApplied = true; + } + + return { + success: true, + data: { score, weight: params.weight, slaApplied, campaignApplied }, + }; + } +} +``` + +- [ ] **Step 2: Create stub handlers** + +```typescript +// src/rules-engine/actions/assign.action.ts + +import type { ActionHandler, ActionResult } from '../types/action.types'; +import type { RuleAction } from '../types/rule.types'; + +export class AssignActionHandler implements ActionHandler { + type = 'assign'; + + async execute(_action: RuleAction, _context: Record): Promise { + return { success: true, data: { stub: true, action: 'assign' } }; + } +} +``` + +```typescript +// src/rules-engine/actions/escalate.action.ts + +import type { ActionHandler, ActionResult } from '../types/action.types'; +import type { RuleAction } from '../types/rule.types'; + +export class EscalateActionHandler implements ActionHandler { + type = 'escalate'; + + async execute(_action: RuleAction, _context: Record): Promise { + return { success: true, data: { stub: true, action: 'escalate' } }; + } +} +``` + +- [ ] **Step 3: Create hospital-starter.json** + +```json +{ + "priorityConfig": { + "taskWeights": { + "missed_call": { "weight": 9, "slaMinutes": 720, "enabled": true }, + "follow_up": { "weight": 8, "slaMinutes": 1440, "enabled": true }, + "campaign_lead": { "weight": 7, "slaMinutes": 2880, "enabled": true }, + "attempt_2": { "weight": 6, "slaMinutes": 1440, "enabled": true }, + "attempt_3": { "weight": 4, "slaMinutes": 2880, "enabled": true } + }, + "campaignWeights": {}, + "sourceWeights": { + "WHATSAPP": 9, "PHONE": 8, "FACEBOOK_AD": 7, "GOOGLE_AD": 7, + "INSTAGRAM": 5, "WEBSITE": 7, "REFERRAL": 6, "WALK_IN": 5, "OTHER": 5 + } + }, + "rules": [ + { + "ruleType": "priority", + "name": "Missed calls — high urgency", + "description": "Missed calls get highest priority with SLA-based urgency", + "enabled": true, + "priority": 1, + "trigger": { "type": "on_request", "request": "worklist" }, + "conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "missed_call" }] }, + "action": { "type": "score", "params": { "weight": 9, "slaMultiplier": true } } + }, + { + "ruleType": "priority", + "name": "Scheduled follow-ups", + "description": "Committed callbacks from prior calls", + "enabled": true, + "priority": 2, + "trigger": { "type": "on_request", "request": "worklist" }, + "conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "follow_up" }] }, + "action": { "type": "score", "params": { "weight": 8, "slaMultiplier": true } } + }, + { + "ruleType": "priority", + "name": "Campaign leads — weighted", + "description": "Outbound campaign calls, weighted by campaign importance", + "enabled": true, + "priority": 3, + "trigger": { "type": "on_request", "request": "worklist" }, + "conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "campaign_lead" }] }, + "action": { "type": "score", "params": { "weight": 7, "slaMultiplier": true, "campaignMultiplier": true } } + }, + { + "ruleType": "priority", + "name": "2nd attempt — medium urgency", + "description": "First call went unanswered, try again", + "enabled": true, + "priority": 4, + "trigger": { "type": "on_request", "request": "worklist" }, + "conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "attempt_2" }] }, + "action": { "type": "score", "params": { "weight": 6, "slaMultiplier": true } } + }, + { + "ruleType": "priority", + "name": "3rd attempt — lower urgency", + "description": "Two prior unanswered attempts", + "enabled": true, + "priority": 5, + "trigger": { "type": "on_request", "request": "worklist" }, + "conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "attempt_3" }] }, + "action": { "type": "score", "params": { "weight": 4, "slaMultiplier": true } } + }, + { + "ruleType": "priority", + "name": "Spam leads — deprioritize", + "description": "High spam score leads get pushed down", + "enabled": true, + "priority": 10, + "trigger": { "type": "on_request", "request": "worklist" }, + "conditions": { "all": [{ "fact": "lead.spamScore", "operator": "greaterThan", "value": 60 }] }, + "action": { "type": "score", "params": { "weight": -3 } } + }, + { + "ruleType": "automation", + "name": "SLA breach — escalate to supervisor", + "description": "Alert supervisor when callback SLA is breached", + "enabled": true, + "priority": 1, + "status": "draft", + "trigger": { "type": "on_schedule", "interval": "5m" }, + "conditions": { "all": [{ "fact": "call.slaBreached", "operator": "equal", "value": true }, { "fact": "call.callbackStatus", "operator": "equal", "value": "PENDING_CALLBACK" }] }, + "action": { "type": "escalate", "params": { "channel": "notification", "recipients": "supervisor", "message": "SLA breached — no callback attempted", "severity": "critical" } } + } + ] +} +``` + +- [ ] **Step 4: Commit** + +```bash +git add src/rules-engine/actions/ src/rules-engine/templates/ +git commit -m "feat: action handlers (score + stubs) + hospital starter template" +``` + +--- + +### Task 5: Rules Engine Service (Core) + +**Files:** +- Create: `helix-engage-server/src/rules-engine/rules-engine.service.ts` + +- [ ] **Step 1: Create rules-engine.service.ts** + +```typescript +// src/rules-engine/rules-engine.service.ts + +import { Injectable, Logger } from '@nestjs/common'; +import { Engine } from 'json-rules-engine'; +import { RulesStorageService } from './rules-storage.service'; +import { LeadFactsProvider } from './facts/lead-facts.provider'; +import { CallFactsProvider, computeSlaMultiplier, computeSlaStatus } from './facts/call-facts.provider'; +import { AgentFactsProvider } from './facts/agent-facts.provider'; +import { ScoreActionHandler } from './actions/score.action'; +import { AssignActionHandler } from './actions/assign.action'; +import { EscalateActionHandler } from './actions/escalate.action'; +import type { Rule, ScoredItem, ScoreBreakdown, PriorityConfig } from './types/rule.types'; +import type { ActionHandler } from './types/action.types'; + +@Injectable() +export class RulesEngineService { + private readonly logger = new Logger(RulesEngineService.name); + private readonly leadFacts = new LeadFactsProvider(); + private readonly callFacts = new CallFactsProvider(); + private readonly agentFacts = new AgentFactsProvider(); + private readonly actionHandlers: Map; + + constructor(private readonly storage: RulesStorageService) { + this.actionHandlers = new Map([ + ['score', new ScoreActionHandler()], + ['assign', new AssignActionHandler()], + ['escalate', new EscalateActionHandler()], + ]); + } + + async evaluate(triggerType: string, triggerValue: string, factContext: Record): Promise<{ rulesApplied: string[]; results: any[] }> { + const rules = await this.storage.getByTrigger(triggerType, triggerValue); + if (rules.length === 0) return { rulesApplied: [], results: [] }; + + const engine = new Engine(); + const ruleMap = new Map(); + + for (const rule of rules) { + engine.addRule({ + conditions: rule.conditions, + event: { type: rule.action.type, params: { ruleId: rule.id, ...rule.action.params } }, + priority: rule.priority, + }); + ruleMap.set(rule.id, rule); + } + + for (const [key, value] of Object.entries(factContext)) { + engine.addFact(key, value); + } + + const { events } = await engine.run(); + const results: any[] = []; + const rulesApplied: string[] = []; + + for (const event of events) { + const ruleId = event.params?.ruleId; + const rule = ruleMap.get(ruleId); + if (!rule) continue; + const handler = this.actionHandlers.get(event.type); + if (handler) { + const result = await handler.execute(rule.action, factContext); + results.push({ ruleId, ruleName: rule.name, ...result }); + rulesApplied.push(rule.name); + } + } + + return { rulesApplied, results }; + } + + async scoreWorklistItem(item: any, priorityConfig: PriorityConfig): Promise { + const leadFacts = await this.leadFacts.resolveFacts(item.originalLead ?? item); + const callFacts = await this.callFacts.resolveFacts(item, priorityConfig); + const taskType = callFacts['call.taskType'] as string; + + // Inject priority config weights into context for the score action + const campaignWeight = item.campaignId ? (priorityConfig.campaignWeights[item.campaignId] ?? 5) : 5; + const sourceWeight = priorityConfig.sourceWeights[leadFacts['lead.source'] as string] ?? 5; + + const allFacts = { + ...leadFacts, + ...callFacts, + '_campaignWeight': campaignWeight, + '_sourceWeight': sourceWeight, + }; + + const { rulesApplied, results } = await this.evaluate('on_request', 'worklist', allFacts); + + let totalScore = 0; + let slaMultiplierVal = 1; + let campaignMultiplierVal = 1; + + for (const result of results) { + if (result.success && result.data?.score != null) { + totalScore += result.data.score; + if (result.data.slaApplied) slaMultiplierVal = computeSlaMultiplier((allFacts['call.slaElapsedPercent'] as number) ?? 0); + if (result.data.campaignApplied) campaignMultiplierVal = (campaignWeight / 10) * (sourceWeight / 10); + } + } + + const slaElapsedPercent = (allFacts['call.slaElapsedPercent'] as number) ?? 0; + + return { + id: item.id, + score: Math.round(totalScore * 100) / 100, + scoreBreakdown: { + baseScore: totalScore, + slaMultiplier: Math.round(slaMultiplierVal * 100) / 100, + campaignMultiplier: Math.round(campaignMultiplierVal * 100) / 100, + rulesApplied, + }, + slaStatus: computeSlaStatus(slaElapsedPercent), + slaElapsedPercent, + }; + } + + async scoreWorklist(items: any[]): Promise<(any & ScoredItem)[]> { + const priorityConfig = await this.storage.getPriorityConfig(); + const scored = await Promise.all( + items.map(async (item) => { + const scoreData = await this.scoreWorklistItem(item, priorityConfig); + return { ...item, ...scoreData }; + }), + ); + scored.sort((a, b) => b.score - a.score); + return scored; + } + + async previewScoring(items: any[], config: PriorityConfig): Promise<(any & ScoredItem)[]> { + // Same as scoreWorklist but uses provided config (for live preview) + const scored = await Promise.all( + items.map(async (item) => { + const scoreData = await this.scoreWorklistItem(item, config); + return { ...item, ...scoreData }; + }), + ); + scored.sort((a, b) => b.score - a.score); + return scored; + } +} +``` + +- [ ] **Step 2: Commit** + +```bash +git add src/rules-engine/rules-engine.service.ts +git commit -m "feat: rules engine service — scoring, evaluation, live preview" +``` + +--- + +### Task 6: Controller + Module + Worklist Integration + +**Files:** +- Create: `helix-engage-server/src/rules-engine/rules-engine.controller.ts` +- Create: `helix-engage-server/src/rules-engine/rules-engine.module.ts` +- Create: `helix-engage-server/src/rules-engine/consumers/worklist.consumer.ts` +- Modify: `helix-engage-server/src/app.module.ts` +- Modify: `helix-engage-server/src/worklist/worklist.service.ts` +- Modify: `helix-engage-server/src/worklist/worklist.module.ts` + +- [ ] **Step 1: Create rules-engine.controller.ts** + +```typescript +// src/rules-engine/rules-engine.controller.ts + +import { Controller, Get, Post, Put, Delete, Patch, Param, Body, HttpException, Logger } from '@nestjs/common'; +import { RulesStorageService } from './rules-storage.service'; +import { RulesEngineService } from './rules-engine.service'; +import type { Rule, PriorityConfig } from './types/rule.types'; +import { readFileSync } from 'fs'; +import { join } from 'path'; + +@Controller('api/rules') +export class RulesEngineController { + private readonly logger = new Logger(RulesEngineController.name); + + constructor( + private readonly storage: RulesStorageService, + private readonly engine: RulesEngineService, + ) {} + + // --- Priority Config (slider UI) --- + + @Get('priority-config') + async getPriorityConfig() { + return this.storage.getPriorityConfig(); + } + + @Put('priority-config') + async updatePriorityConfig(@Body() body: PriorityConfig) { + return this.storage.updatePriorityConfig(body); + } + + // --- Rule CRUD --- + + @Get() + async listRules() { + return this.storage.getAll(); + } + + @Get(':id') + async getRule(@Param('id') id: string) { + const rule = await this.storage.getById(id); + if (!rule) throw new HttpException('Rule not found', 404); + return rule; + } + + @Post() + async createRule(@Body() body: any) { + if (!body.name || !body.trigger || !body.conditions || !body.action) { + throw new HttpException('name, trigger, conditions, and action are required', 400); + } + return this.storage.create({ + ...body, + ruleType: body.ruleType ?? 'priority', + enabled: body.enabled ?? true, + priority: body.priority ?? 99, + }); + } + + @Put(':id') + async updateRule(@Param('id') id: string, @Body() body: Partial) { + const updated = await this.storage.update(id, body); + if (!updated) throw new HttpException('Rule not found', 404); + return updated; + } + + @Delete(':id') + async deleteRule(@Param('id') id: string) { + const deleted = await this.storage.delete(id); + if (!deleted) throw new HttpException('Rule not found', 404); + return { status: 'ok' }; + } + + @Patch(':id/toggle') + async toggleRule(@Param('id') id: string) { + const toggled = await this.storage.toggle(id); + if (!toggled) throw new HttpException('Rule not found', 404); + return toggled; + } + + @Post('reorder') + async reorderRules(@Body() body: { ids: string[] }) { + if (!body.ids?.length) throw new HttpException('ids array required', 400); + return this.storage.reorder(body.ids); + } + + // --- Evaluation --- + + @Post('evaluate') + async evaluate(@Body() body: { trigger: string; triggerValue: string; facts: Record }) { + return this.engine.evaluate(body.trigger, body.triggerValue, body.facts); + } + + // --- Templates --- + + @Get('templates/list') + async listTemplates() { + return [{ id: 'hospital-starter', name: 'Hospital Starter Pack', description: 'Default rules for a hospital call center', ruleCount: 7 }]; + } + + @Post('templates/:id/apply') + async applyTemplate(@Param('id') id: string) { + if (id !== 'hospital-starter') throw new HttpException('Template not found', 404); + + let template: any; + try { + template = JSON.parse(readFileSync(join(__dirname, 'templates', 'hospital-starter.json'), 'utf8')); + } catch { + throw new HttpException('Failed to load template', 500); + } + + // Apply priority config + await this.storage.updatePriorityConfig(template.priorityConfig); + + // Create rules + const created: Rule[] = []; + for (const rule of template.rules) { + const newRule = await this.storage.create(rule); + created.push(newRule); + } + + this.logger.log(`Applied hospital-starter template: ${created.length} rules + priority config`); + return { status: 'ok', rulesCreated: created.length, rules: created }; + } +} +``` + +- [ ] **Step 2: Create rules-engine.module.ts** + +```typescript +// src/rules-engine/rules-engine.module.ts + +import { Module } from '@nestjs/common'; +import { RulesEngineController } from './rules-engine.controller'; +import { RulesEngineService } from './rules-engine.service'; +import { RulesStorageService } from './rules-storage.service'; +import { WorklistConsumer } from './consumers/worklist.consumer'; + +@Module({ + controllers: [RulesEngineController], + providers: [RulesEngineService, RulesStorageService, WorklistConsumer], + exports: [RulesEngineService, RulesStorageService, WorklistConsumer], +}) +export class RulesEngineModule {} +``` + +- [ ] **Step 3: Create worklist.consumer.ts** + +```typescript +// src/rules-engine/consumers/worklist.consumer.ts + +import { Injectable, Logger } from '@nestjs/common'; +import { RulesEngineService } from '../rules-engine.service'; +import { RulesStorageService } from '../rules-storage.service'; + +@Injectable() +export class WorklistConsumer { + private readonly logger = new Logger(WorklistConsumer.name); + + constructor( + private readonly engine: RulesEngineService, + private readonly storage: RulesStorageService, + ) {} + + async scoreAndRank(worklistItems: any[]): Promise { + const rules = await this.storage.getByTrigger('on_request', 'worklist'); + if (rules.length === 0) { + this.logger.debug('No scoring rules configured — returning unsorted'); + return worklistItems; + } + this.logger.debug(`Scoring ${worklistItems.length} items with ${rules.length} rules`); + return this.engine.scoreWorklist(worklistItems); + } +} +``` + +- [ ] **Step 4: Register in app.module.ts** + +Add import and register `RulesEngineModule` in the imports array of `src/app.module.ts`. + +- [ ] **Step 5: Integrate into WorklistService** + +Inject `WorklistConsumer` into `WorklistService`. After fetching the 3 arrays (missedCalls, followUps, marketingLeads), combine into a flat array with a `type` field, score via the consumer, then split back into the 3 categories for the response. Add scoring fields to each item. + +- [ ] **Step 6: Update WorklistModule imports** + +Add `RulesEngineModule` to `WorklistModule` imports. + +- [ ] **Step 7: Build and verify** + +```bash +cd helix-engage-server && npm run build +``` + +- [ ] **Step 8: Commit** + +```bash +git add src/rules-engine/ src/worklist/ src/app.module.ts +git commit -m "feat: rules engine module + controller + worklist scoring integration" +``` + +--- + +### Task 7: Client-Side Scoring Library + +**Files:** +- Create: `helix-engage/src/lib/scoring.ts` + +Shared scoring formula for the frontend live preview. Must match the sidecar computation exactly. + +- [ ] **Step 1: Create scoring.ts** + +```typescript +// src/lib/scoring.ts — client-side scoring for live preview + +export type TaskWeightConfig = { + weight: number; + slaMinutes: number; + enabled: boolean; +}; + +export type PriorityConfig = { + taskWeights: Record; + campaignWeights: Record; + sourceWeights: Record; +}; + +export type ScoreResult = { + score: number; + baseScore: number; + slaMultiplier: number; + campaignMultiplier: number; + slaElapsedPercent: number; + slaStatus: 'low' | 'medium' | 'high' | 'critical'; + taskType: string; +}; + +export function computeSlaMultiplier(slaElapsedPercent: number): number { + const elapsed = slaElapsedPercent / 100; + if (elapsed > 1) return 1.0 + (elapsed - 1) * 0.5; + return Math.pow(elapsed, 1.6); +} + +export function computeSlaStatus(slaElapsedPercent: number): 'low' | 'medium' | 'high' | 'critical' { + if (slaElapsedPercent > 100) return 'critical'; + if (slaElapsedPercent >= 80) return 'high'; + if (slaElapsedPercent >= 50) return 'medium'; + return 'low'; +} + +export function inferTaskType(item: any): string { + if (item.callStatus === 'MISSED' || item.type === 'missed') return 'missed_call'; + if (item.followUpType === 'CALLBACK' || item.type === 'callback' || item.type === 'follow-up') return 'follow_up'; + if (item.contactAttempts >= 3) return 'attempt_3'; + if (item.contactAttempts >= 2) return 'attempt_2'; + return 'campaign_lead'; +} + +export function scoreItem(item: any, config: PriorityConfig): ScoreResult { + const taskType = inferTaskType(item); + const taskConfig = config.taskWeights[taskType]; + + if (!taskConfig?.enabled) { + return { score: 0, baseScore: 0, slaMultiplier: 1, campaignMultiplier: 1, slaElapsedPercent: 0, slaStatus: 'low', taskType }; + } + + const createdAt = item.createdAt ? new Date(item.createdAt).getTime() : Date.now(); + const elapsedMinutes = (Date.now() - createdAt) / 60000; + const slaElapsedPercent = Math.round((elapsedMinutes / taskConfig.slaMinutes) * 100); + + const baseScore = taskConfig.weight; + const slaMultiplier = computeSlaMultiplier(slaElapsedPercent); + + let campaignMultiplier = 1; + if (item.campaignId && config.campaignWeights[item.campaignId]) { + const cw = (config.campaignWeights[item.campaignId] ?? 5) / 10; + const source = item.leadSource ?? item.source ?? 'OTHER'; + const sw = (config.sourceWeights[source] ?? 5) / 10; + campaignMultiplier = cw * sw; + } + + const score = Math.round(baseScore * slaMultiplier * campaignMultiplier * 100) / 100; + + return { + score, + baseScore, + slaMultiplier: Math.round(slaMultiplier * 100) / 100, + campaignMultiplier: Math.round(campaignMultiplier * 100) / 100, + slaElapsedPercent, + slaStatus: computeSlaStatus(slaElapsedPercent), + taskType, + }; +} + +export function scoreAndRankItems(items: any[], config: PriorityConfig): (any & ScoreResult)[] { + return items + .map(item => ({ ...item, ...scoreItem(item, config) })) + .sort((a, b) => b.score - a.score); +} + +export const TASK_TYPE_LABELS: Record = { + missed_call: 'Missed Calls', + follow_up: 'Follow-ups', + campaign_lead: 'Campaign Leads', + attempt_2: '2nd Attempt', + attempt_3: '3rd Attempt', +}; + +export const SOURCE_LABELS: Record = { + WHATSAPP: 'WhatsApp', PHONE: 'Phone', FACEBOOK_AD: 'Facebook Ad', + GOOGLE_AD: 'Google Ad', INSTAGRAM: 'Instagram', WEBSITE: 'Website', + REFERRAL: 'Referral', WALK_IN: 'Walk-in', OTHER: 'Other', +}; + +export const DEFAULT_PRIORITY_CONFIG: PriorityConfig = { + taskWeights: { + missed_call: { weight: 9, slaMinutes: 720, enabled: true }, + follow_up: { weight: 8, slaMinutes: 1440, enabled: true }, + campaign_lead: { weight: 7, slaMinutes: 2880, enabled: true }, + attempt_2: { weight: 6, slaMinutes: 1440, enabled: true }, + attempt_3: { weight: 4, slaMinutes: 2880, enabled: true }, + }, + campaignWeights: {}, + sourceWeights: { + WHATSAPP: 9, PHONE: 8, FACEBOOK_AD: 7, GOOGLE_AD: 7, + INSTAGRAM: 5, WEBSITE: 7, REFERRAL: 6, WALK_IN: 5, OTHER: 5, + }, +}; +``` + +- [ ] **Step 2: Commit** + +```bash +cd helix-engage +git add src/lib/scoring.ts +git commit -m "feat: client-side scoring library for live preview" +``` + +--- + +### Task 8: Priority Rules Settings Page + +**Files:** +- Create: `helix-engage/src/pages/rules-settings.tsx` +- Create: `helix-engage/src/components/rules/weight-slider-row.tsx` +- Create: `helix-engage/src/components/rules/priority-config-panel.tsx` +- Create: `helix-engage/src/components/rules/campaign-weights-panel.tsx` +- Create: `helix-engage/src/components/rules/source-weights-panel.tsx` +- Create: `helix-engage/src/components/rules/worklist-preview.tsx` +- Modify: `helix-engage/src/components/layout/sidebar.tsx` — add nav item + +- [ ] **Step 1: Create weight-slider-row.tsx** + +Reusable row component: label + Untitled UI Slider (0-10) + current value display + optional SLA input + optional toggle. + +- [ ] **Step 2: Create priority-config-panel.tsx** + +Section with task type weight sliders and SLA inputs. Uses `weight-slider-row.tsx` for each task type. Fetches initial config from `GET /api/rules/priority-config`, calls `PUT` on change (debounced). + +- [ ] **Step 3: Create campaign-weights-panel.tsx** + +Lists campaigns from DataProvider with weight sliders. Default weight 5 for campaigns without a configured weight. + +- [ ] **Step 4: Create source-weights-panel.tsx** + +Lists lead sources with weight sliders. + +- [ ] **Step 5: Create worklist-preview.tsx** + +Shows a mini worklist table re-ranked using the client-side `scoreAndRankItems()` function. Uses current worklist data from DataProvider + the current slider config. Updates in real-time as sliders change. + +- [ ] **Step 6: Create rules-settings.tsx** + +Page layout with Untitled UI Tabs: "Priority" (active) and "Automations" (coming soon). Priority tab renders the 3 config panels + preview panel in a 2-column layout (config left, preview right). + +- [ ] **Step 7: Add to sidebar** + +Add "Rules" nav item under Supervisor section in `sidebar.tsx` for admin role. + +- [ ] **Step 8: Add route** + +Add `/rules` route in the router configuration. + +- [ ] **Step 9: Commit** + +```bash +git add src/pages/rules-settings.tsx src/components/rules/ src/components/layout/sidebar.tsx +git commit -m "feat: priority rules settings page — weight sliders + live preview" +``` + +--- + +### Task 9: Worklist Score Display + +**Files:** +- Modify: `helix-engage/src/components/call-desk/worklist-panel.tsx` + +- [ ] **Step 1: Add SLA status dot** + +Replace or augment the priority Badge with an SLA status indicator: +- `low` → green dot +- `medium` → amber dot +- `high` → red dot +- `critical` → dark-red pulsing dot + +- [ ] **Step 2: Add score display** + +Show the computed score as a small badge or number next to the item. Tooltip on hover shows scoreBreakdown: which rules fired, SLA multiplier, campaign multiplier. + +- [ ] **Step 3: Sort by score** + +When worklist items have a `score` field (from the sidecar), sort by score descending instead of the hardcoded priority + createdAt. + +- [ ] **Step 4: Commit** + +```bash +git add src/components/call-desk/worklist-panel.tsx +git commit -m "feat: worklist score display — SLA dots + score badges + breakdown tooltip" +``` + +--- + +## Execution Notes + +- Tasks 1-4 are independent (backend) — can be parallelized +- Task 5 depends on 1-4 +- Task 6 depends on 5 +- Task 7 is independent (frontend) — can run in parallel with backend tasks +- Tasks 8-9 depend on Task 7 +- Build sidecar after Task 6 to verify compilation +- Hospital starter template is applied via `POST /api/rules/templates/hospital-starter/apply` diff --git a/docs/superpowers/plans/2026-04-02-design-tokens.md b/docs/superpowers/plans/2026-04-02-design-tokens.md new file mode 100644 index 0000000..b0a2f46 --- /dev/null +++ b/docs/superpowers/plans/2026-04-02-design-tokens.md @@ -0,0 +1,600 @@ +# Design Tokens — Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** JSON-driven multi-hospital theming — sidecar serves theme config, frontend provider injects CSS variables + content tokens, supervisor edits branding from Settings. + +**Architecture:** Sidecar stores `data/theme.json`, serves via REST. Frontend `ThemeTokenProvider` fetches on mount, overrides CSS custom properties on ``, exposes content tokens via React context. Settings page has a Branding tab for admins. + +**Tech Stack:** NestJS (sidecar controller/service), React context + CSS custom properties (frontend), Untitled UI components (settings form) + +**Spec:** `docs/superpowers/specs/2026-04-02-design-tokens-design.md` + +--- + +## File Map + +| File | Action | Responsibility | +|---|---|---| +| `helix-engage-server/src/config/theme.controller.ts` | Create | GET/PUT/POST endpoints for theme | +| `helix-engage-server/src/config/theme.service.ts` | Create | Read/write/validate/backup theme JSON | +| `helix-engage-server/src/config/theme.defaults.ts` | Create | Default Global Hospital theme constant | +| `helix-engage-server/src/config/config.module.ts` | Create | NestJS module for theme | +| `helix-engage-server/src/app.module.ts` | Modify | Import ConfigThemeModule | +| `helix-engage-server/data/theme.json` | Create | Default theme file | +| `helix-engage/src/providers/theme-token-provider.tsx` | Create | Fetch theme, inject CSS vars, expose context | +| `helix-engage/src/main.tsx` | Modify | Wrap app with ThemeTokenProvider | +| `helix-engage/src/pages/login.tsx` | Modify | Consume tokens instead of hardcoded strings | +| `helix-engage/src/components/layout/sidebar.tsx` | Modify | Consume tokens for title/subtitle | +| `helix-engage/src/components/call-desk/ai-chat-panel.tsx` | Modify | Consume tokens for quick actions | +| `helix-engage/src/pages/branding-settings.tsx` | Create | Branding tab in settings for admins | +| `helix-engage/src/main.tsx` | Modify | Add branding settings route | + +--- + +### Task 1: Default Theme Constant + Theme Service (Sidecar) + +**Files:** +- Create: `helix-engage-server/src/config/theme.defaults.ts` +- Create: `helix-engage-server/src/config/theme.service.ts` + +- [ ] **Step 1: Create theme.defaults.ts** + +```typescript +// src/config/theme.defaults.ts + +export type ThemeConfig = { + brand: { + name: string; + hospitalName: string; + logo: string; + favicon: string; + }; + colors: { + brand: Record; + }; + typography: { + body: string; + display: string; + }; + login: { + title: string; + subtitle: string; + showGoogleSignIn: boolean; + showForgotPassword: boolean; + poweredBy: { label: string; url: string }; + }; + sidebar: { + title: string; + subtitle: string; + }; + ai: { + quickActions: Array<{ label: string; prompt: string }>; + }; +}; + +export const DEFAULT_THEME: ThemeConfig = { + brand: { + name: 'Helix Engage', + hospitalName: 'Global Hospital', + logo: '/helix-logo.png', + favicon: '/favicon.ico', + }, + colors: { + brand: { + '25': 'rgb(239 246 255)', + '50': 'rgb(219 234 254)', + '100': 'rgb(191 219 254)', + '200': 'rgb(147 197 253)', + '300': 'rgb(96 165 250)', + '400': 'rgb(59 130 246)', + '500': 'rgb(37 99 235)', + '600': 'rgb(29 78 216)', + '700': 'rgb(30 64 175)', + '800': 'rgb(30 58 138)', + '900': 'rgb(23 37 84)', + '950': 'rgb(15 23 42)', + }, + }, + typography: { + body: "'Satoshi', var(--font-inter, 'Inter'), -apple-system, 'Segoe UI', Roboto, Arial, sans-serif", + display: "'General Sans', var(--font-inter, 'Inter'), -apple-system, 'Segoe UI', Roboto, Arial, sans-serif", + }, + login: { + title: 'Sign in to Helix Engage', + subtitle: 'Global Hospital', + showGoogleSignIn: true, + showForgotPassword: true, + poweredBy: { label: 'Powered by F0rty2.ai', url: 'https://f0rty2.ai' }, + }, + sidebar: { + title: 'Helix Engage', + subtitle: 'Global Hospital · {role}', + }, + ai: { + quickActions: [ + { label: 'Doctor availability', prompt: 'What doctors are available and what are their visiting hours?' }, + { label: 'Clinic timings', prompt: 'What are the clinic locations and timings?' }, + { label: 'Patient history', prompt: "Can you summarize this patient's history?" }, + { label: 'Treatment packages', prompt: 'What treatment packages are available?' }, + ], + }, +}; +``` + +- [ ] **Step 2: Create theme.service.ts** + +```typescript +// src/config/theme.service.ts + +import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; +import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync } from 'fs'; +import { join, dirname } from 'path'; +import { DEFAULT_THEME, type ThemeConfig } from './theme.defaults'; + +const THEME_PATH = join(process.cwd(), 'data', 'theme.json'); +const BACKUP_DIR = join(process.cwd(), 'data', 'theme-backups'); + +@Injectable() +export class ThemeService implements OnModuleInit { + private readonly logger = new Logger(ThemeService.name); + private cached: ThemeConfig | null = null; + + onModuleInit() { + this.load(); + } + + getTheme(): ThemeConfig { + if (this.cached) return this.cached; + return this.load(); + } + + updateTheme(updates: Partial): ThemeConfig { + const current = this.getTheme(); + + // Deep merge + const merged: ThemeConfig = { + brand: { ...current.brand, ...updates.brand }, + colors: { + brand: { ...current.colors.brand, ...updates.colors?.brand }, + }, + typography: { ...current.typography, ...updates.typography }, + login: { ...current.login, ...updates.login, poweredBy: { ...current.login.poweredBy, ...updates.login?.poweredBy } }, + sidebar: { ...current.sidebar, ...updates.sidebar }, + ai: { + quickActions: updates.ai?.quickActions ?? current.ai.quickActions, + }, + }; + + // Backup current + this.backup(); + + // Save + const dir = dirname(THEME_PATH); + if (!existsSync(dir)) mkdirSync(dir, { recursive: true }); + writeFileSync(THEME_PATH, JSON.stringify(merged, null, 2), 'utf8'); + this.cached = merged; + + this.logger.log('Theme updated and saved'); + return merged; + } + + resetTheme(): ThemeConfig { + this.backup(); + const dir = dirname(THEME_PATH); + if (!existsSync(dir)) mkdirSync(dir, { recursive: true }); + writeFileSync(THEME_PATH, JSON.stringify(DEFAULT_THEME, null, 2), 'utf8'); + this.cached = DEFAULT_THEME; + this.logger.log('Theme reset to defaults'); + return DEFAULT_THEME; + } + + private load(): ThemeConfig { + try { + if (existsSync(THEME_PATH)) { + const raw = readFileSync(THEME_PATH, 'utf8'); + const parsed = JSON.parse(raw); + // Merge with defaults to fill missing fields + this.cached = { + brand: { ...DEFAULT_THEME.brand, ...parsed.brand }, + colors: { brand: { ...DEFAULT_THEME.colors.brand, ...parsed.colors?.brand } }, + typography: { ...DEFAULT_THEME.typography, ...parsed.typography }, + login: { ...DEFAULT_THEME.login, ...parsed.login, poweredBy: { ...DEFAULT_THEME.login.poweredBy, ...parsed.login?.poweredBy } }, + sidebar: { ...DEFAULT_THEME.sidebar, ...parsed.sidebar }, + ai: { quickActions: parsed.ai?.quickActions ?? DEFAULT_THEME.ai.quickActions }, + }; + this.logger.log('Theme loaded from file'); + return this.cached; + } + } catch (err) { + this.logger.warn(`Failed to load theme: ${err}`); + } + + this.cached = DEFAULT_THEME; + this.logger.log('Using default theme'); + return DEFAULT_THEME; + } + + private backup() { + try { + if (!existsSync(THEME_PATH)) return; + if (!existsSync(BACKUP_DIR)) mkdirSync(BACKUP_DIR, { recursive: true }); + const ts = new Date().toISOString().replace(/[:.]/g, '-'); + copyFileSync(THEME_PATH, join(BACKUP_DIR, `theme-${ts}.json`)); + } catch (err) { + this.logger.warn(`Backup failed: ${err}`); + } + } +} +``` + +- [ ] **Step 3: Commit** + +```bash +cd helix-engage-server +git add src/config/theme.defaults.ts src/config/theme.service.ts +git commit -m "feat: theme service — read/write/backup theme JSON" +``` + +--- + +### Task 2: Theme Controller + Module (Sidecar) + +**Files:** +- Create: `helix-engage-server/src/config/theme.controller.ts` +- Create: `helix-engage-server/src/config/config.module.ts` +- Modify: `helix-engage-server/src/app.module.ts` + +- [ ] **Step 1: Create theme.controller.ts** + +```typescript +// src/config/theme.controller.ts + +import { Controller, Get, Put, Post, Body, Logger } from '@nestjs/common'; +import { ThemeService } from './theme.service'; +import type { ThemeConfig } from './theme.defaults'; + +@Controller('api/config') +export class ThemeController { + private readonly logger = new Logger(ThemeController.name); + + constructor(private readonly theme: ThemeService) {} + + @Get('theme') + getTheme() { + return this.theme.getTheme(); + } + + @Put('theme') + updateTheme(@Body() body: Partial) { + this.logger.log('Theme update request'); + return this.theme.updateTheme(body); + } + + @Post('theme/reset') + resetTheme() { + this.logger.log('Theme reset request'); + return this.theme.resetTheme(); + } +} +``` + +- [ ] **Step 2: Create config.module.ts** + +```typescript +// src/config/config.module.ts +// Named ConfigThemeModule to avoid conflict with NestJS ConfigModule + +import { Module } from '@nestjs/common'; +import { ThemeController } from './theme.controller'; +import { ThemeService } from './theme.service'; + +@Module({ + controllers: [ThemeController], + providers: [ThemeService], + exports: [ThemeService], +}) +export class ConfigThemeModule {} +``` + +- [ ] **Step 3: Register in app.module.ts** + +Add import at top: +```typescript +import { ConfigThemeModule } from './config/config.module'; +``` + +Add to imports array: +```typescript +ConfigThemeModule, +``` + +- [ ] **Step 4: Build and verify** + +```bash +cd helix-engage-server && npm run build +``` + +- [ ] **Step 5: Commit** + +```bash +git add src/config/ src/app.module.ts +git commit -m "feat: theme REST API — GET/PUT/POST endpoints" +``` + +--- + +### Task 3: ThemeTokenProvider (Frontend) + +**Files:** +- Create: `helix-engage/src/providers/theme-token-provider.tsx` +- Modify: `helix-engage/src/main.tsx` + +- [ ] **Step 1: Create theme-token-provider.tsx** + +```typescript +// src/providers/theme-token-provider.tsx + +import type { ReactNode } from 'react'; +import { createContext, useContext, useEffect, useState, useCallback } from 'react'; + +const API_URL = import.meta.env.VITE_API_URL ?? 'http://localhost:4100'; + +export type ThemeTokens = { + brand: { name: string; hospitalName: string; logo: string; favicon: string }; + colors: { brand: Record }; + typography: { body: string; display: string }; + login: { title: string; subtitle: string; showGoogleSignIn: boolean; showForgotPassword: boolean; poweredBy: { label: string; url: string } }; + sidebar: { title: string; subtitle: string }; + ai: { quickActions: Array<{ label: string; prompt: string }> }; +}; + +const DEFAULT_TOKENS: ThemeTokens = { + brand: { name: 'Helix Engage', hospitalName: 'Global Hospital', logo: '/helix-logo.png', favicon: '/favicon.ico' }, + colors: { brand: {} }, + typography: { body: '', display: '' }, + login: { title: 'Sign in to Helix Engage', subtitle: 'Global Hospital', showGoogleSignIn: true, showForgotPassword: true, poweredBy: { label: 'Powered by F0rty2.ai', url: 'https://f0rty2.ai' } }, + sidebar: { title: 'Helix Engage', subtitle: 'Global Hospital · {role}' }, + ai: { quickActions: [ + { label: 'Doctor availability', prompt: 'What doctors are available and what are their visiting hours?' }, + { label: 'Clinic timings', prompt: 'What are the clinic locations and timings?' }, + { label: 'Patient history', prompt: "Can you summarize this patient's history?" }, + { label: 'Treatment packages', prompt: 'What treatment packages are available?' }, + ] }, +}; + +type ThemeTokenContextType = { + tokens: ThemeTokens; + refresh: () => Promise; +}; + +const ThemeTokenContext = createContext({ tokens: DEFAULT_TOKENS, refresh: async () => {} }); + +export const useThemeTokens = () => useContext(ThemeTokenContext); + +const applyColorTokens = (brandColors: Record) => { + const root = document.documentElement; + for (const [stop, value] of Object.entries(brandColors)) { + root.style.setProperty(`--color-brand-${stop}`, value); + } +}; + +const applyTypographyTokens = (typography: { body: string; display: string }) => { + const root = document.documentElement; + if (typography.body) root.style.setProperty('--font-body', typography.body); + if (typography.display) root.style.setProperty('--font-display', typography.display); +}; + +export const ThemeTokenProvider = ({ children }: { children: ReactNode }) => { + const [tokens, setTokens] = useState(DEFAULT_TOKENS); + + const fetchTheme = useCallback(async () => { + try { + const res = await fetch(`${API_URL}/api/config/theme`); + if (res.ok) { + const data: ThemeTokens = await res.json(); + setTokens(data); + if (data.colors?.brand && Object.keys(data.colors.brand).length > 0) { + applyColorTokens(data.colors.brand); + } + if (data.typography) { + applyTypographyTokens(data.typography); + } + } + } catch { + // Use defaults silently + } + }, []); + + useEffect(() => { fetchTheme(); }, [fetchTheme]); + + return ( + + {children} + + ); +}; +``` + +- [ ] **Step 2: Wrap app in main.tsx** + +In `main.tsx`, add import: +```typescript +import { ThemeTokenProvider } from '@/providers/theme-token-provider'; +``` + +Wrap inside `ThemeProvider`: +```tsx + + + + ... + + + +``` + +- [ ] **Step 3: Build and verify** + +```bash +npx tsc --noEmit +``` + +- [ ] **Step 4: Commit** + +```bash +git add src/providers/theme-token-provider.tsx src/main.tsx +git commit -m "feat: ThemeTokenProvider — fetch theme, inject CSS variables" +``` + +--- + +### Task 4: Consume Tokens in Login Page + +**Files:** +- Modify: `helix-engage/src/pages/login.tsx` + +- [ ] **Step 1: Replace hardcoded values** + +Import `useThemeTokens`: +```typescript +import { useThemeTokens } from '@/providers/theme-token-provider'; +``` + +Inside the component: +```typescript +const { tokens } = useThemeTokens(); +``` + +Replace hardcoded strings: +- `src="/helix-logo.png"` → `src={tokens.brand.logo}` +- `"Sign in to Helix Engage"` → `{tokens.login.title}` +- `"Global Hospital"` → `{tokens.login.subtitle}` +- Google sign-in section: wrap with `{tokens.login.showGoogleSignIn && (...)}` +- Forgot password: wrap with `{tokens.login.showForgotPassword && (...)}` +- Powered by: `tokens.login.poweredBy.label` and `tokens.login.poweredBy.url` + +- [ ] **Step 2: Commit** + +```bash +git add src/pages/login.tsx +git commit -m "feat: login page consumes theme tokens" +``` + +--- + +### Task 5: Consume Tokens in Sidebar + AI Chat + +**Files:** +- Modify: `helix-engage/src/components/layout/sidebar.tsx` +- Modify: `helix-engage/src/components/call-desk/ai-chat-panel.tsx` + +- [ ] **Step 1: Update sidebar.tsx** + +Import `useThemeTokens` and replace: +- Line 167: `"Helix Engage"` → `{tokens.sidebar.title}` +- Line 168: `"Global Hospital · {getRoleSubtitle(user.role)}"` → `{tokens.sidebar.subtitle.replace('{role}', getRoleSubtitle(user.role))}` +- Line 164: favicon src → `tokens.brand.logo` + +- [ ] **Step 2: Update ai-chat-panel.tsx** + +Import `useThemeTokens` and replace: +- Lines 21-25: hardcoded `QUICK_ACTIONS` array → `tokens.ai.quickActions` + +Move `QUICK_ACTIONS` usage inside the component: +```typescript +const { tokens } = useThemeTokens(); +const quickActions = tokens.ai.quickActions; +``` + +- [ ] **Step 3: Commit** + +```bash +git add src/components/layout/sidebar.tsx src/components/call-desk/ai-chat-panel.tsx +git commit -m "feat: sidebar + AI chat consume theme tokens" +``` + +--- + +### Task 6: Branding Settings Page (Frontend) + +**Files:** +- Create: `helix-engage/src/pages/branding-settings.tsx` +- Modify: `helix-engage/src/main.tsx` (add route) +- Modify: `helix-engage/src/components/layout/sidebar.tsx` (add nav item) + +- [ ] **Step 1: Create branding-settings.tsx** + +The page has 6 collapsible sections matching the spec. Uses Untitled UI `Input`, `TextArea`, `Checkbox`, `Button` components. On save, PUTs to `/api/config/theme` and calls `refresh()` from `useThemeTokens()`. + +Key patterns: +- Fetch current theme on mount via `GET /api/config/theme` +- Local state mirrors the theme JSON structure +- Each section is a collapsible card +- Color section: 12 text inputs for hex/rgb values with colored preview dots +- Save button calls `PUT /api/config/theme` with the full state +- Reset button calls `POST /api/config/theme/reset` +- After save/reset, call `refresh()` to re-apply CSS variables immediately + +- [ ] **Step 2: Add route in main.tsx** + +```typescript +import { BrandingSettingsPage } from '@/pages/branding-settings'; +``` + +Add route: +```tsx +} /> +``` + +- [ ] **Step 3: Add nav item in sidebar.tsx** + +Under the Configuration section (near Rules Engine), add "Branding" link for admin role only. + +- [ ] **Step 4: Build and verify** + +```bash +npx tsc --noEmit +``` + +- [ ] **Step 5: Commit** + +```bash +git add src/pages/branding-settings.tsx src/main.tsx src/components/layout/sidebar.tsx +git commit -m "feat: branding settings page — theme editor for supervisors" +``` + +--- + +### Task 7: Default Theme File + Build Verification + +**Files:** +- Create: `helix-engage-server/data/theme.json` + +- [ ] **Step 1: Create default theme.json** + +Copy the `DEFAULT_THEME` object as JSON to `data/theme.json`. + +- [ ] **Step 2: Build both projects** + +```bash +cd helix-engage-server && npm run build +cd ../helix-engage && npm run build +``` + +- [ ] **Step 3: Commit all** + +```bash +git add data/theme.json +git commit -m "chore: default theme.json file" +``` + +--- + +## Execution Notes + +- ThemeTokenProvider fetches before login — the endpoint is public (no auth) +- CSS variable override on `` has higher specificity than the `@theme` block in `theme.css` +- `tokens.sidebar.subtitle` supports `{role}` placeholder — replaced at render time by the sidebar component +- The branding settings page is admin-only but the theme endpoint itself is unauthenticated (GET) — PUT requires auth +- If the sidecar is unreachable, the frontend silently falls back to hardcoded defaults diff --git a/docs/superpowers/specs/2026-03-31-csv-lead-import-design.md b/docs/superpowers/specs/2026-03-31-csv-lead-import-design.md new file mode 100644 index 0000000..12b4afd --- /dev/null +++ b/docs/superpowers/specs/2026-03-31-csv-lead-import-design.md @@ -0,0 +1,165 @@ +# CSV Lead Import — Design Spec + +**Date**: 2026-03-31 +**Status**: Approved + +--- + +## Overview + +Supervisors can import leads from a CSV file into an existing campaign. The feature is a modal wizard accessible from the Campaigns page. Leads are created via the platform GraphQL API and linked to the selected campaign. Existing patients are detected by phone number matching. + +--- + +## User Flow + +### Entry Point +"Import Leads" button on the Campaigns page (`/campaigns`). Admin role only. + +### Step 1 — Select Campaign (modal opens) +- Campaign cards in a grid layout inside the modal +- Each card shows: campaign name, platform badge (Facebook/Google/Instagram/Manual), status badge (Active/Paused/Completed), lead count +- Click a card to select → proceeds to Step 2 +- Only ACTIVE and PAUSED campaigns shown (not COMPLETED) + +### Step 2 — Upload & Preview +- File drop zone at top of modal (accepts `.csv` only) +- On file upload, parse CSV client-side +- Show preview table with: + - **Column mapping row**: each CSV column header has a dropdown to map to a Lead field. Fuzzy auto-match on load (e.g., "Phone" → contactPhone, "Name" → contactName.firstName, "Email" → contactEmail, "Service" → interestedService) + - **Data rows**: all rows displayed (paginated at 20 per page if large file) + - **Patient match column** (rightmost): for each row, check phone against existing patients in DataProvider + - Green badge: "Existing — {Patient Name}" (phone matched) + - Gray badge: "New" (no match) + - **Duplicate lead column**: check phone against existing leads + - Orange badge: "Duplicate" (phone already exists as a lead) + - No badge if clean +- Validation: + - `contactPhone` mapping is required — show error banner if unmapped + - Rows with empty phone values are flagged as "Skip — no phone" +- Footer shows summary: "48 leads ready, 3 existing patients, 2 duplicates, 1 skipped" +- "Import" button enabled only when contactPhone is mapped and at least 1 valid row exists + +### Step 3 — Import Progress +- "Import" button triggers sequential lead creation +- Progress bar: "Importing 12 / 48..." +- Each lead created via GraphQL mutation: + ```graphql + mutation($data: LeadCreateInput!) { + createLead(data: $data) { id } + } + ``` +- Data payload per lead: + - `name`: "{firstName} {lastName}" or phone if no name + - `contactName`: `{ firstName, lastName }` from mapped columns + - `contactPhone`: `{ primaryPhoneNumber }` from mapped column (normalized with +91 prefix) + - `contactEmail`: `{ primaryEmail }` if mapped + - `interestedService`: if mapped + - `source`: campaign platform (FACEBOOK_AD, GOOGLE_AD, etc.) or MANUAL + - `status`: NEW + - `campaignId`: selected campaign ID + - `patientId`: if phone matched an existing patient + - All other mapped fields set accordingly +- Duplicate leads (phone already exists) are skipped +- On complete: summary card — "45 created, 3 linked to existing patients, 2 skipped (duplicates), 1 skipped (no phone)" + +### Step 4 — Done +- Summary with green checkmark +- "Done" button closes modal +- Campaigns page refreshes to show updated lead count + +--- + +## Column Mapping — Fuzzy Match Rules + +CSV headers are normalized (lowercase, trim, remove special chars) and matched against Lead field labels: + +| CSV Header Pattern | Maps To | Field Type | +|---|---|---| +| name, first name, patient name | contactName.firstName | FULL_NAME | +| last name, surname | contactName.lastName | FULL_NAME | +| phone, mobile, contact number, cell | contactPhone | PHONES | +| email, email address | contactEmail | EMAILS | +| service, interested in, department, specialty | interestedService | TEXT | +| priority | priority | SELECT | +| source, lead source, channel | source | SELECT | +| notes, comments, remarks | (stored as lead name suffix or skipped) | — | +| utm_source, utm_medium, utm_campaign, utm_term, utm_content | utmSource/utmMedium/utmCampaign/utmTerm/utmContent | TEXT | + +Unmapped columns are ignored. User can override any auto-match via dropdown. + +--- + +## Phone Normalization + +Before matching and creating: +1. Strip all non-digit characters +2. Remove leading `+91` or `91` if 12+ digits +3. Take last 10 digits +4. Store as `+91{10digits}` on the Lead + +--- + +## Patient Matching + +Uses the `patients` array from DataProvider (already loaded in memory): +- For each CSV row, normalize the phone number +- Check against `patient.phones.primaryPhoneNumber` (last 10 digits) +- If match found: set `patientId` on the created Lead, show patient name in preview +- If no match: leave `patientId` null, caller resolution will handle it on first call + +--- + +## Duplicate Lead Detection + +Uses the `leads` array from DataProvider: +- For each CSV row, check normalized phone against existing `lead.contactPhone[0].number` +- If match found: mark as duplicate in preview, skip during import +- If no match: create normally + +--- + +## Error Handling + +- Invalid CSV (no headers, empty file): show error banner in modal, no preview +- File too large (>5000 rows): show warning, allow import but warn about duration +- Individual mutation failures: log error, continue with remaining rows, show count in summary +- Network failure mid-import: show partial result — "23 of 48 imported, import interrupted" + +--- + +## Architecture + +### No new sidecar endpoint needed +CSV parsing happens client-side. Lead creation uses the existing GraphQL proxy (`/graphql` → platform). Patient/lead matching uses DataProvider data already in memory. + +### Files + +| File | Action | +|---|---| +| `src/components/campaigns/lead-import-wizard.tsx` | **New** — Modal wizard component (Steps 1-4) | +| `src/pages/campaigns.tsx` | **Modified** — Add "Import Leads" button | +| `src/lib/csv-parser.ts` | **New** — CSV parsing + column fuzzy matching utility | + +### Dependencies +- No new npm packages needed — `FileReader` API + string split for CSV parsing (or use existing `papaparse` if already in node_modules) +- Untitled UI components: Modal, Button, Badge, Table, Input (file), FeaturedIcon + +--- + +## Scope Boundaries + +**In scope:** +- Campaign selection via cards +- CSV upload and client-side parsing +- Fuzzy column mapping with manual override +- Preview with patient match + duplicate detection +- Sequential lead creation with progress +- Phone normalization + +**Out of scope (future):** +- Dynamic campaign-specific entity creation (AI-driven schema) +- Campaign content/template creation +- Bulk update of existing leads from CSV +- API-based lead ingestion (Facebook/Google webhooks) +- Code generation webhook on schema changes diff --git a/docs/superpowers/specs/2026-03-31-rules-engine-design.md b/docs/superpowers/specs/2026-03-31-rules-engine-design.md new file mode 100644 index 0000000..5959f28 --- /dev/null +++ b/docs/superpowers/specs/2026-03-31-rules-engine-design.md @@ -0,0 +1,432 @@ +# Rules Engine — Design Spec (v2) + +**Date**: 2026-03-31 (revised 2026-04-01) +**Status**: Approved +**Phase**: 1 (Engine + Storage + API + Priority Rules UI + Worklist Integration) + +--- + +## Overview + +A configurable rules engine that governs how leads flow through the hospital's call center — which leads get called first, which agent handles them, when to escalate, and when to mark them lost. Each hospital defines its own rules. No code changes needed to change behavior. + +**Product pitch**: "Your hospital defines the rules, the call center follows them automatically." + +--- + +## Two Rule Types + +The engine supports two categories of rules, each with different behavior and UI: + +### Priority Rules — "Who gets called first?" +- Configures worklist ranking via weights, SLA curves, campaign modifiers +- **Computed at request time** — scores are ephemeral, not persisted to entities +- Time-sensitive (SLA elapsed changes every minute — can't be persisted) +- Supervisor sees: weight sliders, SLA thresholds, campaign weights, live worklist preview +- No draft/publish needed — changes affect ranking immediately + +### Automation Rules — "What should happen automatically?" +- Triggers durable actions when conditions are met: field updates, assignments, notifications +- **Writes back to entities** via platform GraphQL mutations (e.g., set lead.priority = HIGH) +- Event-driven (fires on lead.created, call.missed, etc.) or scheduled (every 5m) +- Supervisor sees: if-this-then-that condition builder with entity/field selectors +- **Draft/publish workflow** — rules don't affect live data until published +- Sub-types: Assignment, Escalation, Lifecycle + +| Aspect | Priority Rules | Automation Rules | +|---|---|---| +| When | On worklist request | On entity event / on schedule | +| Effect | Ephemeral score for ranking | Durable entity mutation | +| Persisted? | No (recomputed each request) | Yes (writes to platform) | +| Draft/publish? | No (immediate) | Yes | +| UI | Sliders + live preview | Condition builder + draft/publish | + +--- + +## Architecture + +Self-contained NestJS module inside helix-engage-server (sidecar). Designed for extraction into a standalone microservice when needed. + +``` +helix-engage-server/src/rules-engine/ +├── rules-engine.module.ts # NestJS module (self-contained) +├── rules-engine.service.ts # Core: json-rules-engine wrapper +├── rules-engine.controller.ts # REST API: CRUD + evaluate + config +├── rules-storage.service.ts # Redis (hot) + JSON file (backup) +├── types/ +│ ├── rule.types.ts # Rule schema (priority + automation) +│ ├── fact.types.ts # Fact definitions + computed facts +│ └── action.types.ts # Action handler interface +├── facts/ +│ ├── lead-facts.provider.ts # Lead/campaign data facts +│ ├── call-facts.provider.ts # Call/SLA data facts (+ computed: ageMinutes, slaElapsed) +│ └── agent-facts.provider.ts # Agent availability facts +├── actions/ +│ ├── score.action.ts # Priority scoring action +│ ├── assign.action.ts # Lead-to-agent assignment (stub) +│ ├── escalate.action.ts # SLA breach alerts (stub) +│ └── update.action.ts # Update entity field (stub) +├── consumers/ +│ └── worklist.consumer.ts # Applies scoring rules to worklist +└── templates/ + └── hospital-starter.json # Pre-built rule set for new hospitals +``` + +### Dependencies +- `json-rules-engine` (npm) — rule evaluation +- Redis — active rule storage, score cache +- Platform GraphQL — fact data (leads, calls, campaigns, agents) +- No imports from other sidecar modules except via constructor injection + +### Communication +- Own Redis namespace: `rules:*` +- Own route prefix: `/api/rules/*` +- Other modules call `RulesEngineService.evaluate()` — they don't import internals + +--- + +## Fact System + +### Design Principle: Entity-Driven Facts +Facts should ultimately be driven by entity metadata from the platform — adding a field to an entity automatically makes it available as a fact. This is the long-term goal. + +### Phase 1: Curated Facts + Computed Facts +For Phase 1, facts are curated (hardcoded providers) with two categories: + +**Entity field facts** — direct field values from platform entities: +- `lead.source`, `lead.status`, `lead.campaignId`, etc. +- `call.direction`, `call.status`, `call.callbackStatus`, etc. +- `agent.status`, `agent.skills`, etc. + +**Computed facts** — derived values that don't exist as entity fields: +- `lead.ageMinutes` — computed from `createdAt` +- `call.slaElapsedPercent` — computed from `createdAt` + task type SLA +- `call.slaBreached` — computed from slaElapsedPercent > 100 +- `call.taskType` — inferred from call data (missed_call, follow_up, campaign_lead, etc.) + +### Phase 2: Metadata-Driven Discovery +- Query platform metadata API to discover entities and fields dynamically +- Each field's type (NUMBER, TEXT, SELECT, BOOLEAN) drives: + - Available operators in the condition builder UI + - Input type (slider, dropdown with enum values, text, toggle) +- Computed facts remain registered in code alongside metadata-driven facts + +--- + +## Rule Schema + +```typescript +type RuleType = 'priority' | 'automation'; + +type Rule = { + id: string; // UUID + ruleType: RuleType; // Priority or Automation + name: string; // Human-readable + description?: string; // BA-friendly explanation + enabled: boolean; // Toggle on/off without deleting + priority: number; // Evaluation order (lower = first) + + trigger: RuleTrigger; // When to evaluate + conditions: RuleConditionGroup; // What to check + action: RuleAction; // What to do + + // Automation rules only + status?: 'draft' | 'published'; // Draft/publish workflow + + metadata: { + createdAt: string; + updatedAt: string; + createdBy: string; + category: RuleCategory; + tags?: string[]; + }; +}; + +type RuleTrigger = + | { type: 'on_request'; request: 'worklist' | 'assignment' } + | { type: 'on_event'; event: string } + | { type: 'on_schedule'; interval: string } + | { type: 'always' }; + +type RuleCategory = + | 'priority' // Worklist scoring (Priority Rules) + | 'assignment' // Lead/call routing to agent (Automation) + | 'escalation' // SLA breach handling (Automation) + | 'lifecycle' // Lead status transitions (Automation) + | 'qualification'; // Lead quality scoring (Automation) + +type RuleConditionGroup = { + all?: (RuleCondition | RuleConditionGroup)[]; + any?: (RuleCondition | RuleConditionGroup)[]; +}; + +type RuleCondition = { + fact: string; // Fact name + operator: RuleOperator; + value: any; + path?: string; // JSON path for nested facts +}; + +type RuleOperator = + | 'equal' | 'notEqual' + | 'greaterThan' | 'greaterThanInclusive' + | 'lessThan' | 'lessThanInclusive' + | 'in' | 'notIn' + | 'contains' | 'doesNotContain' + | 'exists' | 'doesNotExist'; + +type RuleAction = { + type: RuleActionType; + params: ScoreActionParams | AssignActionParams | EscalateActionParams | UpdateActionParams; +}; + +type RuleActionType = 'score' | 'assign' | 'escalate' | 'update' | 'notify'; + +// Score action params (Priority Rules) +type ScoreActionParams = { + weight: number; // 0-10 base weight + slaMultiplier?: boolean; // Apply SLA urgency curve + campaignMultiplier?: boolean; // Apply campaign weight +}; + +// Assign action params (Automation Rules — stub) +type AssignActionParams = { + agentId?: string; + agentPool?: string[]; + strategy: 'specific' | 'round-robin' | 'least-loaded' | 'skill-based'; +}; + +// Escalate action params (Automation Rules — stub) +type EscalateActionParams = { + channel: 'toast' | 'notification' | 'sms' | 'email'; + recipients: 'supervisor' | 'agent' | string[]; + message: string; + severity: 'warning' | 'critical'; +}; + +// Update action params (Automation Rules — stub) +type UpdateActionParams = { + entity: string; + field: string; + value: any; +}; +``` + +--- + +## Priority Rules — Scoring System + +### Formula +``` +finalScore = baseScore × slaMultiplier × campaignMultiplier +``` + +### Base Score +Determined by the rule's `weight` param (0-10). Multiple rules can fire for the same item — scores are **summed**. + +### SLA Multiplier (time-sensitive, computed at request time) +``` +if slaElapsed <= 100%: multiplier = (slaElapsed / 100) ^ 1.6 +if slaElapsed > 100%: multiplier = 1.0 + (excess × 0.05) +``` +Non-linear curve — urgency accelerates as deadline approaches. Continues increasing past breach. + +### Campaign Multiplier +``` +campaignWeight (0-10) / 10 × sourceWeight (0-10) / 10 +``` +IVF(9) × WhatsApp(9) = 0.81. Health(7) × Instagram(5) = 0.35. + +### Priority Config (supervisor-editable) +```typescript +type PriorityConfig = { + taskWeights: Record; + campaignWeights: Record; // campaignId → 0-10 + sourceWeights: Record; // leadSource → 0-10 +}; + +// Default config (from hospital starter template) +const DEFAULT_PRIORITY_CONFIG = { + taskWeights: { + missed_call: { weight: 9, slaMinutes: 720 }, // 12 hours + follow_up: { weight: 8, slaMinutes: 1440 }, // 1 day + campaign_lead: { weight: 7, slaMinutes: 2880 }, // 2 days + attempt_2: { weight: 6, slaMinutes: 1440 }, + attempt_3: { weight: 4, slaMinutes: 2880 }, + }, + campaignWeights: {}, // Empty = no campaign multiplier + sourceWeights: { + WHATSAPP: 9, PHONE: 8, FACEBOOK_AD: 7, GOOGLE_AD: 7, + INSTAGRAM: 5, WEBSITE: 7, REFERRAL: 6, WALK_IN: 5, OTHER: 5, + }, +}; +``` + +This config is what the **Priority Rules UI** edits via sliders. Under the hood, each entry generates a json-rules-engine rule. + +--- + +## Priority Rules UI (Supervisor Settings) + +### Layout +Settings page → "Priority" tab with three sections: + +**Section 1: Task Type Weights** +| Task Type | Weight (slider 0-10) | SLA (input) | +|---|---|---| +| Missed Calls | ████████░░ 9 | 12h | +| Follow-ups | ███████░░░ 8 | 1d | +| Campaign Leads | ██████░░░░ 7 | 2d | +| 2nd Attempt | █████░░░░░ 6 | 1d | +| 3rd Attempt | ███░░░░░░░ 4 | 2d | + +**Section 2: Campaign Weights** +Shows existing campaigns with weight sliders. Default 5. +| Campaign | Weight | +|---|---| +| IVF Awareness | ████████░░ 9 | +| Health Checkup | ██████░░░░ 7 | +| Cancer Screening | ███████░░░ 8 | + +**Section 3: Source Weights** +| Source | Weight | +|---|---| +| WhatsApp | ████████░░ 9 | +| Phone | ███████░░░ 8 | +| Facebook Ad | ██████░░░░ 7 | +| ... | ... | + +**Section 4: Live Preview** +Shows the current worklist re-ranked with the configured weights. As supervisor adjusts sliders, preview updates in real-time (client-side computation using the same scoring formula). + +### Components +- Untitled UI Slider (if available) or custom range input +- Untitled UI Toggle for enable/disable per task type +- Untitled UI Tabs for Priority / Automations +- Score badges showing computed values in preview + +--- + +## Storage + +### Redis Keys +``` +rules:config # JSON array of all Rule objects +rules:priority-config # PriorityConfig JSON (slider values) +rules:config:backup_path # Path to JSON backup file +rules:scores:{itemId} # Cached base score per worklist item +rules:scores:version # Incremented on rule change (invalidates all scores) +rules:eval:log:{ruleId} # Last evaluation result (debug) +``` + +### JSON File Backup +On every rule/config change: +1. Write to Redis +2. Persist to `data/rules-config.json` + `data/priority-config.json` in sidecar working directory +3. On sidecar startup: if Redis is empty, load from JSON files + +--- + +## API Endpoints + +### Priority Config (used by UI sliders) +``` +GET /api/rules/priority-config # Get current priority config +PUT /api/rules/priority-config # Update priority config (slider values) +POST /api/rules/priority-config/preview # Preview scoring with modified config +``` + +### Rule CRUD (for automation rules) +``` +GET /api/rules # List all rules +GET /api/rules/:id # Get single rule +POST /api/rules # Create rule +PUT /api/rules/:id # Update rule +DELETE /api/rules/:id # Delete rule +PATCH /api/rules/:id/toggle # Enable/disable +POST /api/rules/reorder # Change evaluation order +``` + +### Evaluation +``` +POST /api/rules/evaluate # Evaluate rules against provided facts +``` + +### Templates +``` +GET /api/rules/templates # List available rule templates +POST /api/rules/templates/:id/apply # Apply a template (creates rules + config) +``` + +--- + +## Worklist Integration + +### Current Flow +``` +GET /api/worklist → returns { missedCalls, followUps, marketingLeads } → frontend sorts by priority + createdAt +``` + +### New Flow +``` +GET /api/worklist → fetch 3 arrays → score each item via RulesEngineService → return with scores → frontend sorts by score +``` + +### Response Change +Each worklist item gains: +```typescript +{ + ...existingFields, + score: number; // Computed priority score + scoreBreakdown: { // Explainability + baseScore: number; + slaMultiplier: number; + campaignMultiplier: number; + rulesApplied: string[]; // Rule names that fired + }; + slaStatus: 'low' | 'medium' | 'high' | 'critical'; + slaElapsedPercent: number; +} +``` + +### Frontend Changes +- Worklist sorts by `score` descending instead of hardcoded priority +- SLA status dot (green/amber/red/dark-red) replaces priority badge +- Tooltip on score shows breakdown ("IVF campaign ×0.81, Missed call weight 9, SLA 72% elapsed") + +--- + +## Hospital Starter Template + +Pre-configured priority config + automation rules for a typical hospital. Applied on first setup via `POST /api/rules/templates/hospital-starter/apply`. + +Creates: +1. `PriorityConfig` with default task/campaign/source weights +2. Scoring rules in `rules:config` matching the config +3. One escalation rule stub (SLA breach → supervisor notification) + +--- + +## Scope Boundaries + +**In scope (Phase 1 — Friday):** +- `json-rules-engine` integration in sidecar +- Rule schema with `ruleType: 'priority' | 'automation'` distinction +- Curated fact providers (lead, call, agent) with computed facts +- Score action handler (full) + assign/escalate/update stubs +- Redis storage + JSON backup +- PriorityConfig CRUD + preview endpoints +- Rule CRUD API endpoints +- Worklist consumer (scoring integration) +- Hospital starter template +- **Priority Rules UI** — supervisor settings page with weight sliders, SLA config, live preview +- Frontend worklist changes (score display, SLA dots, breakdown tooltip) + +**Out of scope (Phase 2+):** +- Automation Rules UI (condition builder with entity/field selectors) +- Metadata-driven fact discovery from platform API +- Assignment/escalation/update action handlers (stubs in Phase 1) +- Event-driven rule evaluation (on_event triggers) +- Scheduled rule evaluation (on_schedule triggers) +- Draft/publish workflow for automation rules +- Multi-tenant rule isolation diff --git a/docs/superpowers/specs/2026-04-02-design-tokens-design.md b/docs/superpowers/specs/2026-04-02-design-tokens-design.md new file mode 100644 index 0000000..b1c7e04 --- /dev/null +++ b/docs/superpowers/specs/2026-04-02-design-tokens-design.md @@ -0,0 +1,240 @@ +# Design Tokens — Multi-Hospital Theming + +**Date**: 2026-04-02 +**Status**: Draft + +--- + +## Overview + +A JSON-driven design token system that allows each hospital customer to rebrand Helix Engage by providing a single JSON configuration file. The JSON is served by the sidecar, consumed by the frontend at runtime via a React provider that injects CSS custom properties. + +--- + +## Architecture + +``` +Sidecar (helix-engage-server) + └─ GET /api/config/theme → returns hospital theme JSON + └─ theme stored as JSON file at data/theme.json (editable, hot-reloadable) + +Frontend (helix-engage) + └─ ThemeTokenProvider (wraps app) → fetches theme JSON on mount + └─ Injects CSS custom properties on element + └─ Exposes useThemeTokens() hook for content tokens (logo, name, text) + └─ Components read colors via existing Tailwind classes (no changes needed) +``` + +--- + +## Theme JSON Schema + +```json +{ + "brand": { + "name": "Helix Engage", + "hospitalName": "Global Hospital", + "logo": "/helix-logo.png", + "favicon": "/favicon.ico" + }, + "colors": { + "brand": { + "25": "rgb(239 246 255)", + "50": "rgb(219 234 254)", + "100": "rgb(191 219 254)", + "200": "rgb(147 197 253)", + "300": "rgb(96 165 250)", + "400": "rgb(59 130 246)", + "500": "rgb(37 99 235)", + "600": "rgb(29 78 216)", + "700": "rgb(30 64 175)", + "800": "rgb(30 58 138)", + "900": "rgb(23 37 84)", + "950": "rgb(15 23 42)" + } + }, + "typography": { + "body": "Satoshi, Inter, -apple-system, sans-serif", + "display": "General Sans, Inter, -apple-system, sans-serif" + }, + "login": { + "title": "Sign in to Helix Engage", + "subtitle": "Global Hospital", + "showGoogleSignIn": true, + "showForgotPassword": true, + "poweredBy": { + "label": "Powered by F0rty2.ai", + "url": "https://f0rty2.ai" + } + }, + "sidebar": { + "title": "Helix Engage", + "subtitle": "Global Hospital · Call Center Agent" + }, + "ai": { + "quickActions": [ + { "label": "Doctor availability", "prompt": "What doctors are available?" }, + { "label": "Clinic timings", "prompt": "What are the clinic timings?" }, + { "label": "Patient history", "prompt": "Summarize this patient's history" }, + { "label": "Treatment packages", "prompt": "What packages are available?" } + ] + } +} +``` + +--- + +## Sidecar Implementation + +### Endpoints + +``` +GET /api/config/theme — Returns theme JSON (no auth, public — needed before login) +PUT /api/config/theme — Updates theme JSON (auth required, admin only) +POST /api/config/theme/reset — Resets to default theme (auth required, admin only) +``` + +- Stored in `data/theme.json` on the sidecar filesystem +- Cached in memory, invalidated on PUT +- If file doesn't exist, returns a hardcoded default (Global Hospital theme) +- PUT validates the JSON schema before saving +- PUT also writes a timestamped backup to `data/theme-backups/` + +### Files + +- `helix-engage-server/src/config/theme.controller.ts` — REST endpoints +- `helix-engage-server/src/config/theme.service.ts` — read/write/validate/backup logic + +--- + +## Frontend Implementation + +### ThemeTokenProvider + +New provider wrapping the app in `main.tsx`. Responsibilities: + +1. **Fetch** `GET /api/config/theme` on mount (before rendering anything) +2. **Inject CSS variables** on `document.documentElement.style`: + - `--color-brand-25` through `--color-brand-950` (overrides the Untitled UI brand scale) + - `--font-body`, `--font-display` (overrides typography) +3. **Store content tokens** in React context (brand name, logo, login text, sidebar text, quick actions) +4. **Expose** `useThemeTokens()` hook for components to read content tokens + +### File: `src/providers/theme-token-provider.tsx` + +```tsx +type ThemeTokens = { + brand: { name: string; hospitalName: string; logo: string; favicon: string }; + login: { title: string; subtitle: string; showGoogleSignIn: boolean; showForgotPassword: boolean; poweredBy: { label: string; url: string } }; + sidebar: { title: string; subtitle: string }; + ai: { quickActions: Array<{ label: string; prompt: string }> }; +}; +``` + +### CSS Variable Injection + +The provider maps `colors.brand.*` to CSS custom properties that Untitled UI already reads: + +``` +theme.colors.brand["500"] → document.documentElement.style.setProperty('--color-brand-500', value) +``` + +Since `theme.css` defines `--color-brand-500: var(--color-blue-500)`, setting `--color-brand-500` directly on `` overrides the alias with higher specificity. + +Typography: +``` +theme.typography.body → --font-body +theme.typography.display → --font-display +``` + +### Consumers + +Components that currently hardcode hospital-specific content: + +| Component | Current hardcoded value | Token path | +|---|---|---| +| `login.tsx` line 93 | "Sign in to Helix Engage" | `login.title` | +| `login.tsx` line 94 | "Global Hospital" | `login.subtitle` | +| `login.tsx` line 92 | `/helix-logo.png` | `brand.logo` | +| `login.tsx` line 181 | "Powered by F0rty2.ai" | `login.poweredBy.label` | +| `sidebar.tsx` | "Helix Engage" | `sidebar.title` | +| `sidebar.tsx` | "Global Hospital · Call Center Agent" | `sidebar.subtitle` | +| `ai-chat-panel.tsx` lines 21-25 | Quick action prompts | `ai.quickActions` | +| `app-shell.tsx` | favicon | `brand.favicon` | + +--- + +## Default Theme + +If the sidecar returns no theme (endpoint down, file missing), the frontend uses a hardcoded default matching the current Global Hospital branding. This ensures the app works without a sidecar theme endpoint. + +--- + +## Settings UI (Supervisor) + +New tab in the Settings page: **Branding**. Visible only to admin role. + +### Sections + +**1. Brand Identity** +- Hospital name (text input) +- App name (text input) +- Logo upload (file input → stores URL) +- Favicon upload + +**2. Brand Colors** +- 12 color swatches (25 through 950) with hex/rgb input per swatch +- Live preview strip showing the full scale +- "Reset to default" button per section + +**3. Typography** +- Body font family (text input with common font suggestions) +- Display font family (text input) + +**4. Login Page** +- Title text +- Subtitle text +- Show Google sign-in (toggle) +- Show forgot password (toggle) +- Powered-by label + URL + +**5. Sidebar** +- Title text +- Subtitle template (supports `{role}` placeholder — "Global Hospital · {role}") + +**6. AI Quick Actions** +- Editable list of label + prompt pairs +- Add / remove / reorder + +### Save Flow +- Supervisor edits fields → clicks Save → `PUT /api/config/theme` → sidecar validates + saves + backs up +- Frontend re-fetches theme on save → CSS variables update → page reflects changes immediately (no reload needed) + +### File +`src/pages/settings.tsx` — new "Branding" tab (or `src/pages/branding-settings.tsx` if settings page is already complex) + +--- + +## What This Does NOT Change + +- **Tailwind classes** — no changes. Components continue using `text-brand-secondary`, `bg-brand-solid`, etc. The CSS variables they reference are overridden at runtime. +- **Component structure** — no layout changes. Only content strings and colors change. +- **Untitled UI theme.css** — not modified. The provider overrides are applied inline on ``, higher specificity. + +--- + +## Scope + +**In scope:** +- Sidecar theme endpoint + JSON file +- ThemeTokenProvider + useThemeTokens hook +- Login page consuming tokens +- Sidebar consuming tokens +- AI quick actions consuming tokens +- Brand color override via CSS variables +- Typography override via CSS variables + +**Out of scope:** +- Dark mode customization (inherits from Untitled UI) +- Per-role theming +- Logo upload to cloud storage (uses URL for now — can be a data URI or hosted path) diff --git a/docs/weekly-update-mar18-25.html b/docs/weekly-update-mar18-25.html new file mode 100644 index 0000000..b9cc274 --- /dev/null +++ b/docs/weekly-update-mar18-25.html @@ -0,0 +1,886 @@ + + + + + + Helix Engage — Weekly Update (Mar 18–25, 2026) + + + + + + +
+ + + + + +
+ + +
+ or Space to navigate +
+ + +
+
+ Weekly Engineering Update +
+

Helix Engage

+

Contact Center CRM · Real-time Telephony · AI Copilot

+

March 18 – 25, 2026

+
+ + +
+
+ At a Glance +
+

Week in Numbers

+
+
+
0
+
Total Commits
+
+
+
0
+
Repositories
+
+
+
0
+
Days Active
+
+
+
0
+
Frontend Commits
+
+
+
+ helix-engage 50 + helix-engage-server 27 + FortyTwoApps/SDK 1 +
+
+ + +
+
+
+
📞
+ Core Infrastructure +
+
+

Telephony & SIP Overhaul

+
+
+

Outbound Calling Frontend

+
    +
  • Direct SIP call from browser — no Kookoo bridge needed
  • +
  • Immediate call card UI with auto-answer SIP bridge
  • +
  • End Call label fix, force active state after auto-answer
  • +
  • Reset outboundPending on call end to prevent inbound poisoning
  • +
+
+
+

Ozonetel Integration Server

+
    +
  • Ozonetel V3 dial endpoint + webhook handler for call events
  • +
  • Kookoo IVR outbound bridging (deprecated → direct SIP)
  • +
  • Set Disposition API for ACW release
  • +
  • Force Ready endpoint for agent state management
  • +
  • Token: 10-min cache, 401 invalidation, refresh on login
  • +
+
+
+

SIP & Agent State Frontend

+
    +
  • SIP driven by Agent entity with token refresh
  • +
  • Dynamic SIP from agentConfig, logout cleanup, heartbeat
  • +
  • Centralised outbound dial into useSip().dialOutbound()
  • +
  • UCID tracking from SIP headers for Ozonetel disposition
  • +
  • Network indicator for connection health
  • +
+
+
+

Multi-Agent & Sessions Server

+
    +
  • Multi-agent SIP with Redis session lockout
  • +
  • Strict duplicate login lockout — one device per agent
  • +
  • Session lock stores IP + timestamp for debugging
  • +
  • SSE agent state broadcast for real-time supervisor view
  • +
+
+
+
+ + +
+
+
+
🖥️
+ User Experience +
+
+

Call Desk & Agent UX

+
+
+

Call Desk Redesign

+
    +
  • 2-panel layout with collapsible sidebar & inline AI
  • +
  • Collapsible context panel, worklist/calls tabs, phone numbers
  • +
  • Pinned header & chat input, numpad dialler
  • +
  • Ringtone support for incoming calls
  • +
+
+
+

Post-Call Workflow

+
    +
  • Disposition → appointment booking → follow-up creation
  • +
  • Disposition returns straight to worklist — no intermediate screens
  • +
  • Send disposition to sidecar with UCID for Ozonetel ACW
  • +
  • Enquiry in post-call, appointment skip button
  • +
+
+
+

UI Polish

+
    +
  • FontAwesome Pro Duotone icon migration (all icons)
  • +
  • Tooltips, sticky headers, roles, search, AI prompts
  • +
  • Fix React error #520 (isRowHeader) in production tables
  • +
  • AI scroll containment, brand tokens refresh
  • +
+
+
+
+ + +
+
+
+
🚀
+ Features Shipped +
+
+

Major Features

+
+
+

Supervisor Module

+
    +
  • Team performance analytics page
  • +
  • Live monitor with active calls visibility
  • +
  • Master data management pages
  • +
  • Server: team perf + active calls endpoints
  • +
+
+
+

Missed Call Queue (Phase 2)

+
    +
  • Missed call queue ingestion & worklist
  • +
  • Auto-assignment engine for agents
  • +
  • Login redesign with role-based routing
  • +
  • Lead lookup for missed callers
  • +
+
+
+

Agent Features (Phase 1)

+
    +
  • Agent status toggle (Ready / Not Ready / Break)
  • +
  • Global search across patients, leads, calls
  • +
  • Enquiry form for new patient intake
  • +
  • My Performance page + logout modal
  • +
+
+
+

Recording Analysis

+
    +
  • Deepgram diarization + AI insights
  • +
  • Redis caching layer for analysis results
  • +
  • Full-stack: frontend player + server module
  • +
+
+
+
+ + +
+
+
+
⚙️
+ Backend & Data +
+
+

Backend & Data Layer

+
+
+

Platform Data Wiring

+
    +
  • Migrated frontend to Jotai + Vercel AI SDK
  • +
  • Corrected all 7 GraphQL queries (field names, LINKS/PHONES)
  • +
  • Webhook handler for Ozonetel call records
  • +
  • Complete seeder: 5 doctors, appointments linked, agent names match
  • +
+
+
+

Server Endpoints

+
    +
  • Call control, recording, CDR, missed calls, live call assist
  • +
  • Agent summary, AHT, performance aggregation
  • +
  • Token refresh endpoint for auto-renewal
  • +
  • Search module with full-text capabilities
  • +
+
+
+

Data Pages Built

+
    +
  • Worklist table, call history, patients, dashboard
  • +
  • Reports, team dashboard, campaigns, settings
  • +
  • Agent detail page, campaign edit slideout
  • +
  • Appointments page with data refresh on login
  • +
+
+
+

SDK App FortyTwoApps

+
    +
  • Helix Engage SDK app entity definitions
  • +
  • Call center CRM object model for Fortytwo platform
  • +
  • Foundation for platform-native data integration
  • +
+
+
+
+ + +
+
+
+
🛠️
+ Operations +
+
+

Deployment & DevOps

+
+
+

Deployment

+
    +
  • Deployed to Hostinger VPS with Docker
  • +
  • Switched to global_healthx Ozonetel account
  • +
  • Dockerfile for server-side containerization
  • +
+
+
+

AI & Testing

+
    +
  • Migrated AI to Vercel AI SDK + OpenAI provider
  • +
  • AI flow test script — validates auth, lead, patient, doctor, appointments
  • +
  • Live call assist integration
  • +
+
+
+

Documentation

+
    +
  • Team onboarding README with architecture guide
  • +
  • Supervisor module spec + implementation plan
  • +
  • Multi-agent spec + plan
  • +
  • Next session plans documented in commits
  • +
+
+
+
+ + +
+
+
+
📅
+ Day by Day +
+
+

Development Timeline

+
+
+
MAR 18 (Tue)
+
Foundation Day
+
Call desk redesign, Jotai + Vercel AI SDK migration, seeder with 5 doctors + linked appointments, AI flow test script, deployed to VPS
+
+
+
MAR 19 (Wed)
+
Data Layer Sprint
+
All data pages built (worklist, call history, patients, dashboard, reports), post-call workflow (disposition → booking), GraphQL fixes, Kookoo IVR outbound, outbound call UI
+
+
+
MAR 20 (Thu)
+
Telephony Breakthrough
+
Direct SIP call from browser replacing Kookoo bridge, UCID tracking, Force Ready, Ozonetel Set Disposition, telephony overhaul
+
+
+
MAR 21 (Fri)
+
Agent Experience
+
Phase 1 shipped — agent status toggle, global search, enquiry form, My Performance page, full FontAwesome icon migration, agent summary/AHT endpoints
+
+
+
MAR 23 (Sun)
+
Scale & Reliability
+
Phase 2 — missed call queue + auto-assignment, multi-agent SIP with Redis lockout, duplicate login prevention, Patient 360 rewrite, onboarding docs, SDK entity defs
+
+
+
MAR 24 (Mon)
+
Supervisor Module
+
Supervisor module with team performance + live monitor + master data, SSE agent state, UUID fix, maintenance module, QA bug sweep, supervisor endpoints
+
+
+
MAR 25 (Tue)
+
Intelligence Layer
+
Call recording analysis with Deepgram diarization + AI insights, SIP driven by Agent entity, token refresh, network indicator
+
+
+
+ + +
+

78 commits. 8 days. Ship mode. 🚢

+

+ From browser-native SIP calling to AI-powered recording analysis — Helix Engage is becoming a production contact center platform. +

+
+ SIP Calling ✓ + Multi-Agent ✓ + Supervisor Module ✓ + AI Copilot ✓ + Recording Analysis ✓ +
+

Satya Suman Sari · FortyTwo Platform

+
+ + + + + diff --git a/docs/weekly-update-mar18-25.pptx b/docs/weekly-update-mar18-25.pptx new file mode 100644 index 0000000..d61bc12 Binary files /dev/null and b/docs/weekly-update-mar18-25.pptx differ diff --git a/package-lock.json b/package-lock.json index 8633c04..02e4dc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7006 +1,6455 @@ { - "name": "helix-engage", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "helix-engage", - "version": "0.1.0", - "dependencies": { - "@fortawesome/fontawesome-svg-core": "^7.2.0", - "@fortawesome/free-solid-svg-icons": "^7.2.0", - "@fortawesome/pro-duotone-svg-icons": "^7.2.0", - "@fortawesome/pro-light-svg-icons": "^7.2.0", - "@fortawesome/pro-regular-svg-icons": "^7.2.0", - "@fortawesome/pro-solid-svg-icons": "^7.2.0", - "@fortawesome/react-fontawesome": "^3.2.0", - "@tailwindcss/typography": "^0.5.19", - "@tailwindcss/vite": "^4.1.18", - "@untitledui/file-icons": "^0.0.8", - "@untitledui/icons": "^0.0.21", - "echarts": "^6.0.0", - "echarts-for-react": "^3.0.6", - "input-otp": "^1.4.2", - "jotai": "^2.18.1", - "jssip": "^3.13.6", - "motion": "^12.29.0", - "qr-code-styling": "^1.9.2", - "react": "^19.2.3", - "react-aria": "^3.46.0", - "react-aria-components": "^1.16.0", - "react-dom": "^19.2.3", - "react-hotkeys-hook": "^5.2.3", - "react-router": "^7.13.0", - "socket.io-client": "^4.8.3", - "sonner": "^2.0.7", - "tailwind-merge": "^3.5.0", - "tailwindcss": "^4.1.18", - "tailwindcss-animate": "^1.0.7", - "tailwindcss-react-aria-components": "^2.0.1" - }, - "devDependencies": { - "@eslint/js": "^10.0.1", - "@tailwindcss/postcss": "^4.1.18", - "@trivago/prettier-plugin-sort-imports": "^5.2.2", - "@types/jssip": "^3.5.3", - "@types/node": "^24.10.9", - "@types/react": "^19.2.9", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react-swc": "^4.2.2", - "eslint": "^10.1.0", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.5.2", - "globals": "^16.5.0", - "husky": "^9.1.7", - "lint-staged": "^16.4.0", - "prettier": "^3.8.1", - "prettier-plugin-tailwindcss": "^0.6.14", - "typescript": "^5.9.3", - "typescript-eslint": "^8.53.1", - "vite": "^7.3.1" - } - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "http://localhost:4873/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "http://localhost:4873/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "http://localhost:4873/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "http://localhost:4873/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "http://localhost:4873/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "http://localhost:4873/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.0", - "resolved": "http://localhost:4873/@babel/parser/-/parser-7.29.0.tgz", - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "http://localhost:4873/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "http://localhost:4873/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "http://localhost:4873/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", - "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/android-arm/-/android-arm-0.27.4.tgz", - "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", - "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/android-x64/-/android-x64-0.27.4.tgz", - "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", - "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", - "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", - "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", - "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", - "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", - "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", - "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", - "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", - "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", - "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", - "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", - "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", - "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", - "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", - "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", - "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", - "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", - "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", - "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", - "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", - "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.27.4", - "resolved": "http://localhost:4873/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", - "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "http://localhost:4873/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "http://localhost:4873/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "http://localhost:4873/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.23.3", - "resolved": "http://localhost:4873/@eslint/config-array/-/config-array-0.23.3.tgz", - "integrity": "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^3.0.3", - "debug": "^4.3.1", - "minimatch": "^10.2.4" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.5.3", - "resolved": "http://localhost:4873/@eslint/config-helpers/-/config-helpers-0.5.3.tgz", - "integrity": "sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^1.1.1" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - } - }, - "node_modules/@eslint/core": { - "version": "1.1.1", - "resolved": "http://localhost:4873/@eslint/core/-/core-1.1.1.tgz", - "integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - } - }, - "node_modules/@eslint/js": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", - "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "eslint": "^10.0.0" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true + "name": "helix-engage", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "helix-engage", + "version": "0.1.0", + "dependencies": { + "@ai-sdk/react": "^1.2.12", + "@fortawesome/fontawesome-svg-core": "^7.2.0", + "@fortawesome/free-solid-svg-icons": "^7.2.0", + "@fortawesome/pro-duotone-svg-icons": "^7.2.0", + "@fortawesome/pro-light-svg-icons": "^7.2.0", + "@fortawesome/pro-regular-svg-icons": "^7.2.0", + "@fortawesome/pro-solid-svg-icons": "^7.2.0", + "@fortawesome/react-fontawesome": "^3.2.0", + "@tailwindcss/typography": "^0.5.19", + "@tailwindcss/vite": "^4.1.18", + "@untitledui/file-icons": "^0.0.8", + "@untitledui/icons": "^0.0.21", + "echarts": "^6.0.0", + "echarts-for-react": "^3.0.6", + "input-otp": "^1.4.2", + "jotai": "^2.18.1", + "jssip": "^3.13.6", + "motion": "^12.29.0", + "pptxgenjs": "^4.0.1", + "qr-code-styling": "^1.9.2", + "react": "^19.2.3", + "react-aria": "^3.46.0", + "react-aria-components": "^1.16.0", + "react-dom": "^19.2.3", + "react-hotkeys-hook": "^5.2.3", + "react-router": "^7.13.0", + "socket.io-client": "^4.8.3", + "sonner": "^2.0.7", + "tailwind-merge": "^3.5.0", + "tailwindcss": "^4.1.18", + "tailwindcss-animate": "^1.0.7", + "tailwindcss-react-aria-components": "^2.0.1" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.18", + "@trivago/prettier-plugin-sort-imports": "^5.2.2", + "@types/jssip": "^3.5.3", + "@types/node": "^24.10.9", + "@types/react": "^19.2.9", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react-swc": "^4.2.2", + "globals": "^16.5.0", + "prettier": "^3.8.1", + "prettier-plugin-tailwindcss": "^0.6.14", + "typescript": "^5.9.3", + "typescript-eslint": "^8.53.1", + "vite": "^7.3.1" + } + }, + "node_modules/@ai-sdk/provider": { + "version": "1.1.3", + "resolved": "http://localhost:4873/@ai-sdk/provider/-/provider-1.1.3.tgz", + "integrity": "sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==", + "license": "Apache-2.0", + "dependencies": { + "json-schema": "^0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ai-sdk/provider-utils": { + "version": "2.2.8", + "resolved": "http://localhost:4873/@ai-sdk/provider-utils/-/provider-utils-2.2.8.tgz", + "integrity": "sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "1.1.3", + "nanoid": "^3.3.8", + "secure-json-parse": "^2.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.23.8" + } + }, + "node_modules/@ai-sdk/react": { + "version": "1.2.12", + "resolved": "http://localhost:4873/@ai-sdk/react/-/react-1.2.12.tgz", + "integrity": "sha512-jK1IZZ22evPZoQW3vlkZ7wvjYGYF+tRBKXtrcolduIkQ/m/sOAVcVeVDUDvh1T91xCnWCdUGCPZg2avZ90mv3g==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider-utils": "2.2.8", + "@ai-sdk/ui-utils": "1.2.11", + "swr": "^2.2.5", + "throttleit": "2.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@ai-sdk/ui-utils": { + "version": "1.2.11", + "resolved": "http://localhost:4873/@ai-sdk/ui-utils/-/ui-utils-1.2.11.tgz", + "integrity": "sha512-3zcwCc8ezzFlwp3ZD15wAPjf2Au4s3vAbKsXQVyhxODHcmu0iyPO2Eua6D/vicq/AUm/BAo60r97O6HU+EI0+w==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "1.1.3", + "@ai-sdk/provider-utils": "2.2.8", + "zod-to-json-schema": "^3.24.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.23.8" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "http://localhost:4873/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "http://localhost:4873/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "http://localhost:4873/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "http://localhost:4873/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "http://localhost:4873/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "http://localhost:4873/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "http://localhost:4873/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "http://localhost:4873/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "http://localhost:4873/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "http://localhost:4873/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.4", + "resolved": "http://localhost:4873/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "http://localhost:4873/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "http://localhost:4873/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "http://localhost:4873/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.3", + "resolved": "http://localhost:4873/@eslint/config-array/-/config-array-0.23.3.tgz", + "integrity": "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@eslint/object-schema": "^3.0.3", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.3", + "resolved": "http://localhost:4873/@eslint/config-helpers/-/config-helpers-0.5.3.tgz", + "integrity": "sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@eslint/core": "^1.1.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.1.1", + "resolved": "http://localhost:4873/@eslint/core/-/core-1.1.1.tgz", + "integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.3", + "resolved": "http://localhost:4873/@eslint/object-schema/-/object-schema-3.0.3.tgz", + "integrity": "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.6.1", + "resolved": "http://localhost:4873/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", + "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@eslint/core": "^1.1.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "2.3.6", + "resolved": "http://localhost:4873/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz", + "integrity": "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==", + "license": "MIT", + "dependencies": { + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/intl-localematcher": "0.6.2", + "decimal.js": "^10.4.3", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "2.2.7", + "resolved": "http://localhost:4873/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz", + "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.11.4", + "resolved": "http://localhost:4873/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz", + "integrity": "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==", + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/icu-skeleton-parser": "1.8.16", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.16", + "resolved": "http://localhost:4873/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz", + "integrity": "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==", + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.6.2", + "resolved": "http://localhost:4873/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz", + "integrity": "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "7.2.0", + "resolved": "https://npm.fontawesome.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.2.0.tgz", + "integrity": "sha512-IpR0bER9FY25p+e7BmFH25MZKEwFHTfRAfhOyJubgiDnoJNsSvJ7nigLraHtp4VOG/cy8D7uiV0dLkHOne5Fhw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "7.2.0", + "resolved": "https://npm.fontawesome.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-7.2.0.tgz", + "integrity": "sha512-6639htZMjEkwskf3J+e6/iar+4cTNM9qhoWuRfj9F3eJD6r7iCzV1SWnQr2Mdv0QT0suuqU8BoJCZUyCtP9R4Q==", + "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-common-types": "7.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "7.2.0", + "resolved": "https://npm.fontawesome.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-7.2.0.tgz", + "integrity": "sha512-YTVITFGN0/24PxzXrwqCgnyd7njDuzp5ZvaCx5nq/jg55kUYd94Nj8UTchBdBofi/L0nwRfjGOg0E41d2u9T1w==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "7.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/pro-duotone-svg-icons": { + "version": "7.2.0", + "resolved": "https://npm.fontawesome.com/@fortawesome/pro-duotone-svg-icons/-/pro-duotone-svg-icons-7.2.0.tgz", + "integrity": "sha512-G0oZPLWrOjodNsKEzjnmZ/wzXCQhyXHsscIuCsRwPr42N0zgMmVvClZuEq6eqiBiyo1qhm3RnN6xNLddJh9z7A==", + "license": "UNLICENSED", + "dependencies": { + "@fortawesome/fontawesome-common-types": "7.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/pro-light-svg-icons": { + "version": "7.2.0", + "resolved": "https://npm.fontawesome.com/@fortawesome/pro-light-svg-icons/-/pro-light-svg-icons-7.2.0.tgz", + "integrity": "sha512-0SZf+Lu4DoolJelZi9Cc1Ta2VqUGkvV6BPxCb22mV16GQhqGa2VuLkqAn7zur0Sy8Cinu6MyPRfndHSe72zYyQ==", + "license": "UNLICENSED", + "dependencies": { + "@fortawesome/fontawesome-common-types": "7.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/pro-regular-svg-icons": { + "version": "7.2.0", + "resolved": "https://npm.fontawesome.com/@fortawesome/pro-regular-svg-icons/-/pro-regular-svg-icons-7.2.0.tgz", + "integrity": "sha512-FU6amNj6Dbsb2m19T8ABiL8HoImIGm8AhxnPAgQDDZcslGezu6R7HrDicBPJuVTNFSxFGRRAXIRs/z44xg7ftA==", + "license": "UNLICENSED", + "dependencies": { + "@fortawesome/fontawesome-common-types": "7.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/pro-solid-svg-icons": { + "version": "7.2.0", + "resolved": "https://npm.fontawesome.com/@fortawesome/pro-solid-svg-icons/-/pro-solid-svg-icons-7.2.0.tgz", + "integrity": "sha512-r+YsuG1B+iYcCXNS82bfvRnGJtlRhVI5Xk7vVJ9+ymJU5u4UGGGOSFRV5kRWH2zFItH9PKaIjnN1cXMcgOM/+g==", + "license": "UNLICENSED", + "dependencies": { + "@fortawesome/fontawesome-common-types": "7.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "3.2.0", + "resolved": "https://npm.fontawesome.com/@fortawesome/react-fontawesome/-/react-fontawesome-3.2.0.tgz", + "integrity": "sha512-E9Gu1hqd6JussVO26EC4WqRZssXMnQr2ol7ZNWkkFOH8jZUaxDJ9Z9WF9wIVkC+kJGXUdY3tlffpDwEKfgQrQw==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~6 || ~7", + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "http://localhost:4873/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "http://localhost:4873/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "http://localhost:4873/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "http://localhost:4873/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@internationalized/date": { + "version": "3.12.0", + "resolved": "http://localhost:4873/@internationalized/date/-/date-3.12.0.tgz", + "integrity": "sha512-/PyIMzK29jtXaGU23qTvNZxvBXRtKbNnGDFD+PY6CZw/Y8Ex8pFUzkuCJCG9aOqmShjqhS9mPqP6Dk5onQY8rQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@internationalized/message": { + "version": "3.1.8", + "resolved": "http://localhost:4873/@internationalized/message/-/message-3.1.8.tgz", + "integrity": "sha512-Rwk3j/TlYZhn3HQ6PyXUV0XP9Uv42jqZGNegt0BXlxjE6G3+LwHjbQZAGHhCnCPdaA6Tvd3ma/7QzLlLkJxAWA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "intl-messageformat": "^10.1.0" + } + }, + "node_modules/@internationalized/number": { + "version": "3.6.5", + "resolved": "http://localhost:4873/@internationalized/number/-/number-3.6.5.tgz", + "integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@internationalized/string": { + "version": "3.2.7", + "resolved": "http://localhost:4873/@internationalized/string/-/string-3.2.7.tgz", + "integrity": "sha512-D4OHBjrinH+PFZPvfCXvG28n2LSykWcJ7GIioQL+ok0LON15SdfoUssoHzzOUmVZLbRoREsQXVzA6r8JKsbP6A==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "http://localhost:4873/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "http://localhost:4873/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "http://localhost:4873/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "http://localhost:4873/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "http://localhost:4873/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@react-aria/autocomplete": { + "version": "3.0.0-rc.6", + "resolved": "http://localhost:4873/@react-aria/autocomplete/-/autocomplete-3.0.0-rc.6.tgz", + "integrity": "sha512-uymUNJ8NW+dX7lmgkHE+SklAbxwktycAJcI5lBBw6KPZyc0EdMHC+/Fc5CUz3enIAhNwd2oxxogcSHknquMzQA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/combobox": "^3.15.0", + "@react-aria/focus": "^3.21.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/listbox": "^3.15.3", + "@react-aria/searchfield": "^3.8.12", + "@react-aria/textfield": "^3.18.5", + "@react-aria/utils": "^3.33.1", + "@react-stately/autocomplete": "3.0.0-beta.4", + "@react-stately/combobox": "^3.13.0", + "@react-types/autocomplete": "3.0.0-alpha.38", + "@react-types/button": "^3.15.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/breadcrumbs": { + "version": "3.5.32", + "resolved": "http://localhost:4873/@react-aria/breadcrumbs/-/breadcrumbs-3.5.32.tgz", + "integrity": "sha512-S61vh5DJ2PXiXUwD7gk+pvS/b4VPrc3ZJOUZ0yVRLHkVESr5LhIZH+SAVgZkm1lzKyMRG+BH+fiRH/DZRSs7SA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/i18n": "^3.12.16", + "@react-aria/link": "^3.8.9", + "@react-aria/utils": "^3.33.1", + "@react-types/breadcrumbs": "^3.7.19", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/button": { + "version": "3.14.5", + "resolved": "http://localhost:4873/@react-aria/button/-/button-3.14.5.tgz", + "integrity": "sha512-ZuLx+wQj9VQhH9BYe7t0JowmKnns2XrFHFNvIVBb5RwxL+CIycIOL7brhWKg2rGdxvlOom7jhVbcjSmtAaSyaQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/toolbar": "3.0.0-beta.24", + "@react-aria/utils": "^3.33.1", + "@react-stately/toggle": "^3.9.5", + "@react-types/button": "^3.15.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/calendar": { + "version": "3.9.5", + "resolved": "http://localhost:4873/@react-aria/calendar/-/calendar-3.9.5.tgz", + "integrity": "sha512-k0kvceYdZZu+DoeqephtlmIvh1CxqdFyoN52iqVzTz9O0pe5Xfhq7zxPGbeCp4pC61xzp8Lu/6uFA/YNfQQNag==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.0", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/utils": "^3.33.1", + "@react-stately/calendar": "^3.9.3", + "@react-types/button": "^3.15.1", + "@react-types/calendar": "^3.8.3", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/checkbox": { + "version": "3.16.5", + "resolved": "http://localhost:4873/@react-aria/checkbox/-/checkbox-3.16.5.tgz", + "integrity": "sha512-ZhUT7ELuD52hb+Zpzw0ElLQiVOd5sKYahrh+PK3vq13Wk5TedBscALpjuXetI4pwFfdmAM1Lhgcsrd8+6AmyvA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/form": "^3.1.5", + "@react-aria/interactions": "^3.27.1", + "@react-aria/label": "^3.7.25", + "@react-aria/toggle": "^3.12.5", + "@react-aria/utils": "^3.33.1", + "@react-stately/checkbox": "^3.7.5", + "@react-stately/form": "^3.2.4", + "@react-stately/toggle": "^3.9.5", + "@react-types/checkbox": "^3.10.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/collections": { + "version": "3.0.3", + "resolved": "http://localhost:4873/@react-aria/collections/-/collections-3.0.3.tgz", + "integrity": "sha512-lbC5DEbHeVFvVr4ke9y8D9Nynnr8G8UjVEBoFGRylpAaScU7SX1TN84QI+EjMbsdZ0/5P2H7gUTS+MYd+6U3Rg==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.33.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/color": { + "version": "3.1.5", + "resolved": "http://localhost:4873/@react-aria/color/-/color-3.1.5.tgz", + "integrity": "sha512-eysWdBRzE8WDhBzh1nfjyUgzseMokXGHjIoJo880T7IPJ8tTavfQni49pU1B2qWrNOWPyrwx4Bd9pzHyboxJSA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/numberfield": "^3.12.5", + "@react-aria/slider": "^3.8.5", + "@react-aria/spinbutton": "^3.7.2", + "@react-aria/textfield": "^3.18.5", + "@react-aria/utils": "^3.33.1", + "@react-aria/visually-hidden": "^3.8.31", + "@react-stately/color": "^3.9.5", + "@react-stately/form": "^3.2.4", + "@react-types/color": "^3.1.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/combobox": { + "version": "3.15.0", + "resolved": "http://localhost:4873/@react-aria/combobox/-/combobox-3.15.0.tgz", + "integrity": "sha512-qSjQTFwKl3x1jCP2NRSJ6doZqAp6c2GTfoiFwWjaWg1IewwLsglaW6NnzqRDFiqFbDGgXPn4MqtC1VYEJ3NEjA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/listbox": "^3.15.3", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/menu": "^3.21.0", + "@react-aria/overlays": "^3.31.2", + "@react-aria/selection": "^3.27.2", + "@react-aria/textfield": "^3.18.5", + "@react-aria/utils": "^3.33.1", + "@react-stately/collections": "^3.12.10", + "@react-stately/combobox": "^3.13.0", + "@react-stately/form": "^3.2.4", + "@react-types/button": "^3.15.1", + "@react-types/combobox": "^3.14.0", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/datepicker": { + "version": "3.16.1", + "resolved": "http://localhost:4873/@react-aria/datepicker/-/datepicker-3.16.1.tgz", + "integrity": "sha512-6BltCVWt09yefTkGjb2gViGCwoddx9HKJiZbY9u6Es/Q+VhwNJQRtczbnZ3K32p262hIknukNf/5nZaCOI1AKA==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.0", + "@internationalized/number": "^3.6.5", + "@internationalized/string": "^3.2.7", + "@react-aria/focus": "^3.21.5", + "@react-aria/form": "^3.1.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/label": "^3.7.25", + "@react-aria/spinbutton": "^3.7.2", + "@react-aria/utils": "^3.33.1", + "@react-stately/datepicker": "^3.16.1", + "@react-stately/form": "^3.2.4", + "@react-types/button": "^3.15.1", + "@react-types/calendar": "^3.8.3", + "@react-types/datepicker": "^3.13.5", + "@react-types/dialog": "^3.5.24", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/dialog": { + "version": "3.5.34", + "resolved": "http://localhost:4873/@react-aria/dialog/-/dialog-3.5.34.tgz", + "integrity": "sha512-/x53Q5ynpW5Kv9637WYu7SrDfj3woSp6jJRj8l6teGnWW/iNZWYJETgzHfbxx+HPKYATCZesRoIeO2LnYIXyEA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/overlays": "^3.31.2", + "@react-aria/utils": "^3.33.1", + "@react-types/dialog": "^3.5.24", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/disclosure": { + "version": "3.1.3", + "resolved": "http://localhost:4873/@react-aria/disclosure/-/disclosure-3.1.3.tgz", + "integrity": "sha512-S3k7Wqrj+x0sWcP88Z1stSr5TIZmKEmx2rU7RB1O1/jPpbw5mgKnjtiriOlTh+kwdK11FkeqgxyHzAcBAR+FMQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.33.1", + "@react-stately/disclosure": "^3.0.11", + "@react-types/button": "^3.15.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/dnd": { + "version": "3.11.6", + "resolved": "http://localhost:4873/@react-aria/dnd/-/dnd-3.11.6.tgz", + "integrity": "sha512-4YLHUeYJleF+moAYaYt8UZqujudPvpoaHR+QMkWIFzhfridVUhCr6ZjGWrzpSZY3r68k46TG7YCsi4IEiNnysw==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/string": "^3.2.7", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/overlays": "^3.31.2", + "@react-aria/utils": "^3.33.1", + "@react-stately/collections": "^3.12.10", + "@react-stately/dnd": "^3.7.4", + "@react-types/button": "^3.15.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/focus": { + "version": "3.21.5", + "resolved": "http://localhost:4873/@react-aria/focus/-/focus-3.21.5.tgz", + "integrity": "sha512-V18fwCyf8zqgJdpLQeDU5ZRNd9TeOfBbhLgmX77Zr5ae9XwaoJ1R3SFJG1wCJX60t34AW+aLZSEEK+saQElf3Q==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/utils": "^3.33.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/form": { + "version": "3.1.5", + "resolved": "http://localhost:4873/@react-aria/form/-/form-3.1.5.tgz", + "integrity": "sha512-BWlONgHn8hmaMkcS6AgMSLQeNqVBwqPNLhdqjDO/PCfzvV7O8NZw/dFeIzJwfG4aBfSpbHHRdXGdfrk3d8dylQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/utils": "^3.33.1", + "@react-stately/form": "^3.2.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/grid": { + "version": "3.14.8", + "resolved": "http://localhost:4873/@react-aria/grid/-/grid-3.14.8.tgz", + "integrity": "sha512-X6rRFKDu/Kh6Sv8FBap3vjcb+z4jXkSOwkYnexIJp5kMTo5/Dqo55cCBio5B70Tanfv32Ev/6SpzYG7ryxnM9w==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/selection": "^3.27.2", + "@react-aria/utils": "^3.33.1", + "@react-stately/collections": "^3.12.10", + "@react-stately/grid": "^3.11.9", + "@react-stately/selection": "^3.20.9", + "@react-types/checkbox": "^3.10.4", + "@react-types/grid": "^3.3.8", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/gridlist": { + "version": "3.14.4", + "resolved": "http://localhost:4873/@react-aria/gridlist/-/gridlist-3.14.4.tgz", + "integrity": "sha512-C/SbwC0qagZatoBrCjx8iZUex9apaJ8o8iRJ9eVHz0cpj7mXg6HuuotYGmDy9q67A2hve4I693RM1Cuwqwm+PQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/grid": "^3.14.8", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/selection": "^3.27.2", + "@react-aria/utils": "^3.33.1", + "@react-stately/list": "^3.13.4", + "@react-stately/tree": "^3.9.6", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/i18n": { + "version": "3.12.16", + "resolved": "http://localhost:4873/@react-aria/i18n/-/i18n-3.12.16.tgz", + "integrity": "sha512-Km2CAz6MFQOUEaattaW+2jBdWOHUF8WX7VQoNbjlqElCP58nSaqi9yxTWUDRhAcn8/xFUnkFh4MFweNgtrHuEA==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.0", + "@internationalized/message": "^3.1.8", + "@internationalized/number": "^3.6.5", + "@internationalized/string": "^3.2.7", + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.33.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/interactions": { + "version": "3.27.1", + "resolved": "http://localhost:4873/@react-aria/interactions/-/interactions-3.27.1.tgz", + "integrity": "sha512-M3wLpTTmDflI0QGNK0PJNUaBXXfeBXue8ZxLMngfc1piHNiH4G5lUvWd9W14XVbqrSCVY8i8DfGrNYpyyZu0tw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.33.1", + "@react-stately/flags": "^3.1.2", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/label": { + "version": "3.7.25", + "resolved": "http://localhost:4873/@react-aria/label/-/label-3.7.25.tgz", + "integrity": "sha512-oNK3Pqj4LDPwEbQaoM/uCip4QvQmmwGOh08VeW+vzSi6TAwf+KoWTyH/tiAeB0CHWNDK0k3e1iTygTAt4wzBmg==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/utils": "^3.33.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/landmark": { + "version": "3.0.10", + "resolved": "http://localhost:4873/@react-aria/landmark/-/landmark-3.0.10.tgz", + "integrity": "sha512-GpNjJaI8/a6WxYDZgzTCLYSzPM6xp2pxCIQ4udiGbTCtxx13Trmm0cPABvPtzELidgolCf05em9Phr+3G0eE8A==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/utils": "^3.33.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/link": { + "version": "3.8.9", + "resolved": "http://localhost:4873/@react-aria/link/-/link-3.8.9.tgz", + "integrity": "sha512-UaAFBfs84/Qq6TxlMWkREqqNY6SFLukot+z2Aa1kC+VyStv1kWG6sE5QLjm4SBn1Q3CGRsefhB/5+taaIbB4Pw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/utils": "^3.33.1", + "@react-types/link": "^3.6.7", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/listbox": { + "version": "3.15.3", + "resolved": "http://localhost:4873/@react-aria/listbox/-/listbox-3.15.3.tgz", + "integrity": "sha512-C6YgiyrHS5sbS5UBdxGMhEs+EKJYotJgGVtl9l0ySXpBUXERiHJWLOyV7a8PwkUOmepbB4FaLD7Y9EUzGkrGlw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/label": "^3.7.25", + "@react-aria/selection": "^3.27.2", + "@react-aria/utils": "^3.33.1", + "@react-stately/collections": "^3.12.10", + "@react-stately/list": "^3.13.4", + "@react-types/listbox": "^3.7.6", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/live-announcer": { + "version": "3.4.4", + "resolved": "http://localhost:4873/@react-aria/live-announcer/-/live-announcer-3.4.4.tgz", + "integrity": "sha512-PTTBIjNRnrdJOIRTDGNifY2d//kA7GUAwRFJNOEwSNG4FW+Bq9awqLiflw0JkpyB0VNIwou6lqKPHZVLsGWOXA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@react-aria/menu": { + "version": "3.21.0", + "resolved": "http://localhost:4873/@react-aria/menu/-/menu-3.21.0.tgz", + "integrity": "sha512-CKTVZ4izSE1eKIti6TbTtzJAUo+WT8O4JC0XZCYDBpa0f++lD19Kz9aY+iY1buv5xGI20gAfpO474E9oEd4aQA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/overlays": "^3.31.2", + "@react-aria/selection": "^3.27.2", + "@react-aria/utils": "^3.33.1", + "@react-stately/collections": "^3.12.10", + "@react-stately/menu": "^3.9.11", + "@react-stately/selection": "^3.20.9", + "@react-stately/tree": "^3.9.6", + "@react-types/button": "^3.15.1", + "@react-types/menu": "^3.10.7", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/meter": { + "version": "3.4.30", + "resolved": "http://localhost:4873/@react-aria/meter/-/meter-3.4.30.tgz", + "integrity": "sha512-ZmANKW7s/Z4QGylHi46nhwtQ47T1bfMsU9MysBu7ViXXNJ03F4b6JXCJlKL5o2goQ3NbfZ68GeWamIT0BWSgtw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/progress": "^3.4.30", + "@react-types/meter": "^3.4.15", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/numberfield": { + "version": "3.12.5", + "resolved": "http://localhost:4873/@react-aria/numberfield/-/numberfield-3.12.5.tgz", + "integrity": "sha512-Fi41IUWXEHLFIeJ/LHuZ9Azs8J/P563fZi37GSBkIq5P1pNt1rPgJJng5CNn4KsHxwqadTRUlbbZwbZraWDtRg==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/spinbutton": "^3.7.2", + "@react-aria/textfield": "^3.18.5", + "@react-aria/utils": "^3.33.1", + "@react-stately/form": "^3.2.4", + "@react-stately/numberfield": "^3.11.0", + "@react-types/button": "^3.15.1", + "@react-types/numberfield": "^3.8.18", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/overlays": { + "version": "3.31.2", + "resolved": "http://localhost:4873/@react-aria/overlays/-/overlays-3.31.2.tgz", + "integrity": "sha512-78HYI08r6LvcfD34gyv19ArRIjy1qxOKuXl/jYnjLDyQzD4pVb634IQWcm0zt10RdKgyuH6HTqvuDOgZTLet7Q==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.33.1", + "@react-aria/visually-hidden": "^3.8.31", + "@react-stately/flags": "^3.1.2", + "@react-stately/overlays": "^3.6.23", + "@react-types/button": "^3.15.1", + "@react-types/overlays": "^3.9.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/progress": { + "version": "3.4.30", + "resolved": "http://localhost:4873/@react-aria/progress/-/progress-3.4.30.tgz", + "integrity": "sha512-S6OWVGgluSWYSd/A6O8CVjz83eeMUfkuWSra0ewAV9bmxZ7TP9pUmD3bGdqHZEl97nt5vHGjZ3eq/x8eCmzKhA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/i18n": "^3.12.16", + "@react-aria/label": "^3.7.25", + "@react-aria/utils": "^3.33.1", + "@react-types/progress": "^3.5.18", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/radio": { + "version": "3.12.5", + "resolved": "http://localhost:4873/@react-aria/radio/-/radio-3.12.5.tgz", + "integrity": "sha512-8CCJKJzfozEiWBPO9QAATG1rBGJEJ+xoqvHf9LKU2sPFGsA2/SRnLs6LB9fCG5R3spvaK1xz0any1fjWPl7x8A==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/form": "^3.1.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/label": "^3.7.25", + "@react-aria/utils": "^3.33.1", + "@react-stately/radio": "^3.11.5", + "@react-types/radio": "^3.9.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/searchfield": { + "version": "3.8.12", + "resolved": "http://localhost:4873/@react-aria/searchfield/-/searchfield-3.8.12.tgz", + "integrity": "sha512-kYlUHD/+mWzNroHoR8ojUxYBoMviRZn134WaKPFjfNUGZDOEuh4XzOoj+cjdJfe6N3mwTaYu6rJQtunSHIAfhA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/i18n": "^3.12.16", + "@react-aria/textfield": "^3.18.5", + "@react-aria/utils": "^3.33.1", + "@react-stately/searchfield": "^3.5.19", + "@react-types/button": "^3.15.1", + "@react-types/searchfield": "^3.6.8", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/select": { + "version": "3.17.3", + "resolved": "http://localhost:4873/@react-aria/select/-/select-3.17.3.tgz", + "integrity": "sha512-u0UFWw0S7q9oiSbjetDpRoLLIcC+L89uYlm+YfCrdT8ntbQgABNiJRxdVvxnhR0fR6MC9ASTTvuQnNHNn52+1A==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/form": "^3.1.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/label": "^3.7.25", + "@react-aria/listbox": "^3.15.3", + "@react-aria/menu": "^3.21.0", + "@react-aria/selection": "^3.27.2", + "@react-aria/utils": "^3.33.1", + "@react-aria/visually-hidden": "^3.8.31", + "@react-stately/select": "^3.9.2", + "@react-types/button": "^3.15.1", + "@react-types/select": "^3.12.2", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/selection": { + "version": "3.27.2", + "resolved": "http://localhost:4873/@react-aria/selection/-/selection-3.27.2.tgz", + "integrity": "sha512-GbUSSLX/ciXix95KW1g+SLM9np7iXpIZrFDSXkC6oNx1uhy18eAcuTkeZE25+SY5USVUmEzjI3m/3JoSUcebbg==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/utils": "^3.33.1", + "@react-stately/selection": "^3.20.9", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/separator": { + "version": "3.4.16", + "resolved": "http://localhost:4873/@react-aria/separator/-/separator-3.4.16.tgz", + "integrity": "sha512-RCUtQhDGnPxKzyG8KM79yOB0fSiEf8r/rxShidOVnGLiBW2KFmBa22/Gfc4jnqg/keN3dxvkSGoqmeXgctyp6g==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/utils": "^3.33.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/slider": { + "version": "3.8.5", + "resolved": "http://localhost:4873/@react-aria/slider/-/slider-3.8.5.tgz", + "integrity": "sha512-gqkJxznk141mE0JamXF5CXml9PDbPkBz8dyKlihtWHWX4yhEbVYdC9J0otE7iCR3zx69Bm7WHoTGL0BsdpKzVA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/label": "^3.7.25", + "@react-aria/utils": "^3.33.1", + "@react-stately/slider": "^3.7.5", + "@react-types/shared": "^3.33.1", + "@react-types/slider": "^3.8.4", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/spinbutton": { + "version": "3.7.2", + "resolved": "http://localhost:4873/@react-aria/spinbutton/-/spinbutton-3.7.2.tgz", + "integrity": "sha512-adjE1wNCWlugvAtVXlXWPtIG9JWurEgYVn1Eeyh19x038+oXGvOsOAoKCXM+SnGleTWQ9J7pEZITFoEI3cVfAw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/i18n": "^3.12.16", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/utils": "^3.33.1", + "@react-types/button": "^3.15.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.9.10", + "resolved": "http://localhost:4873/@react-aria/ssr/-/ssr-3.9.10.tgz", + "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/switch": { + "version": "3.7.11", + "resolved": "http://localhost:4873/@react-aria/switch/-/switch-3.7.11.tgz", + "integrity": "sha512-dYVX71HiepBsKyeMaQgHbhqI+MQ3MVoTd5EnTbUjefIBnmQZavYj1/e4NUiUI4Ix+/C0HxL8ibDAv4NlSW3eLQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/toggle": "^3.12.5", + "@react-stately/toggle": "^3.9.5", + "@react-types/shared": "^3.33.1", + "@react-types/switch": "^3.5.17", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/table": { + "version": "3.17.11", + "resolved": "http://localhost:4873/@react-aria/table/-/table-3.17.11.tgz", + "integrity": "sha512-GkYmWPiW3OM+FUZxdS33teHXHXde7TjHuYgDDaG9phvg6cQTQjGilJozrzA3OfftTOq5VB8XcKTIQW3c0tpYsQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/grid": "^3.14.8", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/utils": "^3.33.1", + "@react-aria/visually-hidden": "^3.8.31", + "@react-stately/collections": "^3.12.10", + "@react-stately/flags": "^3.1.2", + "@react-stately/table": "^3.15.4", + "@react-types/checkbox": "^3.10.4", + "@react-types/grid": "^3.3.8", + "@react-types/shared": "^3.33.1", + "@react-types/table": "^3.13.6", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/tabs": { + "version": "3.11.1", + "resolved": "http://localhost:4873/@react-aria/tabs/-/tabs-3.11.1.tgz", + "integrity": "sha512-3Ppz7yaEDW9L7p9PE9yNOl5caLwNnnLQqI+MX/dwbWlw9HluHS7uIjb21oswNl6UbSxAWyENOka45+KN4Fkh7A==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/selection": "^3.27.2", + "@react-aria/utils": "^3.33.1", + "@react-stately/tabs": "^3.8.9", + "@react-types/shared": "^3.33.1", + "@react-types/tabs": "^3.3.22", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/tag": { + "version": "3.8.1", + "resolved": "http://localhost:4873/@react-aria/tag/-/tag-3.8.1.tgz", + "integrity": "sha512-VonpO++F8afXGDWc9VUxAc2wefyJpp1n9OGpbnB7zmqWiuPwO/RixjUdcH7iJkiC4vADwx9uLnhyD6kcwGV2ig==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/gridlist": "^3.14.4", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/label": "^3.7.25", + "@react-aria/selection": "^3.27.2", + "@react-aria/utils": "^3.33.1", + "@react-stately/list": "^3.13.4", + "@react-types/button": "^3.15.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/textfield": { + "version": "3.18.5", + "resolved": "http://localhost:4873/@react-aria/textfield/-/textfield-3.18.5.tgz", + "integrity": "sha512-ttwVSuwoV3RPaG2k2QzEXKeQNQ3mbdl/2yy6I4Tjrn1ZNkYHfVyJJ26AjenfSmj1kkTQoSAfZ8p+7rZp4n0xoQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/form": "^3.1.5", + "@react-aria/interactions": "^3.27.1", + "@react-aria/label": "^3.7.25", + "@react-aria/utils": "^3.33.1", + "@react-stately/form": "^3.2.4", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.1", + "@react-types/textfield": "^3.12.8", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/toast": { + "version": "3.0.11", + "resolved": "http://localhost:4873/@react-aria/toast/-/toast-3.0.11.tgz", + "integrity": "sha512-2DjZjBAvm8/CWbnZ6s7LjkYCkULKtjMve6GvhPTq98AthuEDLEiBvM1wa3xdecCRhZyRT1g6DXqVca0EfZ9fJA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/landmark": "^3.0.10", + "@react-aria/utils": "^3.33.1", + "@react-stately/toast": "^3.1.3", + "@react-types/button": "^3.15.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/toggle": { + "version": "3.12.5", + "resolved": "http://localhost:4873/@react-aria/toggle/-/toggle-3.12.5.tgz", + "integrity": "sha512-XXVFLzcV8fr9mz7y/wfxEAhWvaBZ9jSfhCMuxH2bsivO7nTcMJ1jb4g2xJNwZgne17bMWNc7mKvW5dbsdlI6BA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/utils": "^3.33.1", + "@react-stately/toggle": "^3.9.5", + "@react-types/checkbox": "^3.10.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/toolbar": { + "version": "3.0.0-beta.24", + "resolved": "http://localhost:4873/@react-aria/toolbar/-/toolbar-3.0.0-beta.24.tgz", + "integrity": "sha512-B2Rmpko7Ghi2RbNfsGdbR7I+RQBDhPGVE4bU3/EwHz+P/vNe5LyGPTeSwqaOMsQTF9lKNCkY8424dVTCr6RUMg==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/focus": "^3.21.5", + "@react-aria/i18n": "^3.12.16", + "@react-aria/utils": "^3.33.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/tooltip": { + "version": "3.9.2", + "resolved": "http://localhost:4873/@react-aria/tooltip/-/tooltip-3.9.2.tgz", + "integrity": "sha512-VrgkPwHiEnAnBhoQ4W7kfry/RfVuRWrUPaJSp0+wKM6u0gg2tmn7OFRDXTxBAm/omQUguIdIjRWg7sf3zHH82A==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/utils": "^3.33.1", + "@react-stately/tooltip": "^3.5.11", + "@react-types/shared": "^3.33.1", + "@react-types/tooltip": "^3.5.2", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/tree": { + "version": "3.1.7", + "resolved": "http://localhost:4873/@react-aria/tree/-/tree-3.1.7.tgz", + "integrity": "sha512-C54yH5NmsOFa2Q+cg6B1BPr5KUlU9vLIoBnVrgrH237FRSXQPIbcM4VpmITAHq1VR7w6ayyS1hgTwFxo67ykWQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/gridlist": "^3.14.4", + "@react-aria/i18n": "^3.12.16", + "@react-aria/selection": "^3.27.2", + "@react-aria/utils": "^3.33.1", + "@react-stately/tree": "^3.9.6", + "@react-types/button": "^3.15.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/utils": { + "version": "3.33.1", + "resolved": "http://localhost:4873/@react-aria/utils/-/utils-3.33.1.tgz", + "integrity": "sha512-kIx1Sj6bbAT0pdqCegHuPanR9zrLn5zMRiM7LN12rgRf55S19ptd9g3ncahArifYTRkfEU9VIn+q0HjfMqS9/w==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/ssr": "^3.9.10", + "@react-stately/flags": "^3.1.2", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/virtualizer": { + "version": "4.1.13", + "resolved": "http://localhost:4873/@react-aria/virtualizer/-/virtualizer-4.1.13.tgz", + "integrity": "sha512-d5KS+p8GXGNRbGPRE/N6jtth3et3KssQIz52h2+CAoAh7C3vvR64kkTaGdeywClvM+fSo8FxJuBrdfQvqC2ktQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/utils": "^3.33.1", + "@react-stately/virtualizer": "^4.4.6", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/visually-hidden": { + "version": "3.8.31", + "resolved": "http://localhost:4873/@react-aria/visually-hidden/-/visually-hidden-3.8.31.tgz", + "integrity": "sha512-RTOHHa4n56a9A3criThqFHBifvZoV71+MCkSuNP2cKO662SUWjqKkd0tJt/mBRMEJPkys8K7Eirp6T8Wt5FFRA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.27.1", + "@react-aria/utils": "^3.33.1", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/autocomplete": { + "version": "3.0.0-beta.4", + "resolved": "http://localhost:4873/@react-stately/autocomplete/-/autocomplete-3.0.0-beta.4.tgz", + "integrity": "sha512-K2Uy7XEdseFvgwRQ8CyrYEHMupjVKEszddOapP8deNz4hntYvT1aRm0m+sKa5Kl/4kvg9c/3NZpQcrky/vRZIg==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/utils": "^3.11.0", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/calendar": { + "version": "3.9.3", + "resolved": "http://localhost:4873/@react-stately/calendar/-/calendar-3.9.3.tgz", + "integrity": "sha512-uw7fCZXoypSBBUsVkbNvJMQWTihZReRbyLIGG3o/ZM630N3OCZhb/h4Uxke4pNu7n527H0V1bAnZgAldIzOYqg==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.0", + "@react-stately/utils": "^3.11.0", + "@react-types/calendar": "^3.8.3", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/checkbox": { + "version": "3.7.5", + "resolved": "http://localhost:4873/@react-stately/checkbox/-/checkbox-3.7.5.tgz", + "integrity": "sha512-K5R5ted7AxLB3sDkuVAazUdyRMraFT1imVqij2GuAiOUFvsZvbuocnDuFkBVKojyV3GpqLBvViV8IaCMc4hNIw==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/form": "^3.2.4", + "@react-stately/utils": "^3.11.0", + "@react-types/checkbox": "^3.10.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/collections": { + "version": "3.12.10", + "resolved": "http://localhost:4873/@react-stately/collections/-/collections-3.12.10.tgz", + "integrity": "sha512-wmF9VxJDyBujBuQ76vXj2g/+bnnj8fx5DdXgRmyfkkYhPB46+g2qnjbVGEvipo7bJuGxDftCUC4SN7l7xqUWfg==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/color": { + "version": "3.9.5", + "resolved": "http://localhost:4873/@react-stately/color/-/color-3.9.5.tgz", + "integrity": "sha512-8pZxzXWDRuglzDwyTG7mLw2LQMCHIVNbVc9YmbsxbOjAL+lOqszo60KzyaFKVxeDQczSvrNTHcQZqlbNIC0eyQ==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/number": "^3.6.5", + "@internationalized/string": "^3.2.7", + "@react-stately/form": "^3.2.4", + "@react-stately/numberfield": "^3.11.0", + "@react-stately/slider": "^3.7.5", + "@react-stately/utils": "^3.11.0", + "@react-types/color": "^3.1.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/combobox": { + "version": "3.13.0", + "resolved": "http://localhost:4873/@react-stately/combobox/-/combobox-3.13.0.tgz", + "integrity": "sha512-dX9g/cK1hjLRjcbWVF6keHxTQDGhKGB2QAgPhWcBmOK3qJv+2dQqsJ6YCGWn/Y2N2acoEseLrAA7+Qe4HWV9cg==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/collections": "^3.12.10", + "@react-stately/form": "^3.2.4", + "@react-stately/list": "^3.13.4", + "@react-stately/overlays": "^3.6.23", + "@react-stately/utils": "^3.11.0", + "@react-types/combobox": "^3.14.0", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/data": { + "version": "3.15.2", + "resolved": "http://localhost:4873/@react-stately/data/-/data-3.15.2.tgz", + "integrity": "sha512-BsmeeGgFwOGwo0g9Waprdyt+846n3KhKggZfpEnp5+sC4dE4uW1VIYpdyupMfr3bQcmX123q6TegfNP3eszrUA==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/datepicker": { + "version": "3.16.1", + "resolved": "http://localhost:4873/@react-stately/datepicker/-/datepicker-3.16.1.tgz", + "integrity": "sha512-BtAMDvxd1OZxkxjqq5tN5TYmp6Hm8+o3+IDA4qmem2/pfQfVbOZeWS2WitcPBImj4n4T+W1A5+PI7mT/6DUBVg==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.0", + "@internationalized/number": "^3.6.5", + "@internationalized/string": "^3.2.7", + "@react-stately/form": "^3.2.4", + "@react-stately/overlays": "^3.6.23", + "@react-stately/utils": "^3.11.0", + "@react-types/datepicker": "^3.13.5", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/disclosure": { + "version": "3.0.11", + "resolved": "http://localhost:4873/@react-stately/disclosure/-/disclosure-3.0.11.tgz", + "integrity": "sha512-/KjB/0HkxGWbhFAPztCP411LUKZCx9k8cKukrlGqrUWyvrcXlmza90j0g/CuxACBoV+DJP9V+4q+8ide0x750A==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/dnd": { + "version": "3.7.4", + "resolved": "http://localhost:4873/@react-stately/dnd/-/dnd-3.7.4.tgz", + "integrity": "sha512-YD0TVR5JkvTqskc1ouBpVKs6t/QS4RYCIyu8Ug8RgO122iIizuf2pfKnRLjYMdu5lXzBXGaIgd49dvnLzEXHIw==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/selection": "^3.20.9", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/flags": { + "version": "3.1.2", + "resolved": "http://localhost:4873/@react-stately/flags/-/flags-3.1.2.tgz", + "integrity": "sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@react-stately/form": { + "version": "3.2.4", + "resolved": "http://localhost:4873/@react-stately/form/-/form-3.2.4.tgz", + "integrity": "sha512-qNBzun8SbLdgahryhKLqL1eqP+MXY6as82sVXYOOvUYLzgU5uuN8mObxYlxJgMI5akSdQJQV3RzyfVobPRE7Kw==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/grid": { + "version": "3.11.9", + "resolved": "http://localhost:4873/@react-stately/grid/-/grid-3.11.9.tgz", + "integrity": "sha512-qQY6F+27iZRn30dt0ZOrSetUmbmNJ0pLe9Weuqw3+XDVSuWT+2O/rO1UUYeK+mO0Acjzdv+IWiYbu9RKf2wS9w==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/collections": "^3.12.10", + "@react-stately/selection": "^3.20.9", + "@react-types/grid": "^3.3.8", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/layout": { + "version": "4.6.0", + "resolved": "http://localhost:4873/@react-stately/layout/-/layout-4.6.0.tgz", + "integrity": "sha512-kBenEsP03nh5rKgfqlVMPcoKTJv0v92CTvrAb5gYY8t9g8LOwzdL89Yannq7f5xv8LFck/MmRQlotpMt2InETg==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/collections": "^3.12.10", + "@react-stately/table": "^3.15.4", + "@react-stately/virtualizer": "^4.4.6", + "@react-types/grid": "^3.3.8", + "@react-types/shared": "^3.33.1", + "@react-types/table": "^3.13.6", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/list": { + "version": "3.13.4", + "resolved": "http://localhost:4873/@react-stately/list/-/list-3.13.4.tgz", + "integrity": "sha512-HHYSjA9VG7FPSAtpXAjQyM/V7qFHWGg88WmMrDt5QDlTBexwPuH0oFLnW0qaVZpAIxuWIsutZfxRAnme/NhhAA==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/collections": "^3.12.10", + "@react-stately/selection": "^3.20.9", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/menu": { + "version": "3.9.11", + "resolved": "http://localhost:4873/@react-stately/menu/-/menu-3.9.11.tgz", + "integrity": "sha512-vYkpO9uV2OUecsIkrOc+Urdl/s1xw/ibNH/UXsp4PtjMnS6mK9q2kXZTM3WvMAKoh12iveUO+YkYCZQshmFLHQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/overlays": "^3.6.23", + "@react-types/menu": "^3.10.7", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/numberfield": { + "version": "3.11.0", + "resolved": "http://localhost:4873/@react-stately/numberfield/-/numberfield-3.11.0.tgz", + "integrity": "sha512-rxfC047vL0LP4tanjinfjKAriAvdVL57Um5RUL5nHML8IOWCB3TBxegQkJ6to6goScC/oZhd0/Y2LSaiRuKbNw==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/number": "^3.6.5", + "@react-stately/form": "^3.2.4", + "@react-stately/utils": "^3.11.0", + "@react-types/numberfield": "^3.8.18", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/overlays": { + "version": "3.6.23", + "resolved": "http://localhost:4873/@react-stately/overlays/-/overlays-3.6.23.tgz", + "integrity": "sha512-RzWxots9A6gAzQMP4s8hOAHV7SbJRTFSlQbb6ly1nkWQXacOSZSFNGsKOaS0eIatfNPlNnW4NIkgtGws5UYzfw==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/utils": "^3.11.0", + "@react-types/overlays": "^3.9.4", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/radio": { + "version": "3.11.5", + "resolved": "http://localhost:4873/@react-stately/radio/-/radio-3.11.5.tgz", + "integrity": "sha512-QxA779S4ea5icQ0ja7CeiNzY1cj7c9G9TN0m7maAIGiTSinZl2Ia8naZJ0XcbRRp+LBll7RFEdekne15TjvS/w==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/form": "^3.2.4", + "@react-stately/utils": "^3.11.0", + "@react-types/radio": "^3.9.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/searchfield": { + "version": "3.5.19", + "resolved": "http://localhost:4873/@react-stately/searchfield/-/searchfield-3.5.19.tgz", + "integrity": "sha512-URllgjbtTQEaOCfddbHpJSPKOzG3pE3ajQHJ7Df8qCoHTjKfL6hnm/vp7X5sxPaZaN7VLZ5kAQxTE8hpo6s0+A==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/utils": "^3.11.0", + "@react-types/searchfield": "^3.6.8", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/select": { + "version": "3.9.2", + "resolved": "http://localhost:4873/@react-stately/select/-/select-3.9.2.tgz", + "integrity": "sha512-oWn0bijuusp8YI7FRM/wgtPVqiIrgU/ZUfLKe/qJUmT8D+JFaMAJnyrAzKpx98TrgamgtXynF78ccpopPhgrKQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/form": "^3.2.4", + "@react-stately/list": "^3.13.4", + "@react-stately/overlays": "^3.6.23", + "@react-stately/utils": "^3.11.0", + "@react-types/select": "^3.12.2", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/selection": { + "version": "3.20.9", + "resolved": "http://localhost:4873/@react-stately/selection/-/selection-3.20.9.tgz", + "integrity": "sha512-RhxRR5Wovg9EVi3pq7gBPK2BoKmP59tOXDMh2r1PbnGevg/7TNdR67DCEblcmXwHuBNS46ELfKdd0XGHqmS8nQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/collections": "^3.12.10", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/slider": { + "version": "3.7.5", + "resolved": "http://localhost:4873/@react-stately/slider/-/slider-3.7.5.tgz", + "integrity": "sha512-OrQMNR5xamLYH52TXtvTgyw3EMwv+JI+1istQgEj1CHBjC9eZZqn5iNCN20tzm+uDPTH0EIGULFjjPIumqYUQg==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.1", + "@react-types/slider": "^3.8.4", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/table": { + "version": "3.15.4", + "resolved": "http://localhost:4873/@react-stately/table/-/table-3.15.4.tgz", + "integrity": "sha512-fGaNyw3wv7JgRCNzgyDzpaaTFuSy5f4Qekch4UheMXDJX7dOeaMhUXeOfvnXCVg+BGM4ey/D82RvDOGvPy1Nww==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/collections": "^3.12.10", + "@react-stately/flags": "^3.1.2", + "@react-stately/grid": "^3.11.9", + "@react-stately/selection": "^3.20.9", + "@react-stately/utils": "^3.11.0", + "@react-types/grid": "^3.3.8", + "@react-types/shared": "^3.33.1", + "@react-types/table": "^3.13.6", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/tabs": { + "version": "3.8.9", + "resolved": "http://localhost:4873/@react-stately/tabs/-/tabs-3.8.9.tgz", + "integrity": "sha512-AQ4Xrn6YzIolaVShCV9cnwOjBKPAOGP/PTp7wpSEtQbQ0HZzUDG2RG/M4baMeUB2jZ33b7ifXyPcK78o0uOftg==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/list": "^3.13.4", + "@react-types/shared": "^3.33.1", + "@react-types/tabs": "^3.3.22", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/toast": { + "version": "3.1.3", + "resolved": "http://localhost:4873/@react-stately/toast/-/toast-3.1.3.tgz", + "integrity": "sha512-mT9QJKmD523lqFpOp0VWZ6QHZENFK7HrodnNJDVc7g616s5GNmemdlkITV43fSY3tHeThCVvPu+Uzh7RvQ9mpQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/toggle": { + "version": "3.9.5", + "resolved": "http://localhost:4873/@react-stately/toggle/-/toggle-3.9.5.tgz", + "integrity": "sha512-PVzXc788q3jH98Kvw1LYDL+wpVC14dCEKjOku8cSaqhEof6AJGaLR9yq+EF1yYSL2dxI6z8ghc0OozY8WrcFcA==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/utils": "^3.11.0", + "@react-types/checkbox": "^3.10.4", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/tooltip": { + "version": "3.5.11", + "resolved": "http://localhost:4873/@react-stately/tooltip/-/tooltip-3.5.11.tgz", + "integrity": "sha512-o8PnFXbvDCuVZ4Ht9ahfS6KHwIZjXopvoQ2vUPxv920irdgWEeC+4omgDOnJ/xFvcpmmJAmSsrQsTQrTguDUQA==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/overlays": "^3.6.23", + "@react-types/tooltip": "^3.5.2", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/tree": { + "version": "3.9.6", + "resolved": "http://localhost:4873/@react-stately/tree/-/tree-3.9.6.tgz", + "integrity": "sha512-JCuhGyX2A+PAMsx2pRSwArfqNFZJ9JSPkDaOQJS8MFPAsBe5HemvXsdmv9aBIMzlbCYcVq6EsrFnzbVVTBt/6w==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/collections": "^3.12.10", + "@react-stately/selection": "^3.20.9", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/utils": { + "version": "3.11.0", + "resolved": "http://localhost:4873/@react-stately/utils/-/utils-3.11.0.tgz", + "integrity": "sha512-8LZpYowJ9eZmmYLpudbo/eclIRnbhWIJZ994ncmlKlouNzKohtM8qTC6B1w1pwUbiwGdUoyzLuQbeaIor5Dvcw==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/virtualizer": { + "version": "4.4.6", + "resolved": "http://localhost:4873/@react-stately/virtualizer/-/virtualizer-4.4.6.tgz", + "integrity": "sha512-9SfXgLFB61/8SXNLfg5ARx9jAK4m03Aw6/Cg8mdZN24SYarL4TKNRpfw8K/HHVU/bi6WHSJypk6Z/z19o/ztrg==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/autocomplete": { + "version": "3.0.0-alpha.38", + "resolved": "http://localhost:4873/@react-types/autocomplete/-/autocomplete-3.0.0-alpha.38.tgz", + "integrity": "sha512-0XrlVC8drzcrCNzybbkZdLcTofXEzBsHuaFevt5awW1J0xBJ+SMLIQMDeUYrvKjjwXUBlCtjJJpOvitGt4Z+KA==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/combobox": "^3.14.0", + "@react-types/searchfield": "^3.6.8", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/breadcrumbs": { + "version": "3.7.19", + "resolved": "http://localhost:4873/@react-types/breadcrumbs/-/breadcrumbs-3.7.19.tgz", + "integrity": "sha512-AnkyYYmzaM2QFi/N0P/kQLM8tHOyFi7p397B/jEMucXDfwMw5Ny1ObCXeIEqbh8KrIa2Xp8SxmQlCV+8FPs4LA==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/link": "^3.6.7", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/button": { + "version": "3.15.1", + "resolved": "http://localhost:4873/@react-types/button/-/button-3.15.1.tgz", + "integrity": "sha512-M1HtsKreJkigCnqceuIT22hDJBSStbPimnpmQmsl7SNyqCFY3+DHS7y/Sl3GvqCkzxF7j9UTL0dG38lGQ3K4xQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/calendar": { + "version": "3.8.3", + "resolved": "http://localhost:4873/@react-types/calendar/-/calendar-3.8.3.tgz", + "integrity": "sha512-fpH6WNXotzH0TlKHXXxtjeLZ7ko0sbyHmwDAwmDFyP7T0Iwn1YQZ+lhceLifvynlxuOgX6oBItyUKmkHQ0FouQ==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.0", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/checkbox": { + "version": "3.10.4", + "resolved": "http://localhost:4873/@react-types/checkbox/-/checkbox-3.10.4.tgz", + "integrity": "sha512-tYCG0Pd1usEz5hjvBEYcqcA0youx930Rss1QBIse9TgMekA1c2WmPDNupYV8phpO8Zuej3DL1WfBeXcgavK8aw==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/color": { + "version": "3.1.4", + "resolved": "http://localhost:4873/@react-types/color/-/color-3.1.4.tgz", + "integrity": "sha512-s+Xj4pvNBlJPpQ1Gr7bO1j4/tuwMUfdS9xIVFuiW5RvDsSybKTUJ/gqPzTxms94VDCRhLFocVn2STNdD2Erf6A==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1", + "@react-types/slider": "^3.8.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/combobox": { + "version": "3.14.0", + "resolved": "http://localhost:4873/@react-types/combobox/-/combobox-3.14.0.tgz", + "integrity": "sha512-zmSSS7BcCOD8rGT8eGbVy7UlL5qq1vm88fFn4WgFe+lfK33ne+E7yTzTxcPY2TCGSo5fY6xMj3OG79FfVNGbSg==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/datepicker": { + "version": "3.13.5", + "resolved": "http://localhost:4873/@react-types/datepicker/-/datepicker-3.13.5.tgz", + "integrity": "sha512-j28Vz+xvbb4bj7+9Xbpc4WTvSitlBvt7YEaEGM/8ZQ5g4Jr85H2KwkmDwjzmMN2r6VMQMMYq9JEcemq5wWpfUQ==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.0", + "@react-types/calendar": "^3.8.3", + "@react-types/overlays": "^3.9.4", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/dialog": { + "version": "3.5.24", + "resolved": "http://localhost:4873/@react-types/dialog/-/dialog-3.5.24.tgz", + "integrity": "sha512-NFurEP/zV0dA/41422lV1t+0oh6f/13n+VmLHZG8R13m1J3ql/kAXZ49zBSqkqANBO1ojyugWebk99IiR4pYOw==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/overlays": "^3.9.4", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/form": { + "version": "3.7.18", + "resolved": "http://localhost:4873/@react-types/form/-/form-3.7.18.tgz", + "integrity": "sha512-0sBJW0+I9nJcF4SmKrYFEWAlehiebSTy7xqriqAXtqfTEdvzAYLGaAK2/7gx+wlNZeDTdW43CDRJ4XAhyhBqnw==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/grid": { + "version": "3.3.8", + "resolved": "http://localhost:4873/@react-types/grid/-/grid-3.3.8.tgz", + "integrity": "sha512-zJvXH8gc1e1VH2H3LRnHH/W2HIkLkZMH3Cu5pLcj0vDuLBSWpcr3Ikh3jZ+VUOZF0G1Jt1lO8pKIaqFzDLNmLQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/link": { + "version": "3.6.7", + "resolved": "http://localhost:4873/@react-types/link/-/link-3.6.7.tgz", + "integrity": "sha512-1apXCFJgMC1uydc2KNENrps1qR642FqDpwlNWe254UTpRZn/hEZhA6ImVr8WhomfLJu672WyWA0rUOv4HT+/pQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/listbox": { + "version": "3.7.6", + "resolved": "http://localhost:4873/@react-types/listbox/-/listbox-3.7.6.tgz", + "integrity": "sha512-335NYElKEByXMalAmeRPyulKIDd2cjOCQhLwvv2BtxO5zaJfZnBbhZs+XPd9zwU6YomyOxODKSHrwbNDx+Jf3w==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/menu": { + "version": "3.10.7", + "resolved": "http://localhost:4873/@react-types/menu/-/menu-3.10.7.tgz", + "integrity": "sha512-+p7ixZdvPDJZhisqdtWiiuJ9pteNfK5i19NB6wzAw5XkljbEzodNhwLv6rI96DY5XpbFso2kcjw7IWi+rAAGGQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/overlays": "^3.9.4", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/meter": { + "version": "3.4.15", + "resolved": "http://localhost:4873/@react-types/meter/-/meter-3.4.15.tgz", + "integrity": "sha512-9WjNphhLLM+TA4Ev1y2MkpugJ5JjTXseHh7ZWWx2veq5DrXMZYclkRpfUrUdLVKvaBIPQCgpQIj0TcQi+quR9A==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/progress": "^3.5.18" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/numberfield": { + "version": "3.8.18", + "resolved": "http://localhost:4873/@react-types/numberfield/-/numberfield-3.8.18.tgz", + "integrity": "sha512-nLzk7YAG9yAUtSv+9R8LgCHsu8hJq8/A+m1KsKxvc8WmNJjIujSFgWvT21MWBiUgPBzJKGzAqpMDDa087mltJQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/overlays": { + "version": "3.9.4", + "resolved": "http://localhost:4873/@react-types/overlays/-/overlays-3.9.4.tgz", + "integrity": "sha512-7Z9HaebMFyYBqtv3XVNHEmVkm7AiYviV7gv0c98elEN2Co+eQcKFGvwBM9Gy/lV57zlTqFX1EX/SAqkMEbCLOA==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/progress": { + "version": "3.5.18", + "resolved": "http://localhost:4873/@react-types/progress/-/progress-3.5.18.tgz", + "integrity": "sha512-mKeQn+KrHr1y0/k7KtrbeDGDaERH6i4f6yBwj/ZtYDCTNKMO3tPHJY6nzF0w/KKZLplIO+BjUbHXc2RVm8ovwQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/radio": { + "version": "3.9.4", + "resolved": "http://localhost:4873/@react-types/radio/-/radio-3.9.4.tgz", + "integrity": "sha512-TkMRY3sA1PcFZhhclu4IUzUTIir6MzNJj8h6WT8vO6Nug2kXJ72qigugVFBWJSE472mltduOErEAo0rtAYWbQA==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/searchfield": { + "version": "3.6.8", + "resolved": "http://localhost:4873/@react-types/searchfield/-/searchfield-3.6.8.tgz", + "integrity": "sha512-M2p7OVdMTMDmlBcHd4N2uCBwg3uJSNM4lmEyf09YD44N5wDAI0yogk52QBwsnhpe+i2s65UwCYgunB+QltRX8A==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1", + "@react-types/textfield": "^3.12.8" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/select": { + "version": "3.12.2", + "resolved": "http://localhost:4873/@react-types/select/-/select-3.12.2.tgz", + "integrity": "sha512-AseOjfr3qM1W1qIWcbAe6NFpwZluVeQX/dmu9BYxjcnVvtoBLPMbE5zX/BPbv+N5eFYjoMyj7Ug9dqnI+LrlGw==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/shared": { + "version": "3.33.1", + "resolved": "http://localhost:4873/@react-types/shared/-/shared-3.33.1.tgz", + "integrity": "sha512-oJHtjvLG43VjwemQDadlR5g/8VepK56B/xKO2XORPHt9zlW6IZs3tZrYlvH29BMvoqC7RtE7E5UjgbnbFtDGag==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/slider": { + "version": "3.8.4", + "resolved": "http://localhost:4873/@react-types/slider/-/slider-3.8.4.tgz", + "integrity": "sha512-C+xFVvfKREai9S/ekBDCVaGPOQYkNUAsQhjQnNsUAATaox4I6IYLmcIgLmljpMQWqAe+gZiWsIwacRYMez2Tew==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/switch": { + "version": "3.5.17", + "resolved": "http://localhost:4873/@react-types/switch/-/switch-3.5.17.tgz", + "integrity": "sha512-2GTPJvBCYI8YZ3oerHtXg+qikabIXCMJ6C2wcIJ5Xn0k9XOovowghfJi10OPB2GGyOiLBU74CczP5nx8adG90Q==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/table": { + "version": "3.13.6", + "resolved": "http://localhost:4873/@react-types/table/-/table-3.13.6.tgz", + "integrity": "sha512-eluL+iFfnVmFm7OSZrrFG9AUjw+tcv898zbv+NsZACa8oXG1v9AimhZfd+Mo8q/5+sX/9hguWNXFkSvmTjuVPQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/grid": "^3.3.8", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/tabs": { + "version": "3.3.22", + "resolved": "http://localhost:4873/@react-types/tabs/-/tabs-3.3.22.tgz", + "integrity": "sha512-HGwLD9dA3k3AGfRKGFBhNgxU9/LyRmxN0kxVj1ghA4L9S/qTOzS6GhrGNkGzsGxyVLV4JN8MLxjWN2o9QHnLEg==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/textfield": { + "version": "3.12.8", + "resolved": "http://localhost:4873/@react-types/textfield/-/textfield-3.12.8.tgz", + "integrity": "sha512-wt6FcuE5AyntxsnPika/h3nf/DPmeAVbI018L9o6h+B/IL4sMWWdx663wx2KOOeHH8ejKGZQNPLhUKs4s1mVQA==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/tooltip": { + "version": "3.5.2", + "resolved": "http://localhost:4873/@react-types/tooltip/-/tooltip-3.5.2.tgz", + "integrity": "sha512-FvSuZ2WP08NEWefrpCdBYpEEZh/5TvqvGjq0wqGzWg2OPwpc14HjD8aE7I3MOuylXkD4MSlMjl7J4DlvlcCs3Q==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/overlays": "^3.9.4", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.7", + "resolved": "http://localhost:4873/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", + "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "http://localhost:4873/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "http://localhost:4873/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, + "node_modules/@swc/core": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core/-/core-1.15.18.tgz", + "integrity": "sha512-z87aF9GphWp//fnkRsqvtY+inMVPgYW3zSlXH1kJFvRT5H/wiAn+G32qW5l3oEk63KSF1x3Ov0BfHCObAmT8RA==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.25" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.15.18", + "@swc/core-darwin-x64": "1.15.18", + "@swc/core-linux-arm-gnueabihf": "1.15.18", + "@swc/core-linux-arm64-gnu": "1.15.18", + "@swc/core-linux-arm64-musl": "1.15.18", + "@swc/core-linux-x64-gnu": "1.15.18", + "@swc/core-linux-x64-musl": "1.15.18", + "@swc/core-win32-arm64-msvc": "1.15.18", + "@swc/core-win32-ia32-msvc": "1.15.18", + "@swc/core-win32-x64-msvc": "1.15.18" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.18.tgz", + "integrity": "sha512-+mIv7uBuSaywN3C9LNuWaX1jJJ3SKfiJuE6Lr3bd+/1Iv8oMU7oLBjYMluX1UrEPzwN2qCdY6Io0yVicABoCwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-darwin-x64/-/core-darwin-x64-1.15.18.tgz", + "integrity": "sha512-wZle0eaQhnzxWX5V/2kEOI6Z9vl/lTFEC6V4EWcn+5pDjhemCpQv9e/TDJ0GIoiClX8EDWRvuZwh+Z3dhL1NAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.18.tgz", + "integrity": "sha512-ao61HGXVqrJFHAcPtF4/DegmwEkVCo4HApnotLU8ognfmU8x589z7+tcf3hU+qBiU1WOXV5fQX6W9Nzs6hjxDw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.18.tgz", + "integrity": "sha512-3xnctOBLIq3kj8PxOCgPrGjBLP/kNOddr6f5gukYt/1IZxsITQaU9TDyjeX6jG+FiCIHjCuWuffsyQDL5Ew1bg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.18.tgz", + "integrity": "sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.18.tgz", + "integrity": "sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.18.tgz", + "integrity": "sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.18.tgz", + "integrity": "sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.18.tgz", + "integrity": "sha512-yVuTrZ0RccD5+PEkpcLOBAuPbYBXS6rslENvIXfvJGXSdX5QGi1ehC4BjAMl5FkKLiam4kJECUI0l7Hq7T1vwg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.15.18", + "resolved": "http://localhost:4873/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.18.tgz", + "integrity": "sha512-7NRmE4hmUQNCbYU3Hn9Tz57mK9Qq4c97ZS+YlamlK6qG9Fb5g/BB3gPDe0iLlJkns/sYv2VWSkm8c3NmbEGjbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "http://localhost:4873/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.19", + "resolved": "http://localhost:4873/@swc/helpers/-/helpers-0.5.19.tgz", + "integrity": "sha512-QamiFeIK3txNjgUTNppE6MiG3p7TdninpZu0E0PbqVh1a9FNLT2FRhisaa4NcaX52XVhA5l7Pk58Ft7Sqi/2sA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@swc/types": { + "version": "0.1.25", + "resolved": "http://localhost:4873/@swc/types/-/types-0.1.25.tgz", + "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", + "jiti": "^2.6.1", + "lightningcss": "1.31.1", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.1" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", + "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", + "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", + "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", + "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", + "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", + "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", + "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", + "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", + "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", + "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", + "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/postcss/-/postcss-4.2.1.tgz", + "integrity": "sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.2.1", + "@tailwindcss/oxide": "4.2.1", + "postcss": "^8.5.6", + "tailwindcss": "4.2.1" + } + }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.19", + "resolved": "http://localhost:4873/@tailwindcss/typography/-/typography-0.5.19.tgz", + "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.2.1", + "resolved": "http://localhost:4873/@tailwindcss/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.2.1", + "@tailwindcss/oxide": "4.2.1", + "tailwindcss": "4.2.1" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports": { + "version": "5.2.2", + "resolved": "http://localhost:4873/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-5.2.2.tgz", + "integrity": "sha512-fYDQA9e6yTNmA13TLVSA+WMQRc5Bn/c0EUBditUHNfMMxN7M82c38b1kEggVE3pLpZ0FwkwJkUEKMiOi52JXFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.7", + "@babel/traverse": "^7.26.7", + "@babel/types": "^7.26.7", + "javascript-natural-sort": "^0.7.1", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">18.12" + }, + "peerDependencies": { + "@vue/compiler-sfc": "3.x", + "prettier": "2.x - 3.x", + "prettier-plugin-svelte": "3.x", + "svelte": "4.x || 5.x" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + }, + "svelte": { + "optional": true + } + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "http://localhost:4873/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "http://localhost:4873/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "http://localhost:4873/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/jssip": { + "version": "3.5.3", + "resolved": "http://localhost:4873/@types/jssip/-/jssip-3.5.3.tgz", + "integrity": "sha512-Rvw7hJPEJ12dlinAyzGpt3wxyPFMJemKRU4jTGRlRATZIdaIZUmpehsdU0oq9jIhx9bNNqIgzR+eR5Xe/U0/2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jssip": "*" + } + }, + "node_modules/@types/node": { + "version": "24.12.0", + "resolved": "http://localhost:4873/@types/node/-/node-24.12.0.tgz", + "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "http://localhost:4873/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "http://localhost:4873/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz", + "integrity": "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.57.0", + "@typescript-eslint/type-utils": "8.57.0", + "@typescript-eslint/utils": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.57.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "http://localhost:4873/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/parser/-/parser-8.57.0.tgz", + "integrity": "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.57.0", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/project-service/-/project-service-8.57.0.tgz", + "integrity": "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.57.0", + "@typescript-eslint/types": "^8.57.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/scope-manager/-/scope-manager-8.57.0.tgz", + "integrity": "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.0.tgz", + "integrity": "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/type-utils/-/type-utils-8.57.0.tgz", + "integrity": "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0", + "@typescript-eslint/utils": "8.57.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/types/-/types-8.57.0.tgz", + "integrity": "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.0.tgz", + "integrity": "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.57.0", + "@typescript-eslint/tsconfig-utils": "8.57.0", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/visitor-keys": "8.57.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/utils/-/utils-8.57.0.tgz", + "integrity": "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.57.0", + "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.57.0", + "resolved": "http://localhost:4873/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.0.tgz", + "integrity": "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@untitledui/file-icons": { + "version": "0.0.8", + "resolved": "http://localhost:4873/@untitledui/file-icons/-/file-icons-0.0.8.tgz", + "integrity": "sha512-lxOp2rreDedjD82SOKoETmCDhm5TckCD3y49EEsuZqxnFES/3bfg9drNiilOCOAuEco7ImvdB4L//I//B93asw==", + "license": "MIT", + "peerDependencies": { + "react": ">= 18" + } + }, + "node_modules/@untitledui/icons": { + "version": "0.0.21", + "resolved": "http://localhost:4873/@untitledui/icons/-/icons-0.0.21.tgz", + "integrity": "sha512-+aVWUw/1se9PIJgwMD3qp5ohynGlVNu2oHSLzMwYpiSFp6bFcxv4kUGy685hQXB/hE4WAqnp7dIEVVMD0tfL7w==", + "license": "MIT", + "peerDependencies": { + "react": ">= 16" + } + }, + "node_modules/@vitejs/plugin-react-swc": { + "version": "4.3.0", + "resolved": "http://localhost:4873/@vitejs/plugin-react-swc/-/plugin-react-swc-4.3.0.tgz", + "integrity": "sha512-mOkXCII839dHyAt/gpoSlm28JIVDwhZ6tnG6wJxUy2bmOx7UaPjvOyIDf3SFv5s7Eo7HVaq6kRcu6YMEzt5Z7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-rc.7", + "@swc/core": "^1.15.11" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "http://localhost:4873/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "http://localhost:4873/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peer": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "http://localhost:4873/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "http://localhost:4873/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "http://localhost:4873/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "http://localhost:4873/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "http://localhost:4873/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "http://localhost:4873/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "http://localhost:4873/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "http://localhost:4873/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "http://localhost:4873/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "http://localhost:4873/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "http://localhost:4873/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "http://localhost:4873/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "http://localhost:4873/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "http://localhost:4873/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "http://localhost:4873/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/echarts": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-6.0.0.tgz", + "integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "6.0.0" + } + }, + "node_modules/echarts-for-react": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.6.tgz", + "integrity": "sha512-4zqLgTGWS3JvkQDXjzkR1k1CHRdpd6by0988TWMJgnvDytegWLbeP/VNZmMa+0VJx2eD7Y632bi2JquXDgiGJg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "size-sensor": "^1.0.1" + }, + "peerDependencies": { + "echarts": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", + "react": "^15.0.0 || >=16.0.0" + } + }, + "node_modules/echarts/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, + "node_modules/engine.io-client": { + "version": "6.6.4", + "resolved": "http://localhost:4873/engine.io-client/-/engine.io-client-6.6.4.tgz", + "integrity": "sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.18.3", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "http://localhost:4873/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.20.0", + "resolved": "http://localhost:4873/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esbuild": { + "version": "0.27.4", + "resolved": "http://localhost:4873/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "http://localhost:4873/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.0.3", + "resolved": "http://localhost:4873/eslint/-/eslint-10.0.3.tgz", + "integrity": "sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.3", + "@eslint/config-helpers": "^0.5.2", + "@eslint/core": "^1.1.1", + "@eslint/plugin-kit": "^0.6.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.1.1", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "http://localhost:4873/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "http://localhost:4873/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "http://localhost:4873/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "http://localhost:4873/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "http://localhost:4873/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "http://localhost:4873/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "http://localhost:4873/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "http://localhost:4873/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "http://localhost:4873/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "http://localhost:4873/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "http://localhost:4873/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "http://localhost:4873/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "http://localhost:4873/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "http://localhost:4873/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "http://localhost:4873/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.1", + "resolved": "http://localhost:4873/flatted/-/flatted-3.4.1.tgz", + "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/framer-motion": { + "version": "12.36.0", + "resolved": "http://localhost:4873/framer-motion/-/framer-motion-12.36.0.tgz", + "integrity": "sha512-4PqYHAT7gev0ke0wos+PyrcFxI0HScjm3asgU8nSYa8YzJFuwgIvdj3/s3ZaxLq0bUSboIn19A2WS/MHwLCvfw==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.36.0", + "motion-utils": "^12.36.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "http://localhost:4873/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "http://localhost:4873/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "http://localhost:4873/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "http://localhost:4873/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/https": { + "version": "1.0.0", + "resolved": "http://localhost:4873/https/-/https-1.0.0.tgz", + "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==", + "license": "ISC" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "http://localhost:4873/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.2.1", + "resolved": "http://localhost:4873/image-size/-/image-size-1.2.1.tgz", + "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==", + "license": "MIT", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "http://localhost:4873/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "http://localhost:4873/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "http://localhost:4873/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/input-otp": { + "version": "1.4.2", + "resolved": "http://localhost:4873/input-otp/-/input-otp-1.4.2.tgz", + "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/intl-messageformat": { + "version": "10.7.18", + "resolved": "http://localhost:4873/intl-messageformat/-/intl-messageformat-10.7.18.tgz", + "integrity": "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==", + "license": "BSD-3-Clause", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/icu-messageformat-parser": "2.11.4", + "tslib": "^2.8.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "http://localhost:4873/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "http://localhost:4873/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "http://localhost:4873/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "http://localhost:4873/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "http://localhost:4873/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "http://localhost:4873/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jotai": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.18.1.tgz", + "integrity": "sha512-e0NOzK+yRFwHo7DOp0DS0Ycq74KMEAObDWFGmfEL28PD9nLqBTt3/Ug7jf9ca72x0gC9LQZG9zH+0ISICmy3iA==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0", + "@babel/template": ">=7.0.0", + "@types/react": ">=17.0.0", + "react": ">=17.0.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@babel/template": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "http://localhost:4873/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "http://localhost:4873/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "http://localhost:4873/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "http://localhost:4873/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "http://localhost:4873/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "http://localhost:4873/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/jssip": { + "version": "3.13.6", + "resolved": "http://localhost:4873/jssip/-/jssip-3.13.6.tgz", + "integrity": "sha512-Bf1ndrSuqpO87/AG56WACR7kKcCvKOzaIQROu7JUMh0qFaGOV4NuR+wsnaXa7f3/d6xhwVczczFyt1ywJmTjPg==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.1", + "events": "^3.3.0", + "sdp-transform": "^2.14.1" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "http://localhost:4873/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "http://localhost:4873/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "http://localhost:4873/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "http://localhost:4873/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lightningcss": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss/-/lightningcss-1.31.1.tgz", + "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.31.1", + "lightningcss-darwin-arm64": "1.31.1", + "lightningcss-darwin-x64": "1.31.1", + "lightningcss-freebsd-x64": "1.31.1", + "lightningcss-linux-arm-gnueabihf": "1.31.1", + "lightningcss-linux-arm64-gnu": "1.31.1", + "lightningcss-linux-arm64-musl": "1.31.1", + "lightningcss-linux-x64-gnu": "1.31.1", + "lightningcss-linux-x64-musl": "1.31.1", + "lightningcss-win32-arm64-msvc": "1.31.1", + "lightningcss-win32-x64-msvc": "1.31.1" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", + "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", + "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", + "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", + "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", + "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", + "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", + "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", + "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", + "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", + "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.31.1", + "resolved": "http://localhost:4873/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", + "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "http://localhost:4873/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "http://localhost:4873/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "http://localhost:4873/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/minimatch": { + "version": "10.2.4", + "resolved": "http://localhost:4873/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/motion": { + "version": "12.36.0", + "resolved": "http://localhost:4873/motion/-/motion-12.36.0.tgz", + "integrity": "sha512-5BMQuktYUX8aEByKWYx5tR4X3G08H2OMgp46wTxZ4o7CDDstyy4A0fe9RLNMjZiwvntCWGDvs16sC87/emz4Yw==", + "license": "MIT", + "dependencies": { + "framer-motion": "^12.36.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "12.36.0", + "resolved": "http://localhost:4873/motion-dom/-/motion-dom-12.36.0.tgz", + "integrity": "sha512-Ep1pq8P88rGJ75om8lTCA13zqd7ywPGwCqwuWwin6BKc0hMLkVfcS6qKlRqEo2+t0DwoUcgGJfXwaiFn4AOcQA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.36.0" + } + }, + "node_modules/motion-utils": { + "version": "12.36.0", + "resolved": "http://localhost:4873/motion-utils/-/motion-utils-12.36.0.tgz", + "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "http://localhost:4873/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "http://localhost:4873/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "http://localhost:4873/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "http://localhost:4873/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "http://localhost:4873/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "http://localhost:4873/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "http://localhost:4873/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "http://localhost:4873/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "http://localhost:4873/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "http://localhost:4873/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "http://localhost:4873/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "http://localhost:4873/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "http://localhost:4873/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pptxgenjs": { + "version": "4.0.1", + "resolved": "http://localhost:4873/pptxgenjs/-/pptxgenjs-4.0.1.tgz", + "integrity": "sha512-TeJISr8wouAuXw4C1F/mC33xbZs/FuEG6nH9FG1Zj+nuPcGMP5YRHl6X+j3HSUnS1f3at6k75ZZXPMZlA5Lj9A==", + "license": "MIT", + "dependencies": { + "@types/node": "^22.8.1", + "https": "^1.0.0", + "image-size": "^1.2.1", + "jszip": "^3.10.1" + } + }, + "node_modules/pptxgenjs/node_modules/@types/node": { + "version": "22.19.15", + "resolved": "http://localhost:4873/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/pptxgenjs/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "http://localhost:4873/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "http://localhost:4873/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "http://localhost:4873/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-tailwindcss": { + "version": "0.6.14", + "resolved": "http://localhost:4873/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.14.tgz", + "integrity": "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-hermes": "*", + "@prettier/plugin-oxc": "*", + "@prettier/plugin-pug": "*", + "@shopify/prettier-plugin-liquid": "*", + "@trivago/prettier-plugin-sort-imports": "*", + "@zackad/prettier-plugin-twig": "*", + "prettier": "^3.0", + "prettier-plugin-astro": "*", + "prettier-plugin-css-order": "*", + "prettier-plugin-import-sort": "*", + "prettier-plugin-jsdoc": "*", + "prettier-plugin-marko": "*", + "prettier-plugin-multiline-arrays": "*", + "prettier-plugin-organize-attributes": "*", + "prettier-plugin-organize-imports": "*", + "prettier-plugin-sort-imports": "*", + "prettier-plugin-style-order": "*", + "prettier-plugin-svelte": "*" + }, + "peerDependenciesMeta": { + "@ianvs/prettier-plugin-sort-imports": { + "optional": true + }, + "@prettier/plugin-hermes": { + "optional": true + }, + "@prettier/plugin-oxc": { + "optional": true + }, + "@prettier/plugin-pug": { + "optional": true + }, + "@shopify/prettier-plugin-liquid": { + "optional": true + }, + "@trivago/prettier-plugin-sort-imports": { + "optional": true + }, + "@zackad/prettier-plugin-twig": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-css-order": { + "optional": true + }, + "prettier-plugin-import-sort": { + "optional": true + }, + "prettier-plugin-jsdoc": { + "optional": true + }, + "prettier-plugin-marko": { + "optional": true + }, + "prettier-plugin-multiline-arrays": { + "optional": true + }, + "prettier-plugin-organize-attributes": { + "optional": true + }, + "prettier-plugin-organize-imports": { + "optional": true + }, + "prettier-plugin-sort-imports": { + "optional": true + }, + "prettier-plugin-style-order": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + } + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "http://localhost:4873/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "http://localhost:4873/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qr-code-styling": { + "version": "1.9.2", + "resolved": "http://localhost:4873/qr-code-styling/-/qr-code-styling-1.9.2.tgz", + "integrity": "sha512-RgJaZJ1/RrXJ6N0j7a+pdw3zMBmzZU4VN2dtAZf8ZggCfRB5stEQ3IoDNGaNhYY3nnZKYlYSLl5YkfWN5dPutg==", + "license": "MIT", + "dependencies": { + "qrcode-generator": "^1.4.4" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/qrcode-generator": { + "version": "1.5.2", + "resolved": "http://localhost:4873/qrcode-generator/-/qrcode-generator-1.5.2.tgz", + "integrity": "sha512-pItrW0Z9HnDBnFmgiNrY1uxRdri32Uh9EjNYLPVC2zZ3ZRIIEqBoDgm4DkvDwNNDHTK7FNkmr8zAa77BYc9xNw==", + "license": "MIT" + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "http://localhost:4873/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "license": "MIT", + "dependencies": { + "inherits": "~2.0.3" + } + }, + "node_modules/react": { + "version": "19.2.4", + "resolved": "http://localhost:4873/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-aria": { + "version": "3.47.0", + "resolved": "http://localhost:4873/react-aria/-/react-aria-3.47.0.tgz", + "integrity": "sha512-nvahimIqdByl/PXk/xPkG30LPRzcin+/Uk0uFfwbbKRRFC9aa22a6BRULZLqVHwa9GaNyKe6CDUxO1Dde4v0kA==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/string": "^3.2.7", + "@react-aria/breadcrumbs": "^3.5.32", + "@react-aria/button": "^3.14.5", + "@react-aria/calendar": "^3.9.5", + "@react-aria/checkbox": "^3.16.5", + "@react-aria/color": "^3.1.5", + "@react-aria/combobox": "^3.15.0", + "@react-aria/datepicker": "^3.16.1", + "@react-aria/dialog": "^3.5.34", + "@react-aria/disclosure": "^3.1.3", + "@react-aria/dnd": "^3.11.6", + "@react-aria/focus": "^3.21.5", + "@react-aria/gridlist": "^3.14.4", + "@react-aria/i18n": "^3.12.16", + "@react-aria/interactions": "^3.27.1", + "@react-aria/label": "^3.7.25", + "@react-aria/landmark": "^3.0.10", + "@react-aria/link": "^3.8.9", + "@react-aria/listbox": "^3.15.3", + "@react-aria/menu": "^3.21.0", + "@react-aria/meter": "^3.4.30", + "@react-aria/numberfield": "^3.12.5", + "@react-aria/overlays": "^3.31.2", + "@react-aria/progress": "^3.4.30", + "@react-aria/radio": "^3.12.5", + "@react-aria/searchfield": "^3.8.12", + "@react-aria/select": "^3.17.3", + "@react-aria/selection": "^3.27.2", + "@react-aria/separator": "^3.4.16", + "@react-aria/slider": "^3.8.5", + "@react-aria/ssr": "^3.9.10", + "@react-aria/switch": "^3.7.11", + "@react-aria/table": "^3.17.11", + "@react-aria/tabs": "^3.11.1", + "@react-aria/tag": "^3.8.1", + "@react-aria/textfield": "^3.18.5", + "@react-aria/toast": "^3.0.11", + "@react-aria/tooltip": "^3.9.2", + "@react-aria/tree": "^3.1.7", + "@react-aria/utils": "^3.33.1", + "@react-aria/visually-hidden": "^3.8.31", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-aria-components": { + "version": "1.16.0", + "resolved": "http://localhost:4873/react-aria-components/-/react-aria-components-1.16.0.tgz", + "integrity": "sha512-MjHbTLpMFzzD2Tv5KbeXoZwPczuUWZcRavVvQQlNHRtXHH38D+sToMEYpNeir7Wh3K/XWtzeX3EujfJW6QNkrw==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.0", + "@internationalized/string": "^3.2.7", + "@react-aria/autocomplete": "3.0.0-rc.6", + "@react-aria/collections": "^3.0.3", + "@react-aria/dnd": "^3.11.6", + "@react-aria/focus": "^3.21.5", + "@react-aria/interactions": "^3.27.1", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/overlays": "^3.31.2", + "@react-aria/ssr": "^3.9.10", + "@react-aria/textfield": "^3.18.5", + "@react-aria/toolbar": "3.0.0-beta.24", + "@react-aria/utils": "^3.33.1", + "@react-aria/virtualizer": "^4.1.13", + "@react-stately/autocomplete": "3.0.0-beta.4", + "@react-stately/layout": "^4.6.0", + "@react-stately/selection": "^3.20.9", + "@react-stately/table": "^3.15.4", + "@react-stately/utils": "^3.11.0", + "@react-stately/virtualizer": "^4.4.6", + "@react-types/form": "^3.7.18", + "@react-types/grid": "^3.3.8", + "@react-types/shared": "^3.33.1", + "@react-types/table": "^3.13.6", + "@swc/helpers": "^0.5.0", + "client-only": "^0.0.1", + "react-aria": "^3.47.0", + "react-stately": "^3.45.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "http://localhost:4873/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" + } + }, + "node_modules/react-hotkeys-hook": { + "version": "5.2.4", + "resolved": "http://localhost:4873/react-hotkeys-hook/-/react-hotkeys-hook-5.2.4.tgz", + "integrity": "sha512-BgKg+A1+TawkYluh5Bo4cTmcgMN5L29uhJbDUQdHwPX+qgXRjIPYU5kIDHyxnAwCkCBiu9V5OpB2mpyeluVF2A==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-router": { + "version": "7.13.1", + "resolved": "http://localhost:4873/react-router/-/react-router-7.13.1.tgz", + "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-stately": { + "version": "3.45.0", + "resolved": "http://localhost:4873/react-stately/-/react-stately-3.45.0.tgz", + "integrity": "sha512-G3bYr0BIiookpt4H05VeZUuVS/FslQAj2TeT8vDfCiL314Y+LtPXIPe/a3eamCA0wljy7z1EDYKV50Qbz7pcJg==", + "license": "Apache-2.0", + "dependencies": { + "@react-stately/calendar": "^3.9.3", + "@react-stately/checkbox": "^3.7.5", + "@react-stately/collections": "^3.12.10", + "@react-stately/color": "^3.9.5", + "@react-stately/combobox": "^3.13.0", + "@react-stately/data": "^3.15.2", + "@react-stately/datepicker": "^3.16.1", + "@react-stately/disclosure": "^3.0.11", + "@react-stately/dnd": "^3.7.4", + "@react-stately/form": "^3.2.4", + "@react-stately/list": "^3.13.4", + "@react-stately/menu": "^3.9.11", + "@react-stately/numberfield": "^3.11.0", + "@react-stately/overlays": "^3.6.23", + "@react-stately/radio": "^3.11.5", + "@react-stately/searchfield": "^3.5.19", + "@react-stately/select": "^3.9.2", + "@react-stately/selection": "^3.20.9", + "@react-stately/slider": "^3.7.5", + "@react-stately/table": "^3.15.4", + "@react-stately/tabs": "^3.8.9", + "@react-stately/toast": "^3.1.3", + "@react-stately/toggle": "^3.9.5", + "@react-stately/tooltip": "^3.5.11", + "@react-stately/tree": "^3.9.6", + "@react-types/shared": "^3.33.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "http://localhost:4873/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "http://localhost:4873/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "http://localhost:4873/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "http://localhost:4873/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/sdp-transform": { + "version": "2.15.0", + "resolved": "http://localhost:4873/sdp-transform/-/sdp-transform-2.15.0.tgz", + "integrity": "sha512-KrOH82c/W+GYQ0LHqtr3caRpM3ITglq3ljGUIb8LTki7ByacJZ9z+piSGiwZDsRyhQbYBOBJgr2k6X4BZXi3Kw==", + "license": "MIT", + "bin": { + "sdp-verify": "checker.js" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "http://localhost:4873/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "license": "BSD-3-Clause" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "http://localhost:4873/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "http://localhost:4873/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "http://localhost:4873/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "http://localhost:4873/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "http://localhost:4873/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/size-sensor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.3.tgz", + "integrity": "sha512-+k9mJ2/rQMiRmQUcjn+qznch260leIXY8r4FyYKKyRBO/s5UoeMAHGkCJyE1R/4wrIhTJONfyloY55SkE7ve3A==", + "license": "ISC" + }, + "node_modules/socket.io-client": { + "version": "4.8.3", + "resolved": "http://localhost:4873/socket.io-client/-/socket.io-client-4.8.3.tgz", + "integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.5", + "resolved": "http://localhost:4873/socket.io-parser/-/socket.io-parser-4.2.5.tgz", + "integrity": "sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sonner": { + "version": "2.0.7", + "resolved": "http://localhost:4873/sonner/-/sonner-2.0.7.tgz", + "integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "http://localhost:4873/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "http://localhost:4873/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/swr": { + "version": "2.4.1", + "resolved": "http://localhost:4873/swr/-/swr-2.4.1.tgz", + "integrity": "sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/tailwind-merge": { + "version": "3.5.0", + "resolved": "http://localhost:4873/tailwind-merge/-/tailwind-merge-3.5.0.tgz", + "integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.2.1", + "resolved": "http://localhost:4873/tailwindcss/-/tailwindcss-4.2.1.tgz", + "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", + "license": "MIT" + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "http://localhost:4873/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/tailwindcss-react-aria-components": { + "version": "2.0.1", + "resolved": "http://localhost:4873/tailwindcss-react-aria-components/-/tailwindcss-react-aria-components-2.0.1.tgz", + "integrity": "sha512-yTAfYv9BE/gKczS+b8UiFMqxnrEYKKNE6Y4vAWzGadkHGb4Yuawp0SHbZKkZJQgFvK0KjO3JpCq/0kzR5jJ9tw==", + "license": "Apache-2.0", + "peerDependencies": { + "tailwindcss": "^4.0.0" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "http://localhost:4873/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/throttleit": { + "version": "2.1.0", + "resolved": "http://localhost:4873/throttleit/-/throttleit-2.1.0.tgz", + "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "http://localhost:4873/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "http://localhost:4873/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "http://localhost:4873/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "http://localhost:4873/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "http://localhost:4873/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.57.0", + "resolved": "http://localhost:4873/typescript-eslint/-/typescript-eslint-8.57.0.tgz", + "integrity": "sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.57.0", + "@typescript-eslint/parser": "8.57.0", + "@typescript-eslint/typescript-estree": "8.57.0", + "@typescript-eslint/utils": "8.57.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "http://localhost:4873/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "http://localhost:4873/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "http://localhost:4873/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "http://localhost:4873/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "http://localhost:4873/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "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 + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "http://localhost:4873/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "http://localhost:4873/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "http://localhost:4873/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "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 + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "http://localhost:4873/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "http://localhost:4873/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "http://localhost:4873/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "http://localhost:4873/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, + "node_modules/zrender": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz", + "integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } + }, + "node_modules/zrender/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" } - } - }, - "node_modules/@eslint/object-schema": { - "version": "3.0.3", - "resolved": "http://localhost:4873/@eslint/object-schema/-/object-schema-3.0.3.tgz", - "integrity": "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.6.1", - "resolved": "http://localhost:4873/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", - "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^1.1.1", - "levn": "^0.4.1" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - } - }, - "node_modules/@formatjs/ecma402-abstract": { - "version": "2.3.6", - "resolved": "http://localhost:4873/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz", - "integrity": "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==", - "license": "MIT", - "dependencies": { - "@formatjs/fast-memoize": "2.2.7", - "@formatjs/intl-localematcher": "0.6.2", - "decimal.js": "^10.4.3", - "tslib": "^2.8.0" - } - }, - "node_modules/@formatjs/fast-memoize": { - "version": "2.2.7", - "resolved": "http://localhost:4873/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz", - "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==", - "license": "MIT", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.11.4", - "resolved": "http://localhost:4873/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz", - "integrity": "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==", - "license": "MIT", - "dependencies": { - "@formatjs/ecma402-abstract": "2.3.6", - "@formatjs/icu-skeleton-parser": "1.8.16", - "tslib": "^2.8.0" - } - }, - "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.16", - "resolved": "http://localhost:4873/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz", - "integrity": "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==", - "license": "MIT", - "dependencies": { - "@formatjs/ecma402-abstract": "2.3.6", - "tslib": "^2.8.0" - } - }, - "node_modules/@formatjs/intl-localematcher": { - "version": "0.6.2", - "resolved": "http://localhost:4873/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz", - "integrity": "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==", - "license": "MIT", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@fortawesome/fontawesome-common-types": { - "version": "7.2.0", - "resolved": "https://npm.fontawesome.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.2.0.tgz", - "integrity": "sha512-IpR0bER9FY25p+e7BmFH25MZKEwFHTfRAfhOyJubgiDnoJNsSvJ7nigLraHtp4VOG/cy8D7uiV0dLkHOne5Fhw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "7.2.0", - "resolved": "https://npm.fontawesome.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-7.2.0.tgz", - "integrity": "sha512-6639htZMjEkwskf3J+e6/iar+4cTNM9qhoWuRfj9F3eJD6r7iCzV1SWnQr2Mdv0QT0suuqU8BoJCZUyCtP9R4Q==", - "license": "MIT", - "dependencies": { - "@fortawesome/fontawesome-common-types": "7.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/free-solid-svg-icons": { - "version": "7.2.0", - "resolved": "https://npm.fontawesome.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-7.2.0.tgz", - "integrity": "sha512-YTVITFGN0/24PxzXrwqCgnyd7njDuzp5ZvaCx5nq/jg55kUYd94Nj8UTchBdBofi/L0nwRfjGOg0E41d2u9T1w==", - "license": "(CC-BY-4.0 AND MIT)", - "dependencies": { - "@fortawesome/fontawesome-common-types": "7.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/pro-duotone-svg-icons": { - "version": "7.2.0", - "resolved": "https://npm.fontawesome.com/@fortawesome/pro-duotone-svg-icons/-/pro-duotone-svg-icons-7.2.0.tgz", - "integrity": "sha512-G0oZPLWrOjodNsKEzjnmZ/wzXCQhyXHsscIuCsRwPr42N0zgMmVvClZuEq6eqiBiyo1qhm3RnN6xNLddJh9z7A==", - "license": "UNLICENSED", - "dependencies": { - "@fortawesome/fontawesome-common-types": "7.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/pro-light-svg-icons": { - "version": "7.2.0", - "resolved": "https://npm.fontawesome.com/@fortawesome/pro-light-svg-icons/-/pro-light-svg-icons-7.2.0.tgz", - "integrity": "sha512-0SZf+Lu4DoolJelZi9Cc1Ta2VqUGkvV6BPxCb22mV16GQhqGa2VuLkqAn7zur0Sy8Cinu6MyPRfndHSe72zYyQ==", - "license": "UNLICENSED", - "dependencies": { - "@fortawesome/fontawesome-common-types": "7.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/pro-regular-svg-icons": { - "version": "7.2.0", - "resolved": "https://npm.fontawesome.com/@fortawesome/pro-regular-svg-icons/-/pro-regular-svg-icons-7.2.0.tgz", - "integrity": "sha512-FU6amNj6Dbsb2m19T8ABiL8HoImIGm8AhxnPAgQDDZcslGezu6R7HrDicBPJuVTNFSxFGRRAXIRs/z44xg7ftA==", - "license": "UNLICENSED", - "dependencies": { - "@fortawesome/fontawesome-common-types": "7.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/pro-solid-svg-icons": { - "version": "7.2.0", - "resolved": "https://npm.fontawesome.com/@fortawesome/pro-solid-svg-icons/-/pro-solid-svg-icons-7.2.0.tgz", - "integrity": "sha512-r+YsuG1B+iYcCXNS82bfvRnGJtlRhVI5Xk7vVJ9+ymJU5u4UGGGOSFRV5kRWH2zFItH9PKaIjnN1cXMcgOM/+g==", - "license": "UNLICENSED", - "dependencies": { - "@fortawesome/fontawesome-common-types": "7.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/react-fontawesome": { - "version": "3.2.0", - "resolved": "https://npm.fontawesome.com/@fortawesome/react-fontawesome/-/react-fontawesome-3.2.0.tgz", - "integrity": "sha512-E9Gu1hqd6JussVO26EC4WqRZssXMnQr2ol7ZNWkkFOH8jZUaxDJ9Z9WF9wIVkC+kJGXUdY3tlffpDwEKfgQrQw==", - "license": "MIT", - "engines": { - "node": ">=20" - }, - "peerDependencies": { - "@fortawesome/fontawesome-svg-core": "~6 || ~7", - "react": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "http://localhost:4873/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "http://localhost:4873/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "http://localhost:4873/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "http://localhost:4873/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@internationalized/date": { - "version": "3.12.0", - "resolved": "http://localhost:4873/@internationalized/date/-/date-3.12.0.tgz", - "integrity": "sha512-/PyIMzK29jtXaGU23qTvNZxvBXRtKbNnGDFD+PY6CZw/Y8Ex8pFUzkuCJCG9aOqmShjqhS9mPqP6Dk5onQY8rQ==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - } - }, - "node_modules/@internationalized/message": { - "version": "3.1.8", - "resolved": "http://localhost:4873/@internationalized/message/-/message-3.1.8.tgz", - "integrity": "sha512-Rwk3j/TlYZhn3HQ6PyXUV0XP9Uv42jqZGNegt0BXlxjE6G3+LwHjbQZAGHhCnCPdaA6Tvd3ma/7QzLlLkJxAWA==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0", - "intl-messageformat": "^10.1.0" - } - }, - "node_modules/@internationalized/number": { - "version": "3.6.5", - "resolved": "http://localhost:4873/@internationalized/number/-/number-3.6.5.tgz", - "integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - } - }, - "node_modules/@internationalized/string": { - "version": "3.2.7", - "resolved": "http://localhost:4873/@internationalized/string/-/string-3.2.7.tgz", - "integrity": "sha512-D4OHBjrinH+PFZPvfCXvG28n2LSykWcJ7GIioQL+ok0LON15SdfoUssoHzzOUmVZLbRoREsQXVzA6r8JKsbP6A==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "http://localhost:4873/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "http://localhost:4873/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "http://localhost:4873/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "http://localhost:4873/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "http://localhost:4873/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@react-aria/autocomplete": { - "version": "3.0.0-rc.6", - "resolved": "http://localhost:4873/@react-aria/autocomplete/-/autocomplete-3.0.0-rc.6.tgz", - "integrity": "sha512-uymUNJ8NW+dX7lmgkHE+SklAbxwktycAJcI5lBBw6KPZyc0EdMHC+/Fc5CUz3enIAhNwd2oxxogcSHknquMzQA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/combobox": "^3.15.0", - "@react-aria/focus": "^3.21.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/listbox": "^3.15.3", - "@react-aria/searchfield": "^3.8.12", - "@react-aria/textfield": "^3.18.5", - "@react-aria/utils": "^3.33.1", - "@react-stately/autocomplete": "3.0.0-beta.4", - "@react-stately/combobox": "^3.13.0", - "@react-types/autocomplete": "3.0.0-alpha.38", - "@react-types/button": "^3.15.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/breadcrumbs": { - "version": "3.5.32", - "resolved": "http://localhost:4873/@react-aria/breadcrumbs/-/breadcrumbs-3.5.32.tgz", - "integrity": "sha512-S61vh5DJ2PXiXUwD7gk+pvS/b4VPrc3ZJOUZ0yVRLHkVESr5LhIZH+SAVgZkm1lzKyMRG+BH+fiRH/DZRSs7SA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.16", - "@react-aria/link": "^3.8.9", - "@react-aria/utils": "^3.33.1", - "@react-types/breadcrumbs": "^3.7.19", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/button": { - "version": "3.14.5", - "resolved": "http://localhost:4873/@react-aria/button/-/button-3.14.5.tgz", - "integrity": "sha512-ZuLx+wQj9VQhH9BYe7t0JowmKnns2XrFHFNvIVBb5RwxL+CIycIOL7brhWKg2rGdxvlOom7jhVbcjSmtAaSyaQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/toolbar": "3.0.0-beta.24", - "@react-aria/utils": "^3.33.1", - "@react-stately/toggle": "^3.9.5", - "@react-types/button": "^3.15.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/calendar": { - "version": "3.9.5", - "resolved": "http://localhost:4873/@react-aria/calendar/-/calendar-3.9.5.tgz", - "integrity": "sha512-k0kvceYdZZu+DoeqephtlmIvh1CxqdFyoN52iqVzTz9O0pe5Xfhq7zxPGbeCp4pC61xzp8Lu/6uFA/YNfQQNag==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.12.0", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/utils": "^3.33.1", - "@react-stately/calendar": "^3.9.3", - "@react-types/button": "^3.15.1", - "@react-types/calendar": "^3.8.3", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/checkbox": { - "version": "3.16.5", - "resolved": "http://localhost:4873/@react-aria/checkbox/-/checkbox-3.16.5.tgz", - "integrity": "sha512-ZhUT7ELuD52hb+Zpzw0ElLQiVOd5sKYahrh+PK3vq13Wk5TedBscALpjuXetI4pwFfdmAM1Lhgcsrd8+6AmyvA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/form": "^3.1.5", - "@react-aria/interactions": "^3.27.1", - "@react-aria/label": "^3.7.25", - "@react-aria/toggle": "^3.12.5", - "@react-aria/utils": "^3.33.1", - "@react-stately/checkbox": "^3.7.5", - "@react-stately/form": "^3.2.4", - "@react-stately/toggle": "^3.9.5", - "@react-types/checkbox": "^3.10.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/collections": { - "version": "3.0.3", - "resolved": "http://localhost:4873/@react-aria/collections/-/collections-3.0.3.tgz", - "integrity": "sha512-lbC5DEbHeVFvVr4ke9y8D9Nynnr8G8UjVEBoFGRylpAaScU7SX1TN84QI+EjMbsdZ0/5P2H7gUTS+MYd+6U3Rg==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.33.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0", - "use-sync-external-store": "^1.6.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/color": { - "version": "3.1.5", - "resolved": "http://localhost:4873/@react-aria/color/-/color-3.1.5.tgz", - "integrity": "sha512-eysWdBRzE8WDhBzh1nfjyUgzseMokXGHjIoJo880T7IPJ8tTavfQni49pU1B2qWrNOWPyrwx4Bd9pzHyboxJSA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/numberfield": "^3.12.5", - "@react-aria/slider": "^3.8.5", - "@react-aria/spinbutton": "^3.7.2", - "@react-aria/textfield": "^3.18.5", - "@react-aria/utils": "^3.33.1", - "@react-aria/visually-hidden": "^3.8.31", - "@react-stately/color": "^3.9.5", - "@react-stately/form": "^3.2.4", - "@react-types/color": "^3.1.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/combobox": { - "version": "3.15.0", - "resolved": "http://localhost:4873/@react-aria/combobox/-/combobox-3.15.0.tgz", - "integrity": "sha512-qSjQTFwKl3x1jCP2NRSJ6doZqAp6c2GTfoiFwWjaWg1IewwLsglaW6NnzqRDFiqFbDGgXPn4MqtC1VYEJ3NEjA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/listbox": "^3.15.3", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/menu": "^3.21.0", - "@react-aria/overlays": "^3.31.2", - "@react-aria/selection": "^3.27.2", - "@react-aria/textfield": "^3.18.5", - "@react-aria/utils": "^3.33.1", - "@react-stately/collections": "^3.12.10", - "@react-stately/combobox": "^3.13.0", - "@react-stately/form": "^3.2.4", - "@react-types/button": "^3.15.1", - "@react-types/combobox": "^3.14.0", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/datepicker": { - "version": "3.16.1", - "resolved": "http://localhost:4873/@react-aria/datepicker/-/datepicker-3.16.1.tgz", - "integrity": "sha512-6BltCVWt09yefTkGjb2gViGCwoddx9HKJiZbY9u6Es/Q+VhwNJQRtczbnZ3K32p262hIknukNf/5nZaCOI1AKA==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.12.0", - "@internationalized/number": "^3.6.5", - "@internationalized/string": "^3.2.7", - "@react-aria/focus": "^3.21.5", - "@react-aria/form": "^3.1.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/label": "^3.7.25", - "@react-aria/spinbutton": "^3.7.2", - "@react-aria/utils": "^3.33.1", - "@react-stately/datepicker": "^3.16.1", - "@react-stately/form": "^3.2.4", - "@react-types/button": "^3.15.1", - "@react-types/calendar": "^3.8.3", - "@react-types/datepicker": "^3.13.5", - "@react-types/dialog": "^3.5.24", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/dialog": { - "version": "3.5.34", - "resolved": "http://localhost:4873/@react-aria/dialog/-/dialog-3.5.34.tgz", - "integrity": "sha512-/x53Q5ynpW5Kv9637WYu7SrDfj3woSp6jJRj8l6teGnWW/iNZWYJETgzHfbxx+HPKYATCZesRoIeO2LnYIXyEA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/overlays": "^3.31.2", - "@react-aria/utils": "^3.33.1", - "@react-types/dialog": "^3.5.24", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/disclosure": { - "version": "3.1.3", - "resolved": "http://localhost:4873/@react-aria/disclosure/-/disclosure-3.1.3.tgz", - "integrity": "sha512-S3k7Wqrj+x0sWcP88Z1stSr5TIZmKEmx2rU7RB1O1/jPpbw5mgKnjtiriOlTh+kwdK11FkeqgxyHzAcBAR+FMQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.33.1", - "@react-stately/disclosure": "^3.0.11", - "@react-types/button": "^3.15.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/dnd": { - "version": "3.11.6", - "resolved": "http://localhost:4873/@react-aria/dnd/-/dnd-3.11.6.tgz", - "integrity": "sha512-4YLHUeYJleF+moAYaYt8UZqujudPvpoaHR+QMkWIFzhfridVUhCr6ZjGWrzpSZY3r68k46TG7YCsi4IEiNnysw==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/string": "^3.2.7", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/overlays": "^3.31.2", - "@react-aria/utils": "^3.33.1", - "@react-stately/collections": "^3.12.10", - "@react-stately/dnd": "^3.7.4", - "@react-types/button": "^3.15.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/focus": { - "version": "3.21.5", - "resolved": "http://localhost:4873/@react-aria/focus/-/focus-3.21.5.tgz", - "integrity": "sha512-V18fwCyf8zqgJdpLQeDU5ZRNd9TeOfBbhLgmX77Zr5ae9XwaoJ1R3SFJG1wCJX60t34AW+aLZSEEK+saQElf3Q==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/utils": "^3.33.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/form": { - "version": "3.1.5", - "resolved": "http://localhost:4873/@react-aria/form/-/form-3.1.5.tgz", - "integrity": "sha512-BWlONgHn8hmaMkcS6AgMSLQeNqVBwqPNLhdqjDO/PCfzvV7O8NZw/dFeIzJwfG4aBfSpbHHRdXGdfrk3d8dylQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/utils": "^3.33.1", - "@react-stately/form": "^3.2.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid": { - "version": "3.14.8", - "resolved": "http://localhost:4873/@react-aria/grid/-/grid-3.14.8.tgz", - "integrity": "sha512-X6rRFKDu/Kh6Sv8FBap3vjcb+z4jXkSOwkYnexIJp5kMTo5/Dqo55cCBio5B70Tanfv32Ev/6SpzYG7ryxnM9w==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/selection": "^3.27.2", - "@react-aria/utils": "^3.33.1", - "@react-stately/collections": "^3.12.10", - "@react-stately/grid": "^3.11.9", - "@react-stately/selection": "^3.20.9", - "@react-types/checkbox": "^3.10.4", - "@react-types/grid": "^3.3.8", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/gridlist": { - "version": "3.14.4", - "resolved": "http://localhost:4873/@react-aria/gridlist/-/gridlist-3.14.4.tgz", - "integrity": "sha512-C/SbwC0qagZatoBrCjx8iZUex9apaJ8o8iRJ9eVHz0cpj7mXg6HuuotYGmDy9q67A2hve4I693RM1Cuwqwm+PQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/grid": "^3.14.8", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/selection": "^3.27.2", - "@react-aria/utils": "^3.33.1", - "@react-stately/list": "^3.13.4", - "@react-stately/tree": "^3.9.6", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/i18n": { - "version": "3.12.16", - "resolved": "http://localhost:4873/@react-aria/i18n/-/i18n-3.12.16.tgz", - "integrity": "sha512-Km2CAz6MFQOUEaattaW+2jBdWOHUF8WX7VQoNbjlqElCP58nSaqi9yxTWUDRhAcn8/xFUnkFh4MFweNgtrHuEA==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.12.0", - "@internationalized/message": "^3.1.8", - "@internationalized/number": "^3.6.5", - "@internationalized/string": "^3.2.7", - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.33.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/interactions": { - "version": "3.27.1", - "resolved": "http://localhost:4873/@react-aria/interactions/-/interactions-3.27.1.tgz", - "integrity": "sha512-M3wLpTTmDflI0QGNK0PJNUaBXXfeBXue8ZxLMngfc1piHNiH4G5lUvWd9W14XVbqrSCVY8i8DfGrNYpyyZu0tw==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.33.1", - "@react-stately/flags": "^3.1.2", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/label": { - "version": "3.7.25", - "resolved": "http://localhost:4873/@react-aria/label/-/label-3.7.25.tgz", - "integrity": "sha512-oNK3Pqj4LDPwEbQaoM/uCip4QvQmmwGOh08VeW+vzSi6TAwf+KoWTyH/tiAeB0CHWNDK0k3e1iTygTAt4wzBmg==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/utils": "^3.33.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/landmark": { - "version": "3.0.10", - "resolved": "http://localhost:4873/@react-aria/landmark/-/landmark-3.0.10.tgz", - "integrity": "sha512-GpNjJaI8/a6WxYDZgzTCLYSzPM6xp2pxCIQ4udiGbTCtxx13Trmm0cPABvPtzELidgolCf05em9Phr+3G0eE8A==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/utils": "^3.33.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0", - "use-sync-external-store": "^1.6.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/link": { - "version": "3.8.9", - "resolved": "http://localhost:4873/@react-aria/link/-/link-3.8.9.tgz", - "integrity": "sha512-UaAFBfs84/Qq6TxlMWkREqqNY6SFLukot+z2Aa1kC+VyStv1kWG6sE5QLjm4SBn1Q3CGRsefhB/5+taaIbB4Pw==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/utils": "^3.33.1", - "@react-types/link": "^3.6.7", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/listbox": { - "version": "3.15.3", - "resolved": "http://localhost:4873/@react-aria/listbox/-/listbox-3.15.3.tgz", - "integrity": "sha512-C6YgiyrHS5sbS5UBdxGMhEs+EKJYotJgGVtl9l0ySXpBUXERiHJWLOyV7a8PwkUOmepbB4FaLD7Y9EUzGkrGlw==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/label": "^3.7.25", - "@react-aria/selection": "^3.27.2", - "@react-aria/utils": "^3.33.1", - "@react-stately/collections": "^3.12.10", - "@react-stately/list": "^3.13.4", - "@react-types/listbox": "^3.7.6", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/live-announcer": { - "version": "3.4.4", - "resolved": "http://localhost:4873/@react-aria/live-announcer/-/live-announcer-3.4.4.tgz", - "integrity": "sha512-PTTBIjNRnrdJOIRTDGNifY2d//kA7GUAwRFJNOEwSNG4FW+Bq9awqLiflw0JkpyB0VNIwou6lqKPHZVLsGWOXA==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - } - }, - "node_modules/@react-aria/menu": { - "version": "3.21.0", - "resolved": "http://localhost:4873/@react-aria/menu/-/menu-3.21.0.tgz", - "integrity": "sha512-CKTVZ4izSE1eKIti6TbTtzJAUo+WT8O4JC0XZCYDBpa0f++lD19Kz9aY+iY1buv5xGI20gAfpO474E9oEd4aQA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/overlays": "^3.31.2", - "@react-aria/selection": "^3.27.2", - "@react-aria/utils": "^3.33.1", - "@react-stately/collections": "^3.12.10", - "@react-stately/menu": "^3.9.11", - "@react-stately/selection": "^3.20.9", - "@react-stately/tree": "^3.9.6", - "@react-types/button": "^3.15.1", - "@react-types/menu": "^3.10.7", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/meter": { - "version": "3.4.30", - "resolved": "http://localhost:4873/@react-aria/meter/-/meter-3.4.30.tgz", - "integrity": "sha512-ZmANKW7s/Z4QGylHi46nhwtQ47T1bfMsU9MysBu7ViXXNJ03F4b6JXCJlKL5o2goQ3NbfZ68GeWamIT0BWSgtw==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/progress": "^3.4.30", - "@react-types/meter": "^3.4.15", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/numberfield": { - "version": "3.12.5", - "resolved": "http://localhost:4873/@react-aria/numberfield/-/numberfield-3.12.5.tgz", - "integrity": "sha512-Fi41IUWXEHLFIeJ/LHuZ9Azs8J/P563fZi37GSBkIq5P1pNt1rPgJJng5CNn4KsHxwqadTRUlbbZwbZraWDtRg==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/spinbutton": "^3.7.2", - "@react-aria/textfield": "^3.18.5", - "@react-aria/utils": "^3.33.1", - "@react-stately/form": "^3.2.4", - "@react-stately/numberfield": "^3.11.0", - "@react-types/button": "^3.15.1", - "@react-types/numberfield": "^3.8.18", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/overlays": { - "version": "3.31.2", - "resolved": "http://localhost:4873/@react-aria/overlays/-/overlays-3.31.2.tgz", - "integrity": "sha512-78HYI08r6LvcfD34gyv19ArRIjy1qxOKuXl/jYnjLDyQzD4pVb634IQWcm0zt10RdKgyuH6HTqvuDOgZTLet7Q==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.33.1", - "@react-aria/visually-hidden": "^3.8.31", - "@react-stately/flags": "^3.1.2", - "@react-stately/overlays": "^3.6.23", - "@react-types/button": "^3.15.1", - "@react-types/overlays": "^3.9.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/progress": { - "version": "3.4.30", - "resolved": "http://localhost:4873/@react-aria/progress/-/progress-3.4.30.tgz", - "integrity": "sha512-S6OWVGgluSWYSd/A6O8CVjz83eeMUfkuWSra0ewAV9bmxZ7TP9pUmD3bGdqHZEl97nt5vHGjZ3eq/x8eCmzKhA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.16", - "@react-aria/label": "^3.7.25", - "@react-aria/utils": "^3.33.1", - "@react-types/progress": "^3.5.18", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/radio": { - "version": "3.12.5", - "resolved": "http://localhost:4873/@react-aria/radio/-/radio-3.12.5.tgz", - "integrity": "sha512-8CCJKJzfozEiWBPO9QAATG1rBGJEJ+xoqvHf9LKU2sPFGsA2/SRnLs6LB9fCG5R3spvaK1xz0any1fjWPl7x8A==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/form": "^3.1.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/label": "^3.7.25", - "@react-aria/utils": "^3.33.1", - "@react-stately/radio": "^3.11.5", - "@react-types/radio": "^3.9.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/searchfield": { - "version": "3.8.12", - "resolved": "http://localhost:4873/@react-aria/searchfield/-/searchfield-3.8.12.tgz", - "integrity": "sha512-kYlUHD/+mWzNroHoR8ojUxYBoMviRZn134WaKPFjfNUGZDOEuh4XzOoj+cjdJfe6N3mwTaYu6rJQtunSHIAfhA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.16", - "@react-aria/textfield": "^3.18.5", - "@react-aria/utils": "^3.33.1", - "@react-stately/searchfield": "^3.5.19", - "@react-types/button": "^3.15.1", - "@react-types/searchfield": "^3.6.8", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/select": { - "version": "3.17.3", - "resolved": "http://localhost:4873/@react-aria/select/-/select-3.17.3.tgz", - "integrity": "sha512-u0UFWw0S7q9oiSbjetDpRoLLIcC+L89uYlm+YfCrdT8ntbQgABNiJRxdVvxnhR0fR6MC9ASTTvuQnNHNn52+1A==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/form": "^3.1.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/label": "^3.7.25", - "@react-aria/listbox": "^3.15.3", - "@react-aria/menu": "^3.21.0", - "@react-aria/selection": "^3.27.2", - "@react-aria/utils": "^3.33.1", - "@react-aria/visually-hidden": "^3.8.31", - "@react-stately/select": "^3.9.2", - "@react-types/button": "^3.15.1", - "@react-types/select": "^3.12.2", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/selection": { - "version": "3.27.2", - "resolved": "http://localhost:4873/@react-aria/selection/-/selection-3.27.2.tgz", - "integrity": "sha512-GbUSSLX/ciXix95KW1g+SLM9np7iXpIZrFDSXkC6oNx1uhy18eAcuTkeZE25+SY5USVUmEzjI3m/3JoSUcebbg==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/utils": "^3.33.1", - "@react-stately/selection": "^3.20.9", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/separator": { - "version": "3.4.16", - "resolved": "http://localhost:4873/@react-aria/separator/-/separator-3.4.16.tgz", - "integrity": "sha512-RCUtQhDGnPxKzyG8KM79yOB0fSiEf8r/rxShidOVnGLiBW2KFmBa22/Gfc4jnqg/keN3dxvkSGoqmeXgctyp6g==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/utils": "^3.33.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/slider": { - "version": "3.8.5", - "resolved": "http://localhost:4873/@react-aria/slider/-/slider-3.8.5.tgz", - "integrity": "sha512-gqkJxznk141mE0JamXF5CXml9PDbPkBz8dyKlihtWHWX4yhEbVYdC9J0otE7iCR3zx69Bm7WHoTGL0BsdpKzVA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/label": "^3.7.25", - "@react-aria/utils": "^3.33.1", - "@react-stately/slider": "^3.7.5", - "@react-types/shared": "^3.33.1", - "@react-types/slider": "^3.8.4", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/spinbutton": { - "version": "3.7.2", - "resolved": "http://localhost:4873/@react-aria/spinbutton/-/spinbutton-3.7.2.tgz", - "integrity": "sha512-adjE1wNCWlugvAtVXlXWPtIG9JWurEgYVn1Eeyh19x038+oXGvOsOAoKCXM+SnGleTWQ9J7pEZITFoEI3cVfAw==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.16", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/utils": "^3.33.1", - "@react-types/button": "^3.15.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/ssr": { - "version": "3.9.10", - "resolved": "http://localhost:4873/@react-aria/ssr/-/ssr-3.9.10.tgz", - "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/switch": { - "version": "3.7.11", - "resolved": "http://localhost:4873/@react-aria/switch/-/switch-3.7.11.tgz", - "integrity": "sha512-dYVX71HiepBsKyeMaQgHbhqI+MQ3MVoTd5EnTbUjefIBnmQZavYj1/e4NUiUI4Ix+/C0HxL8ibDAv4NlSW3eLQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/toggle": "^3.12.5", - "@react-stately/toggle": "^3.9.5", - "@react-types/shared": "^3.33.1", - "@react-types/switch": "^3.5.17", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/table": { - "version": "3.17.11", - "resolved": "http://localhost:4873/@react-aria/table/-/table-3.17.11.tgz", - "integrity": "sha512-GkYmWPiW3OM+FUZxdS33teHXHXde7TjHuYgDDaG9phvg6cQTQjGilJozrzA3OfftTOq5VB8XcKTIQW3c0tpYsQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/grid": "^3.14.8", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/utils": "^3.33.1", - "@react-aria/visually-hidden": "^3.8.31", - "@react-stately/collections": "^3.12.10", - "@react-stately/flags": "^3.1.2", - "@react-stately/table": "^3.15.4", - "@react-types/checkbox": "^3.10.4", - "@react-types/grid": "^3.3.8", - "@react-types/shared": "^3.33.1", - "@react-types/table": "^3.13.6", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/tabs": { - "version": "3.11.1", - "resolved": "http://localhost:4873/@react-aria/tabs/-/tabs-3.11.1.tgz", - "integrity": "sha512-3Ppz7yaEDW9L7p9PE9yNOl5caLwNnnLQqI+MX/dwbWlw9HluHS7uIjb21oswNl6UbSxAWyENOka45+KN4Fkh7A==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/selection": "^3.27.2", - "@react-aria/utils": "^3.33.1", - "@react-stately/tabs": "^3.8.9", - "@react-types/shared": "^3.33.1", - "@react-types/tabs": "^3.3.22", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/tag": { - "version": "3.8.1", - "resolved": "http://localhost:4873/@react-aria/tag/-/tag-3.8.1.tgz", - "integrity": "sha512-VonpO++F8afXGDWc9VUxAc2wefyJpp1n9OGpbnB7zmqWiuPwO/RixjUdcH7iJkiC4vADwx9uLnhyD6kcwGV2ig==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/gridlist": "^3.14.4", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/label": "^3.7.25", - "@react-aria/selection": "^3.27.2", - "@react-aria/utils": "^3.33.1", - "@react-stately/list": "^3.13.4", - "@react-types/button": "^3.15.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/textfield": { - "version": "3.18.5", - "resolved": "http://localhost:4873/@react-aria/textfield/-/textfield-3.18.5.tgz", - "integrity": "sha512-ttwVSuwoV3RPaG2k2QzEXKeQNQ3mbdl/2yy6I4Tjrn1ZNkYHfVyJJ26AjenfSmj1kkTQoSAfZ8p+7rZp4n0xoQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/form": "^3.1.5", - "@react-aria/interactions": "^3.27.1", - "@react-aria/label": "^3.7.25", - "@react-aria/utils": "^3.33.1", - "@react-stately/form": "^3.2.4", - "@react-stately/utils": "^3.11.0", - "@react-types/shared": "^3.33.1", - "@react-types/textfield": "^3.12.8", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/toast": { - "version": "3.0.11", - "resolved": "http://localhost:4873/@react-aria/toast/-/toast-3.0.11.tgz", - "integrity": "sha512-2DjZjBAvm8/CWbnZ6s7LjkYCkULKtjMve6GvhPTq98AthuEDLEiBvM1wa3xdecCRhZyRT1g6DXqVca0EfZ9fJA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/landmark": "^3.0.10", - "@react-aria/utils": "^3.33.1", - "@react-stately/toast": "^3.1.3", - "@react-types/button": "^3.15.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/toggle": { - "version": "3.12.5", - "resolved": "http://localhost:4873/@react-aria/toggle/-/toggle-3.12.5.tgz", - "integrity": "sha512-XXVFLzcV8fr9mz7y/wfxEAhWvaBZ9jSfhCMuxH2bsivO7nTcMJ1jb4g2xJNwZgne17bMWNc7mKvW5dbsdlI6BA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/utils": "^3.33.1", - "@react-stately/toggle": "^3.9.5", - "@react-types/checkbox": "^3.10.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/toolbar": { - "version": "3.0.0-beta.24", - "resolved": "http://localhost:4873/@react-aria/toolbar/-/toolbar-3.0.0-beta.24.tgz", - "integrity": "sha512-B2Rmpko7Ghi2RbNfsGdbR7I+RQBDhPGVE4bU3/EwHz+P/vNe5LyGPTeSwqaOMsQTF9lKNCkY8424dVTCr6RUMg==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.5", - "@react-aria/i18n": "^3.12.16", - "@react-aria/utils": "^3.33.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/tooltip": { - "version": "3.9.2", - "resolved": "http://localhost:4873/@react-aria/tooltip/-/tooltip-3.9.2.tgz", - "integrity": "sha512-VrgkPwHiEnAnBhoQ4W7kfry/RfVuRWrUPaJSp0+wKM6u0gg2tmn7OFRDXTxBAm/omQUguIdIjRWg7sf3zHH82A==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/utils": "^3.33.1", - "@react-stately/tooltip": "^3.5.11", - "@react-types/shared": "^3.33.1", - "@react-types/tooltip": "^3.5.2", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/tree": { - "version": "3.1.7", - "resolved": "http://localhost:4873/@react-aria/tree/-/tree-3.1.7.tgz", - "integrity": "sha512-C54yH5NmsOFa2Q+cg6B1BPr5KUlU9vLIoBnVrgrH237FRSXQPIbcM4VpmITAHq1VR7w6ayyS1hgTwFxo67ykWQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/gridlist": "^3.14.4", - "@react-aria/i18n": "^3.12.16", - "@react-aria/selection": "^3.27.2", - "@react-aria/utils": "^3.33.1", - "@react-stately/tree": "^3.9.6", - "@react-types/button": "^3.15.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/utils": { - "version": "3.33.1", - "resolved": "http://localhost:4873/@react-aria/utils/-/utils-3.33.1.tgz", - "integrity": "sha512-kIx1Sj6bbAT0pdqCegHuPanR9zrLn5zMRiM7LN12rgRf55S19ptd9g3ncahArifYTRkfEU9VIn+q0HjfMqS9/w==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-stately/flags": "^3.1.2", - "@react-stately/utils": "^3.11.0", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/virtualizer": { - "version": "4.1.13", - "resolved": "http://localhost:4873/@react-aria/virtualizer/-/virtualizer-4.1.13.tgz", - "integrity": "sha512-d5KS+p8GXGNRbGPRE/N6jtth3et3KssQIz52h2+CAoAh7C3vvR64kkTaGdeywClvM+fSo8FxJuBrdfQvqC2ktQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/utils": "^3.33.1", - "@react-stately/virtualizer": "^4.4.6", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/visually-hidden": { - "version": "3.8.31", - "resolved": "http://localhost:4873/@react-aria/visually-hidden/-/visually-hidden-3.8.31.tgz", - "integrity": "sha512-RTOHHa4n56a9A3criThqFHBifvZoV71+MCkSuNP2cKO662SUWjqKkd0tJt/mBRMEJPkys8K7Eirp6T8Wt5FFRA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.27.1", - "@react-aria/utils": "^3.33.1", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/autocomplete": { - "version": "3.0.0-beta.4", - "resolved": "http://localhost:4873/@react-stately/autocomplete/-/autocomplete-3.0.0-beta.4.tgz", - "integrity": "sha512-K2Uy7XEdseFvgwRQ8CyrYEHMupjVKEszddOapP8deNz4hntYvT1aRm0m+sKa5Kl/4kvg9c/3NZpQcrky/vRZIg==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/utils": "^3.11.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/calendar": { - "version": "3.9.3", - "resolved": "http://localhost:4873/@react-stately/calendar/-/calendar-3.9.3.tgz", - "integrity": "sha512-uw7fCZXoypSBBUsVkbNvJMQWTihZReRbyLIGG3o/ZM630N3OCZhb/h4Uxke4pNu7n527H0V1bAnZgAldIzOYqg==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.12.0", - "@react-stately/utils": "^3.11.0", - "@react-types/calendar": "^3.8.3", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/checkbox": { - "version": "3.7.5", - "resolved": "http://localhost:4873/@react-stately/checkbox/-/checkbox-3.7.5.tgz", - "integrity": "sha512-K5R5ted7AxLB3sDkuVAazUdyRMraFT1imVqij2GuAiOUFvsZvbuocnDuFkBVKojyV3GpqLBvViV8IaCMc4hNIw==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/form": "^3.2.4", - "@react-stately/utils": "^3.11.0", - "@react-types/checkbox": "^3.10.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/collections": { - "version": "3.12.10", - "resolved": "http://localhost:4873/@react-stately/collections/-/collections-3.12.10.tgz", - "integrity": "sha512-wmF9VxJDyBujBuQ76vXj2g/+bnnj8fx5DdXgRmyfkkYhPB46+g2qnjbVGEvipo7bJuGxDftCUC4SN7l7xqUWfg==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/color": { - "version": "3.9.5", - "resolved": "http://localhost:4873/@react-stately/color/-/color-3.9.5.tgz", - "integrity": "sha512-8pZxzXWDRuglzDwyTG7mLw2LQMCHIVNbVc9YmbsxbOjAL+lOqszo60KzyaFKVxeDQczSvrNTHcQZqlbNIC0eyQ==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/number": "^3.6.5", - "@internationalized/string": "^3.2.7", - "@react-stately/form": "^3.2.4", - "@react-stately/numberfield": "^3.11.0", - "@react-stately/slider": "^3.7.5", - "@react-stately/utils": "^3.11.0", - "@react-types/color": "^3.1.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/combobox": { - "version": "3.13.0", - "resolved": "http://localhost:4873/@react-stately/combobox/-/combobox-3.13.0.tgz", - "integrity": "sha512-dX9g/cK1hjLRjcbWVF6keHxTQDGhKGB2QAgPhWcBmOK3qJv+2dQqsJ6YCGWn/Y2N2acoEseLrAA7+Qe4HWV9cg==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/collections": "^3.12.10", - "@react-stately/form": "^3.2.4", - "@react-stately/list": "^3.13.4", - "@react-stately/overlays": "^3.6.23", - "@react-stately/utils": "^3.11.0", - "@react-types/combobox": "^3.14.0", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/data": { - "version": "3.15.2", - "resolved": "http://localhost:4873/@react-stately/data/-/data-3.15.2.tgz", - "integrity": "sha512-BsmeeGgFwOGwo0g9Waprdyt+846n3KhKggZfpEnp5+sC4dE4uW1VIYpdyupMfr3bQcmX123q6TegfNP3eszrUA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/datepicker": { - "version": "3.16.1", - "resolved": "http://localhost:4873/@react-stately/datepicker/-/datepicker-3.16.1.tgz", - "integrity": "sha512-BtAMDvxd1OZxkxjqq5tN5TYmp6Hm8+o3+IDA4qmem2/pfQfVbOZeWS2WitcPBImj4n4T+W1A5+PI7mT/6DUBVg==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.12.0", - "@internationalized/number": "^3.6.5", - "@internationalized/string": "^3.2.7", - "@react-stately/form": "^3.2.4", - "@react-stately/overlays": "^3.6.23", - "@react-stately/utils": "^3.11.0", - "@react-types/datepicker": "^3.13.5", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/disclosure": { - "version": "3.0.11", - "resolved": "http://localhost:4873/@react-stately/disclosure/-/disclosure-3.0.11.tgz", - "integrity": "sha512-/KjB/0HkxGWbhFAPztCP411LUKZCx9k8cKukrlGqrUWyvrcXlmza90j0g/CuxACBoV+DJP9V+4q+8ide0x750A==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/utils": "^3.11.0", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/dnd": { - "version": "3.7.4", - "resolved": "http://localhost:4873/@react-stately/dnd/-/dnd-3.7.4.tgz", - "integrity": "sha512-YD0TVR5JkvTqskc1ouBpVKs6t/QS4RYCIyu8Ug8RgO122iIizuf2pfKnRLjYMdu5lXzBXGaIgd49dvnLzEXHIw==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/selection": "^3.20.9", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/flags": { - "version": "3.1.2", - "resolved": "http://localhost:4873/@react-stately/flags/-/flags-3.1.2.tgz", - "integrity": "sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - } - }, - "node_modules/@react-stately/form": { - "version": "3.2.4", - "resolved": "http://localhost:4873/@react-stately/form/-/form-3.2.4.tgz", - "integrity": "sha512-qNBzun8SbLdgahryhKLqL1eqP+MXY6as82sVXYOOvUYLzgU5uuN8mObxYlxJgMI5akSdQJQV3RzyfVobPRE7Kw==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/grid": { - "version": "3.11.9", - "resolved": "http://localhost:4873/@react-stately/grid/-/grid-3.11.9.tgz", - "integrity": "sha512-qQY6F+27iZRn30dt0ZOrSetUmbmNJ0pLe9Weuqw3+XDVSuWT+2O/rO1UUYeK+mO0Acjzdv+IWiYbu9RKf2wS9w==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/collections": "^3.12.10", - "@react-stately/selection": "^3.20.9", - "@react-types/grid": "^3.3.8", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/layout": { - "version": "4.6.0", - "resolved": "http://localhost:4873/@react-stately/layout/-/layout-4.6.0.tgz", - "integrity": "sha512-kBenEsP03nh5rKgfqlVMPcoKTJv0v92CTvrAb5gYY8t9g8LOwzdL89Yannq7f5xv8LFck/MmRQlotpMt2InETg==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/collections": "^3.12.10", - "@react-stately/table": "^3.15.4", - "@react-stately/virtualizer": "^4.4.6", - "@react-types/grid": "^3.3.8", - "@react-types/shared": "^3.33.1", - "@react-types/table": "^3.13.6", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/list": { - "version": "3.13.4", - "resolved": "http://localhost:4873/@react-stately/list/-/list-3.13.4.tgz", - "integrity": "sha512-HHYSjA9VG7FPSAtpXAjQyM/V7qFHWGg88WmMrDt5QDlTBexwPuH0oFLnW0qaVZpAIxuWIsutZfxRAnme/NhhAA==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/collections": "^3.12.10", - "@react-stately/selection": "^3.20.9", - "@react-stately/utils": "^3.11.0", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/menu": { - "version": "3.9.11", - "resolved": "http://localhost:4873/@react-stately/menu/-/menu-3.9.11.tgz", - "integrity": "sha512-vYkpO9uV2OUecsIkrOc+Urdl/s1xw/ibNH/UXsp4PtjMnS6mK9q2kXZTM3WvMAKoh12iveUO+YkYCZQshmFLHQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/overlays": "^3.6.23", - "@react-types/menu": "^3.10.7", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/numberfield": { - "version": "3.11.0", - "resolved": "http://localhost:4873/@react-stately/numberfield/-/numberfield-3.11.0.tgz", - "integrity": "sha512-rxfC047vL0LP4tanjinfjKAriAvdVL57Um5RUL5nHML8IOWCB3TBxegQkJ6to6goScC/oZhd0/Y2LSaiRuKbNw==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/number": "^3.6.5", - "@react-stately/form": "^3.2.4", - "@react-stately/utils": "^3.11.0", - "@react-types/numberfield": "^3.8.18", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/overlays": { - "version": "3.6.23", - "resolved": "http://localhost:4873/@react-stately/overlays/-/overlays-3.6.23.tgz", - "integrity": "sha512-RzWxots9A6gAzQMP4s8hOAHV7SbJRTFSlQbb6ly1nkWQXacOSZSFNGsKOaS0eIatfNPlNnW4NIkgtGws5UYzfw==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/utils": "^3.11.0", - "@react-types/overlays": "^3.9.4", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/radio": { - "version": "3.11.5", - "resolved": "http://localhost:4873/@react-stately/radio/-/radio-3.11.5.tgz", - "integrity": "sha512-QxA779S4ea5icQ0ja7CeiNzY1cj7c9G9TN0m7maAIGiTSinZl2Ia8naZJ0XcbRRp+LBll7RFEdekne15TjvS/w==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/form": "^3.2.4", - "@react-stately/utils": "^3.11.0", - "@react-types/radio": "^3.9.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/searchfield": { - "version": "3.5.19", - "resolved": "http://localhost:4873/@react-stately/searchfield/-/searchfield-3.5.19.tgz", - "integrity": "sha512-URllgjbtTQEaOCfddbHpJSPKOzG3pE3ajQHJ7Df8qCoHTjKfL6hnm/vp7X5sxPaZaN7VLZ5kAQxTE8hpo6s0+A==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/utils": "^3.11.0", - "@react-types/searchfield": "^3.6.8", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/select": { - "version": "3.9.2", - "resolved": "http://localhost:4873/@react-stately/select/-/select-3.9.2.tgz", - "integrity": "sha512-oWn0bijuusp8YI7FRM/wgtPVqiIrgU/ZUfLKe/qJUmT8D+JFaMAJnyrAzKpx98TrgamgtXynF78ccpopPhgrKQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/form": "^3.2.4", - "@react-stately/list": "^3.13.4", - "@react-stately/overlays": "^3.6.23", - "@react-stately/utils": "^3.11.0", - "@react-types/select": "^3.12.2", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/selection": { - "version": "3.20.9", - "resolved": "http://localhost:4873/@react-stately/selection/-/selection-3.20.9.tgz", - "integrity": "sha512-RhxRR5Wovg9EVi3pq7gBPK2BoKmP59tOXDMh2r1PbnGevg/7TNdR67DCEblcmXwHuBNS46ELfKdd0XGHqmS8nQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/collections": "^3.12.10", - "@react-stately/utils": "^3.11.0", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/slider": { - "version": "3.7.5", - "resolved": "http://localhost:4873/@react-stately/slider/-/slider-3.7.5.tgz", - "integrity": "sha512-OrQMNR5xamLYH52TXtvTgyw3EMwv+JI+1istQgEj1CHBjC9eZZqn5iNCN20tzm+uDPTH0EIGULFjjPIumqYUQg==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/utils": "^3.11.0", - "@react-types/shared": "^3.33.1", - "@react-types/slider": "^3.8.4", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/table": { - "version": "3.15.4", - "resolved": "http://localhost:4873/@react-stately/table/-/table-3.15.4.tgz", - "integrity": "sha512-fGaNyw3wv7JgRCNzgyDzpaaTFuSy5f4Qekch4UheMXDJX7dOeaMhUXeOfvnXCVg+BGM4ey/D82RvDOGvPy1Nww==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/collections": "^3.12.10", - "@react-stately/flags": "^3.1.2", - "@react-stately/grid": "^3.11.9", - "@react-stately/selection": "^3.20.9", - "@react-stately/utils": "^3.11.0", - "@react-types/grid": "^3.3.8", - "@react-types/shared": "^3.33.1", - "@react-types/table": "^3.13.6", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/tabs": { - "version": "3.8.9", - "resolved": "http://localhost:4873/@react-stately/tabs/-/tabs-3.8.9.tgz", - "integrity": "sha512-AQ4Xrn6YzIolaVShCV9cnwOjBKPAOGP/PTp7wpSEtQbQ0HZzUDG2RG/M4baMeUB2jZ33b7ifXyPcK78o0uOftg==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/list": "^3.13.4", - "@react-types/shared": "^3.33.1", - "@react-types/tabs": "^3.3.22", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/toast": { - "version": "3.1.3", - "resolved": "http://localhost:4873/@react-stately/toast/-/toast-3.1.3.tgz", - "integrity": "sha512-mT9QJKmD523lqFpOp0VWZ6QHZENFK7HrodnNJDVc7g616s5GNmemdlkITV43fSY3tHeThCVvPu+Uzh7RvQ9mpQ==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0", - "use-sync-external-store": "^1.6.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/toggle": { - "version": "3.9.5", - "resolved": "http://localhost:4873/@react-stately/toggle/-/toggle-3.9.5.tgz", - "integrity": "sha512-PVzXc788q3jH98Kvw1LYDL+wpVC14dCEKjOku8cSaqhEof6AJGaLR9yq+EF1yYSL2dxI6z8ghc0OozY8WrcFcA==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/utils": "^3.11.0", - "@react-types/checkbox": "^3.10.4", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/tooltip": { - "version": "3.5.11", - "resolved": "http://localhost:4873/@react-stately/tooltip/-/tooltip-3.5.11.tgz", - "integrity": "sha512-o8PnFXbvDCuVZ4Ht9ahfS6KHwIZjXopvoQ2vUPxv920irdgWEeC+4omgDOnJ/xFvcpmmJAmSsrQsTQrTguDUQA==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/overlays": "^3.6.23", - "@react-types/tooltip": "^3.5.2", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/tree": { - "version": "3.9.6", - "resolved": "http://localhost:4873/@react-stately/tree/-/tree-3.9.6.tgz", - "integrity": "sha512-JCuhGyX2A+PAMsx2pRSwArfqNFZJ9JSPkDaOQJS8MFPAsBe5HemvXsdmv9aBIMzlbCYcVq6EsrFnzbVVTBt/6w==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/collections": "^3.12.10", - "@react-stately/selection": "^3.20.9", - "@react-stately/utils": "^3.11.0", - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/utils": { - "version": "3.11.0", - "resolved": "http://localhost:4873/@react-stately/utils/-/utils-3.11.0.tgz", - "integrity": "sha512-8LZpYowJ9eZmmYLpudbo/eclIRnbhWIJZ994ncmlKlouNzKohtM8qTC6B1w1pwUbiwGdUoyzLuQbeaIor5Dvcw==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/virtualizer": { - "version": "4.4.6", - "resolved": "http://localhost:4873/@react-stately/virtualizer/-/virtualizer-4.4.6.tgz", - "integrity": "sha512-9SfXgLFB61/8SXNLfg5ARx9jAK4m03Aw6/Cg8mdZN24SYarL4TKNRpfw8K/HHVU/bi6WHSJypk6Z/z19o/ztrg==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/autocomplete": { - "version": "3.0.0-alpha.38", - "resolved": "http://localhost:4873/@react-types/autocomplete/-/autocomplete-3.0.0-alpha.38.tgz", - "integrity": "sha512-0XrlVC8drzcrCNzybbkZdLcTofXEzBsHuaFevt5awW1J0xBJ+SMLIQMDeUYrvKjjwXUBlCtjJJpOvitGt4Z+KA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/combobox": "^3.14.0", - "@react-types/searchfield": "^3.6.8", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/breadcrumbs": { - "version": "3.7.19", - "resolved": "http://localhost:4873/@react-types/breadcrumbs/-/breadcrumbs-3.7.19.tgz", - "integrity": "sha512-AnkyYYmzaM2QFi/N0P/kQLM8tHOyFi7p397B/jEMucXDfwMw5Ny1ObCXeIEqbh8KrIa2Xp8SxmQlCV+8FPs4LA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/link": "^3.6.7", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/button": { - "version": "3.15.1", - "resolved": "http://localhost:4873/@react-types/button/-/button-3.15.1.tgz", - "integrity": "sha512-M1HtsKreJkigCnqceuIT22hDJBSStbPimnpmQmsl7SNyqCFY3+DHS7y/Sl3GvqCkzxF7j9UTL0dG38lGQ3K4xQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/calendar": { - "version": "3.8.3", - "resolved": "http://localhost:4873/@react-types/calendar/-/calendar-3.8.3.tgz", - "integrity": "sha512-fpH6WNXotzH0TlKHXXxtjeLZ7ko0sbyHmwDAwmDFyP7T0Iwn1YQZ+lhceLifvynlxuOgX6oBItyUKmkHQ0FouQ==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.12.0", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/checkbox": { - "version": "3.10.4", - "resolved": "http://localhost:4873/@react-types/checkbox/-/checkbox-3.10.4.tgz", - "integrity": "sha512-tYCG0Pd1usEz5hjvBEYcqcA0youx930Rss1QBIse9TgMekA1c2WmPDNupYV8phpO8Zuej3DL1WfBeXcgavK8aw==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/color": { - "version": "3.1.4", - "resolved": "http://localhost:4873/@react-types/color/-/color-3.1.4.tgz", - "integrity": "sha512-s+Xj4pvNBlJPpQ1Gr7bO1j4/tuwMUfdS9xIVFuiW5RvDsSybKTUJ/gqPzTxms94VDCRhLFocVn2STNdD2Erf6A==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1", - "@react-types/slider": "^3.8.4" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/combobox": { - "version": "3.14.0", - "resolved": "http://localhost:4873/@react-types/combobox/-/combobox-3.14.0.tgz", - "integrity": "sha512-zmSSS7BcCOD8rGT8eGbVy7UlL5qq1vm88fFn4WgFe+lfK33ne+E7yTzTxcPY2TCGSo5fY6xMj3OG79FfVNGbSg==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/datepicker": { - "version": "3.13.5", - "resolved": "http://localhost:4873/@react-types/datepicker/-/datepicker-3.13.5.tgz", - "integrity": "sha512-j28Vz+xvbb4bj7+9Xbpc4WTvSitlBvt7YEaEGM/8ZQ5g4Jr85H2KwkmDwjzmMN2r6VMQMMYq9JEcemq5wWpfUQ==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.12.0", - "@react-types/calendar": "^3.8.3", - "@react-types/overlays": "^3.9.4", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/dialog": { - "version": "3.5.24", - "resolved": "http://localhost:4873/@react-types/dialog/-/dialog-3.5.24.tgz", - "integrity": "sha512-NFurEP/zV0dA/41422lV1t+0oh6f/13n+VmLHZG8R13m1J3ql/kAXZ49zBSqkqANBO1ojyugWebk99IiR4pYOw==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/overlays": "^3.9.4", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/form": { - "version": "3.7.18", - "resolved": "http://localhost:4873/@react-types/form/-/form-3.7.18.tgz", - "integrity": "sha512-0sBJW0+I9nJcF4SmKrYFEWAlehiebSTy7xqriqAXtqfTEdvzAYLGaAK2/7gx+wlNZeDTdW43CDRJ4XAhyhBqnw==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/grid": { - "version": "3.3.8", - "resolved": "http://localhost:4873/@react-types/grid/-/grid-3.3.8.tgz", - "integrity": "sha512-zJvXH8gc1e1VH2H3LRnHH/W2HIkLkZMH3Cu5pLcj0vDuLBSWpcr3Ikh3jZ+VUOZF0G1Jt1lO8pKIaqFzDLNmLQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/link": { - "version": "3.6.7", - "resolved": "http://localhost:4873/@react-types/link/-/link-3.6.7.tgz", - "integrity": "sha512-1apXCFJgMC1uydc2KNENrps1qR642FqDpwlNWe254UTpRZn/hEZhA6ImVr8WhomfLJu672WyWA0rUOv4HT+/pQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/listbox": { - "version": "3.7.6", - "resolved": "http://localhost:4873/@react-types/listbox/-/listbox-3.7.6.tgz", - "integrity": "sha512-335NYElKEByXMalAmeRPyulKIDd2cjOCQhLwvv2BtxO5zaJfZnBbhZs+XPd9zwU6YomyOxODKSHrwbNDx+Jf3w==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/menu": { - "version": "3.10.7", - "resolved": "http://localhost:4873/@react-types/menu/-/menu-3.10.7.tgz", - "integrity": "sha512-+p7ixZdvPDJZhisqdtWiiuJ9pteNfK5i19NB6wzAw5XkljbEzodNhwLv6rI96DY5XpbFso2kcjw7IWi+rAAGGQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/overlays": "^3.9.4", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/meter": { - "version": "3.4.15", - "resolved": "http://localhost:4873/@react-types/meter/-/meter-3.4.15.tgz", - "integrity": "sha512-9WjNphhLLM+TA4Ev1y2MkpugJ5JjTXseHh7ZWWx2veq5DrXMZYclkRpfUrUdLVKvaBIPQCgpQIj0TcQi+quR9A==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/progress": "^3.5.18" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/numberfield": { - "version": "3.8.18", - "resolved": "http://localhost:4873/@react-types/numberfield/-/numberfield-3.8.18.tgz", - "integrity": "sha512-nLzk7YAG9yAUtSv+9R8LgCHsu8hJq8/A+m1KsKxvc8WmNJjIujSFgWvT21MWBiUgPBzJKGzAqpMDDa087mltJQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/overlays": { - "version": "3.9.4", - "resolved": "http://localhost:4873/@react-types/overlays/-/overlays-3.9.4.tgz", - "integrity": "sha512-7Z9HaebMFyYBqtv3XVNHEmVkm7AiYviV7gv0c98elEN2Co+eQcKFGvwBM9Gy/lV57zlTqFX1EX/SAqkMEbCLOA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/progress": { - "version": "3.5.18", - "resolved": "http://localhost:4873/@react-types/progress/-/progress-3.5.18.tgz", - "integrity": "sha512-mKeQn+KrHr1y0/k7KtrbeDGDaERH6i4f6yBwj/ZtYDCTNKMO3tPHJY6nzF0w/KKZLplIO+BjUbHXc2RVm8ovwQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/radio": { - "version": "3.9.4", - "resolved": "http://localhost:4873/@react-types/radio/-/radio-3.9.4.tgz", - "integrity": "sha512-TkMRY3sA1PcFZhhclu4IUzUTIir6MzNJj8h6WT8vO6Nug2kXJ72qigugVFBWJSE472mltduOErEAo0rtAYWbQA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/searchfield": { - "version": "3.6.8", - "resolved": "http://localhost:4873/@react-types/searchfield/-/searchfield-3.6.8.tgz", - "integrity": "sha512-M2p7OVdMTMDmlBcHd4N2uCBwg3uJSNM4lmEyf09YD44N5wDAI0yogk52QBwsnhpe+i2s65UwCYgunB+QltRX8A==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1", - "@react-types/textfield": "^3.12.8" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/select": { - "version": "3.12.2", - "resolved": "http://localhost:4873/@react-types/select/-/select-3.12.2.tgz", - "integrity": "sha512-AseOjfr3qM1W1qIWcbAe6NFpwZluVeQX/dmu9BYxjcnVvtoBLPMbE5zX/BPbv+N5eFYjoMyj7Ug9dqnI+LrlGw==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/shared": { - "version": "3.33.1", - "resolved": "http://localhost:4873/@react-types/shared/-/shared-3.33.1.tgz", - "integrity": "sha512-oJHtjvLG43VjwemQDadlR5g/8VepK56B/xKO2XORPHt9zlW6IZs3tZrYlvH29BMvoqC7RtE7E5UjgbnbFtDGag==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/slider": { - "version": "3.8.4", - "resolved": "http://localhost:4873/@react-types/slider/-/slider-3.8.4.tgz", - "integrity": "sha512-C+xFVvfKREai9S/ekBDCVaGPOQYkNUAsQhjQnNsUAATaox4I6IYLmcIgLmljpMQWqAe+gZiWsIwacRYMez2Tew==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/switch": { - "version": "3.5.17", - "resolved": "http://localhost:4873/@react-types/switch/-/switch-3.5.17.tgz", - "integrity": "sha512-2GTPJvBCYI8YZ3oerHtXg+qikabIXCMJ6C2wcIJ5Xn0k9XOovowghfJi10OPB2GGyOiLBU74CczP5nx8adG90Q==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/table": { - "version": "3.13.6", - "resolved": "http://localhost:4873/@react-types/table/-/table-3.13.6.tgz", - "integrity": "sha512-eluL+iFfnVmFm7OSZrrFG9AUjw+tcv898zbv+NsZACa8oXG1v9AimhZfd+Mo8q/5+sX/9hguWNXFkSvmTjuVPQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/grid": "^3.3.8", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/tabs": { - "version": "3.3.22", - "resolved": "http://localhost:4873/@react-types/tabs/-/tabs-3.3.22.tgz", - "integrity": "sha512-HGwLD9dA3k3AGfRKGFBhNgxU9/LyRmxN0kxVj1ghA4L9S/qTOzS6GhrGNkGzsGxyVLV4JN8MLxjWN2o9QHnLEg==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/textfield": { - "version": "3.12.8", - "resolved": "http://localhost:4873/@react-types/textfield/-/textfield-3.12.8.tgz", - "integrity": "sha512-wt6FcuE5AyntxsnPika/h3nf/DPmeAVbI018L9o6h+B/IL4sMWWdx663wx2KOOeHH8ejKGZQNPLhUKs4s1mVQA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/tooltip": { - "version": "3.5.2", - "resolved": "http://localhost:4873/@react-types/tooltip/-/tooltip-3.5.2.tgz", - "integrity": "sha512-FvSuZ2WP08NEWefrpCdBYpEEZh/5TvqvGjq0wqGzWg2OPwpc14HjD8aE7I3MOuylXkD4MSlMjl7J4DlvlcCs3Q==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/overlays": "^3.9.4", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.7", - "resolved": "http://localhost:4873/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", - "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "http://localhost:4873/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "http://localhost:4873/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", - "license": "MIT" - }, - "node_modules/@swc/core": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core/-/core-1.15.18.tgz", - "integrity": "sha512-z87aF9GphWp//fnkRsqvtY+inMVPgYW3zSlXH1kJFvRT5H/wiAn+G32qW5l3oEk63KSF1x3Ov0BfHCObAmT8RA==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.25" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.15.18", - "@swc/core-darwin-x64": "1.15.18", - "@swc/core-linux-arm-gnueabihf": "1.15.18", - "@swc/core-linux-arm64-gnu": "1.15.18", - "@swc/core-linux-arm64-musl": "1.15.18", - "@swc/core-linux-x64-gnu": "1.15.18", - "@swc/core-linux-x64-musl": "1.15.18", - "@swc/core-win32-arm64-msvc": "1.15.18", - "@swc/core-win32-ia32-msvc": "1.15.18", - "@swc/core-win32-x64-msvc": "1.15.18" - }, - "peerDependencies": { - "@swc/helpers": ">=0.5.17" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.18.tgz", - "integrity": "sha512-+mIv7uBuSaywN3C9LNuWaX1jJJ3SKfiJuE6Lr3bd+/1Iv8oMU7oLBjYMluX1UrEPzwN2qCdY6Io0yVicABoCwQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-darwin-x64/-/core-darwin-x64-1.15.18.tgz", - "integrity": "sha512-wZle0eaQhnzxWX5V/2kEOI6Z9vl/lTFEC6V4EWcn+5pDjhemCpQv9e/TDJ0GIoiClX8EDWRvuZwh+Z3dhL1NAg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.18.tgz", - "integrity": "sha512-ao61HGXVqrJFHAcPtF4/DegmwEkVCo4HApnotLU8ognfmU8x589z7+tcf3hU+qBiU1WOXV5fQX6W9Nzs6hjxDw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.18.tgz", - "integrity": "sha512-3xnctOBLIq3kj8PxOCgPrGjBLP/kNOddr6f5gukYt/1IZxsITQaU9TDyjeX6jG+FiCIHjCuWuffsyQDL5Ew1bg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.18.tgz", - "integrity": "sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.18.tgz", - "integrity": "sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.18.tgz", - "integrity": "sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.18.tgz", - "integrity": "sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.18.tgz", - "integrity": "sha512-yVuTrZ0RccD5+PEkpcLOBAuPbYBXS6rslENvIXfvJGXSdX5QGi1ehC4BjAMl5FkKLiam4kJECUI0l7Hq7T1vwg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.15.18", - "resolved": "http://localhost:4873/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.18.tgz", - "integrity": "sha512-7NRmE4hmUQNCbYU3Hn9Tz57mK9Qq4c97ZS+YlamlK6qG9Fb5g/BB3gPDe0iLlJkns/sYv2VWSkm8c3NmbEGjbg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "http://localhost:4873/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@swc/helpers": { - "version": "0.5.19", - "resolved": "http://localhost:4873/@swc/helpers/-/helpers-0.5.19.tgz", - "integrity": "sha512-QamiFeIK3txNjgUTNppE6MiG3p7TdninpZu0E0PbqVh1a9FNLT2FRhisaa4NcaX52XVhA5l7Pk58Ft7Sqi/2sA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@swc/types": { - "version": "0.1.25", - "resolved": "http://localhost:4873/@swc/types/-/types-0.1.25.tgz", - "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3" - } - }, - "node_modules/@tailwindcss/node": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/node/-/node-4.2.1.tgz", - "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.19.0", - "jiti": "^2.6.1", - "lightningcss": "1.31.1", - "magic-string": "^0.30.21", - "source-map-js": "^1.2.1", - "tailwindcss": "4.2.1" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide/-/oxide-4.2.1.tgz", - "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-x64": "4.2.1", - "@tailwindcss/oxide-freebsd-x64": "4.2.1", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-x64-musl": "4.2.1", - "@tailwindcss/oxide-wasm32-wasi": "4.2.1", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", - "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", - "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", - "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", - "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", - "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", - "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", - "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", - "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", - "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", - "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.8.1", - "@emnapi/runtime": "^1.8.1", - "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.1", - "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", - "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", - "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/postcss": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/postcss/-/postcss-4.2.1.tgz", - "integrity": "sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.2.1", - "@tailwindcss/oxide": "4.2.1", - "postcss": "^8.5.6", - "tailwindcss": "4.2.1" - } - }, - "node_modules/@tailwindcss/typography": { - "version": "0.5.19", - "resolved": "http://localhost:4873/@tailwindcss/typography/-/typography-0.5.19.tgz", - "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "6.0.10" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" - } - }, - "node_modules/@tailwindcss/vite": { - "version": "4.2.1", - "resolved": "http://localhost:4873/@tailwindcss/vite/-/vite-4.2.1.tgz", - "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", - "license": "MIT", - "dependencies": { - "@tailwindcss/node": "4.2.1", - "@tailwindcss/oxide": "4.2.1", - "tailwindcss": "4.2.1" - }, - "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" - } - }, - "node_modules/@trivago/prettier-plugin-sort-imports": { - "version": "5.2.2", - "resolved": "http://localhost:4873/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-5.2.2.tgz", - "integrity": "sha512-fYDQA9e6yTNmA13TLVSA+WMQRc5Bn/c0EUBditUHNfMMxN7M82c38b1kEggVE3pLpZ0FwkwJkUEKMiOi52JXFA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@babel/generator": "^7.26.5", - "@babel/parser": "^7.26.7", - "@babel/traverse": "^7.26.7", - "@babel/types": "^7.26.7", - "javascript-natural-sort": "^0.7.1", - "lodash": "^4.17.21" - }, - "engines": { - "node": ">18.12" - }, - "peerDependencies": { - "@vue/compiler-sfc": "3.x", - "prettier": "2.x - 3.x", - "prettier-plugin-svelte": "3.x", - "svelte": "4.x || 5.x" - }, - "peerDependenciesMeta": { - "@vue/compiler-sfc": { - "optional": true - }, - "prettier-plugin-svelte": { - "optional": true - }, - "svelte": { - "optional": true - } - } - }, - "node_modules/@types/esrecurse": { - "version": "4.3.1", - "resolved": "http://localhost:4873/@types/esrecurse/-/esrecurse-4.3.1.tgz", - "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "http://localhost:4873/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "http://localhost:4873/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/jssip": { - "version": "3.5.3", - "resolved": "http://localhost:4873/@types/jssip/-/jssip-3.5.3.tgz", - "integrity": "sha512-Rvw7hJPEJ12dlinAyzGpt3wxyPFMJemKRU4jTGRlRATZIdaIZUmpehsdU0oq9jIhx9bNNqIgzR+eR5Xe/U0/2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "jssip": "*" - } - }, - "node_modules/@types/node": { - "version": "24.12.0", - "resolved": "http://localhost:4873/@types/node/-/node-24.12.0.tgz", - "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "http://localhost:4873/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "http://localhost:4873/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz", - "integrity": "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.0", - "@typescript-eslint/type-utils": "8.57.0", - "@typescript-eslint/utils": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0", - "ignore": "^7.0.5", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.57.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "http://localhost:4873/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/parser/-/parser-8.57.0.tgz", - "integrity": "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.57.0", - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/project-service/-/project-service-8.57.0.tgz", - "integrity": "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.0", - "@typescript-eslint/types": "^8.57.0", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/scope-manager/-/scope-manager-8.57.0.tgz", - "integrity": "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.0.tgz", - "integrity": "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/type-utils/-/type-utils-8.57.0.tgz", - "integrity": "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0", - "@typescript-eslint/utils": "8.57.0", - "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/types/-/types-8.57.0.tgz", - "integrity": "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.0.tgz", - "integrity": "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.57.0", - "@typescript-eslint/tsconfig-utils": "8.57.0", - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/utils/-/utils-8.57.0.tgz", - "integrity": "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.0", - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.0", - "resolved": "http://localhost:4873/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.0.tgz", - "integrity": "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.57.0", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@untitledui/file-icons": { - "version": "0.0.8", - "resolved": "http://localhost:4873/@untitledui/file-icons/-/file-icons-0.0.8.tgz", - "integrity": "sha512-lxOp2rreDedjD82SOKoETmCDhm5TckCD3y49EEsuZqxnFES/3bfg9drNiilOCOAuEco7ImvdB4L//I//B93asw==", - "license": "MIT", - "peerDependencies": { - "react": ">= 18" - } - }, - "node_modules/@untitledui/icons": { - "version": "0.0.21", - "resolved": "http://localhost:4873/@untitledui/icons/-/icons-0.0.21.tgz", - "integrity": "sha512-+aVWUw/1se9PIJgwMD3qp5ohynGlVNu2oHSLzMwYpiSFp6bFcxv4kUGy685hQXB/hE4WAqnp7dIEVVMD0tfL7w==", - "license": "MIT", - "peerDependencies": { - "react": ">= 16" - } - }, - "node_modules/@vitejs/plugin-react-swc": { - "version": "4.3.0", - "resolved": "http://localhost:4873/@vitejs/plugin-react-swc/-/plugin-react-swc-4.3.0.tgz", - "integrity": "sha512-mOkXCII839dHyAt/gpoSlm28JIVDwhZ6tnG6wJxUy2bmOx7UaPjvOyIDf3SFv5s7Eo7HVaq6kRcu6YMEzt5Z7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rolldown/pluginutils": "1.0.0-rc.7", - "@swc/core": "^1.15.11" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "vite": "^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/acorn": { - "version": "8.16.0", - "resolved": "http://localhost:4873/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "http://localhost:4873/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.14.0", - "resolved": "http://localhost:4873/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", - "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "environment": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "http://localhost:4873/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.10", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.10.tgz", - "integrity": "sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "http://localhost:4873/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001781", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz", - "integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", - "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^8.0.0", - "string-width": "^8.2.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "http://localhost:4873/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "http://localhost:4873/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", - "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "1.1.1", - "resolved": "http://localhost:4873/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "http://localhost:4873/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "http://localhost:4873/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "http://localhost:4873/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "http://localhost:4873/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "http://localhost:4873/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "license": "MIT" - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "http://localhost:4873/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "http://localhost:4873/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/echarts": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/echarts/-/echarts-6.0.0.tgz", - "integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "2.3.0", - "zrender": "6.0.0" - } - }, - "node_modules/echarts-for-react": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.6.tgz", - "integrity": "sha512-4zqLgTGWS3JvkQDXjzkR1k1CHRdpd6by0988TWMJgnvDytegWLbeP/VNZmMa+0VJx2eD7Y632bi2JquXDgiGJg==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "size-sensor": "^1.0.1" - }, - "peerDependencies": { - "echarts": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", - "react": "^15.0.0 || >=16.0.0" - } - }, - "node_modules/echarts/node_modules/tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", - "license": "0BSD" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.321", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.321.tgz", - "integrity": "sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, - "node_modules/engine.io-client": { - "version": "6.6.4", - "resolved": "http://localhost:4873/engine.io-client/-/engine.io-client-6.6.4.tgz", - "integrity": "sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==", - "license": "MIT", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.4.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.18.3", - "xmlhttprequest-ssl": "~2.1.1" - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.3", - "resolved": "http://localhost:4873/engine.io-parser/-/engine.io-parser-5.2.3.tgz", - "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.20.0", - "resolved": "http://localhost:4873/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", - "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/environment": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", - "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esbuild": { - "version": "0.27.4", - "resolved": "http://localhost:4873/esbuild/-/esbuild-0.27.4.tgz", - "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.4", - "@esbuild/android-arm": "0.27.4", - "@esbuild/android-arm64": "0.27.4", - "@esbuild/android-x64": "0.27.4", - "@esbuild/darwin-arm64": "0.27.4", - "@esbuild/darwin-x64": "0.27.4", - "@esbuild/freebsd-arm64": "0.27.4", - "@esbuild/freebsd-x64": "0.27.4", - "@esbuild/linux-arm": "0.27.4", - "@esbuild/linux-arm64": "0.27.4", - "@esbuild/linux-ia32": "0.27.4", - "@esbuild/linux-loong64": "0.27.4", - "@esbuild/linux-mips64el": "0.27.4", - "@esbuild/linux-ppc64": "0.27.4", - "@esbuild/linux-riscv64": "0.27.4", - "@esbuild/linux-s390x": "0.27.4", - "@esbuild/linux-x64": "0.27.4", - "@esbuild/netbsd-arm64": "0.27.4", - "@esbuild/netbsd-x64": "0.27.4", - "@esbuild/openbsd-arm64": "0.27.4", - "@esbuild/openbsd-x64": "0.27.4", - "@esbuild/openharmony-arm64": "0.27.4", - "@esbuild/sunos-x64": "0.27.4", - "@esbuild/win32-arm64": "0.27.4", - "@esbuild/win32-ia32": "0.27.4", - "@esbuild/win32-x64": "0.27.4" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "http://localhost:4873/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.1.0.tgz", - "integrity": "sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.2", - "@eslint/config-array": "^0.23.3", - "@eslint/config-helpers": "^0.5.3", - "@eslint/core": "^1.1.1", - "@eslint/plugin-kit": "^0.6.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.14.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "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.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.2.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", - "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.24.4", - "@babel/parser": "^7.24.4", - "hermes-parser": "^0.25.1", - "zod": "^3.25.0 || ^4.0.0", - "zod-validation-error": "^3.5.0 || ^4.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-react-refresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.2.tgz", - "integrity": "sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "eslint": "^9 || ^10" - } - }, - "node_modules/eslint-scope": { - "version": "9.1.2", - "resolved": "http://localhost:4873/eslint-scope/-/eslint-scope-9.1.2.tgz", - "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@types/esrecurse": "^4.3.1", - "@types/estree": "^1.0.8", - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "http://localhost:4873/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "11.2.0", - "resolved": "http://localhost:4873/espree/-/espree-11.2.0.tgz", - "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.16.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^5.0.1" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.7.0", - "resolved": "http://localhost:4873/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "http://localhost:4873/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "http://localhost:4873/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "http://localhost:4873/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "http://localhost:4873/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "http://localhost:4873/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "http://localhost:4873/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "http://localhost:4873/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "http://localhost:4873/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "http://localhost:4873/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "http://localhost:4873/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "http://localhost:4873/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.4.1", - "resolved": "http://localhost:4873/flatted/-/flatted-3.4.1.tgz", - "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/framer-motion": { - "version": "12.36.0", - "resolved": "http://localhost:4873/framer-motion/-/framer-motion-12.36.0.tgz", - "integrity": "sha512-4PqYHAT7gev0ke0wos+PyrcFxI0HScjm3asgU8nSYa8YzJFuwgIvdj3/s3ZaxLq0bUSboIn19A2WS/MHwLCvfw==", - "license": "MIT", - "dependencies": { - "motion-dom": "^12.36.0", - "motion-utils": "^12.36.0", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "http://localhost:4873/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "http://localhost:4873/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "16.5.0", - "resolved": "http://localhost:4873/globals/-/globals-16.5.0.tgz", - "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "http://localhost:4873/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/hermes-estree": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", - "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", - "dev": true, - "license": "MIT" - }, - "node_modules/hermes-parser": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", - "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hermes-estree": "0.25.1" - } - }, - "node_modules/husky": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", - "dev": true, - "license": "MIT", - "bin": { - "husky": "bin.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "http://localhost:4873/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "http://localhost:4873/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/input-otp": { - "version": "1.4.2", - "resolved": "http://localhost:4873/input-otp/-/input-otp-1.4.2.tgz", - "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" - } - }, - "node_modules/intl-messageformat": { - "version": "10.7.18", - "resolved": "http://localhost:4873/intl-messageformat/-/intl-messageformat-10.7.18.tgz", - "integrity": "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==", - "license": "BSD-3-Clause", - "dependencies": { - "@formatjs/ecma402-abstract": "2.3.6", - "@formatjs/fast-memoize": "2.2.7", - "@formatjs/icu-messageformat-parser": "2.11.4", - "tslib": "^2.8.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "http://localhost:4873/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "http://localhost:4873/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "http://localhost:4873/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/javascript-natural-sort": { - "version": "0.7.1", - "resolved": "http://localhost:4873/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", - "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", - "dev": true, - "license": "MIT" - }, - "node_modules/jiti": { - "version": "2.6.1", - "resolved": "http://localhost:4873/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/jotai": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.18.1.tgz", - "integrity": "sha512-e0NOzK+yRFwHo7DOp0DS0Ycq74KMEAObDWFGmfEL28PD9nLqBTt3/Ug7jf9ca72x0gC9LQZG9zH+0ISICmy3iA==", - "license": "MIT", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0", - "@babel/template": ">=7.0.0", - "@types/react": ">=17.0.0", - "react": ">=17.0.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@babel/template": { - "optional": true - }, - "@types/react": { - "optional": true - }, - "react": { - "optional": true - } - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "http://localhost:4873/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "http://localhost:4873/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "http://localhost:4873/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "http://localhost:4873/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "http://localhost:4873/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jssip": { - "version": "3.13.6", - "resolved": "http://localhost:4873/jssip/-/jssip-3.13.6.tgz", - "integrity": "sha512-Bf1ndrSuqpO87/AG56WACR7kKcCvKOzaIQROu7JUMh0qFaGOV4NuR+wsnaXa7f3/d6xhwVczczFyt1ywJmTjPg==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.1", - "events": "^3.3.0", - "sdp-transform": "^2.14.1" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "http://localhost:4873/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "http://localhost:4873/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lightningcss": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss/-/lightningcss-1.31.1.tgz", - "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.31.1", - "lightningcss-darwin-arm64": "1.31.1", - "lightningcss-darwin-x64": "1.31.1", - "lightningcss-freebsd-x64": "1.31.1", - "lightningcss-linux-arm-gnueabihf": "1.31.1", - "lightningcss-linux-arm64-gnu": "1.31.1", - "lightningcss-linux-arm64-musl": "1.31.1", - "lightningcss-linux-x64-gnu": "1.31.1", - "lightningcss-linux-x64-musl": "1.31.1", - "lightningcss-win32-arm64-msvc": "1.31.1", - "lightningcss-win32-x64-msvc": "1.31.1" - } - }, - "node_modules/lightningcss-android-arm64": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", - "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", - "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", - "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", - "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", - "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", - "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", - "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", - "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", - "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", - "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.31.1", - "resolved": "http://localhost:4873/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", - "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lint-staged": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz", - "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^14.0.3", - "listr2": "^9.0.5", - "picomatch": "^4.0.3", - "string-argv": "^0.3.2", - "tinyexec": "^1.0.4", - "yaml": "^2.8.2" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "engines": { - "node": ">=20.17" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "node_modules/listr2": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", - "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^5.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.1.0", - "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "http://localhost:4873/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.23", - "resolved": "http://localhost:4873/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-update": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", - "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^7.0.0", - "cli-cursor": "^5.0.0", - "slice-ansi": "^7.1.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", - "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "http://localhost:4873/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "10.2.4", - "resolved": "http://localhost:4873/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/motion": { - "version": "12.36.0", - "resolved": "http://localhost:4873/motion/-/motion-12.36.0.tgz", - "integrity": "sha512-5BMQuktYUX8aEByKWYx5tR4X3G08H2OMgp46wTxZ4o7CDDstyy4A0fe9RLNMjZiwvntCWGDvs16sC87/emz4Yw==", - "license": "MIT", - "dependencies": { - "framer-motion": "^12.36.0", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/motion-dom": { - "version": "12.36.0", - "resolved": "http://localhost:4873/motion-dom/-/motion-dom-12.36.0.tgz", - "integrity": "sha512-Ep1pq8P88rGJ75om8lTCA13zqd7ywPGwCqwuWwin6BKc0hMLkVfcS6qKlRqEo2+t0DwoUcgGJfXwaiFn4AOcQA==", - "license": "MIT", - "dependencies": { - "motion-utils": "^12.36.0" - } - }, - "node_modules/motion-utils": { - "version": "12.36.0", - "resolved": "http://localhost:4873/motion-utils/-/motion-utils-12.36.0.tgz", - "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==", - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "http://localhost:4873/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "http://localhost:4873/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "http://localhost:4873/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.36", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", - "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", - "dev": true, - "license": "MIT" - }, - "node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "http://localhost:4873/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "http://localhost:4873/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "http://localhost:4873/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "http://localhost:4873/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "http://localhost:4873/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "http://localhost:4873/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "http://localhost:4873/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/postcss": { - "version": "8.5.8", - "resolved": "http://localhost:4873/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "http://localhost:4873/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "http://localhost:4873/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.8.1", - "resolved": "http://localhost:4873/prettier/-/prettier-3.8.1.tgz", - "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-plugin-tailwindcss": { - "version": "0.6.14", - "resolved": "http://localhost:4873/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.14.tgz", - "integrity": "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.21.3" - }, - "peerDependencies": { - "@ianvs/prettier-plugin-sort-imports": "*", - "@prettier/plugin-hermes": "*", - "@prettier/plugin-oxc": "*", - "@prettier/plugin-pug": "*", - "@shopify/prettier-plugin-liquid": "*", - "@trivago/prettier-plugin-sort-imports": "*", - "@zackad/prettier-plugin-twig": "*", - "prettier": "^3.0", - "prettier-plugin-astro": "*", - "prettier-plugin-css-order": "*", - "prettier-plugin-import-sort": "*", - "prettier-plugin-jsdoc": "*", - "prettier-plugin-marko": "*", - "prettier-plugin-multiline-arrays": "*", - "prettier-plugin-organize-attributes": "*", - "prettier-plugin-organize-imports": "*", - "prettier-plugin-sort-imports": "*", - "prettier-plugin-style-order": "*", - "prettier-plugin-svelte": "*" - }, - "peerDependenciesMeta": { - "@ianvs/prettier-plugin-sort-imports": { - "optional": true - }, - "@prettier/plugin-hermes": { - "optional": true - }, - "@prettier/plugin-oxc": { - "optional": true - }, - "@prettier/plugin-pug": { - "optional": true - }, - "@shopify/prettier-plugin-liquid": { - "optional": true - }, - "@trivago/prettier-plugin-sort-imports": { - "optional": true - }, - "@zackad/prettier-plugin-twig": { - "optional": true - }, - "prettier-plugin-astro": { - "optional": true - }, - "prettier-plugin-css-order": { - "optional": true - }, - "prettier-plugin-import-sort": { - "optional": true - }, - "prettier-plugin-jsdoc": { - "optional": true - }, - "prettier-plugin-marko": { - "optional": true - }, - "prettier-plugin-multiline-arrays": { - "optional": true - }, - "prettier-plugin-organize-attributes": { - "optional": true - }, - "prettier-plugin-organize-imports": { - "optional": true - }, - "prettier-plugin-sort-imports": { - "optional": true - }, - "prettier-plugin-style-order": { - "optional": true - }, - "prettier-plugin-svelte": { - "optional": true - } - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "http://localhost:4873/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/qr-code-styling": { - "version": "1.9.2", - "resolved": "http://localhost:4873/qr-code-styling/-/qr-code-styling-1.9.2.tgz", - "integrity": "sha512-RgJaZJ1/RrXJ6N0j7a+pdw3zMBmzZU4VN2dtAZf8ZggCfRB5stEQ3IoDNGaNhYY3nnZKYlYSLl5YkfWN5dPutg==", - "license": "MIT", - "dependencies": { - "qrcode-generator": "^1.4.4" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/qrcode-generator": { - "version": "1.5.2", - "resolved": "http://localhost:4873/qrcode-generator/-/qrcode-generator-1.5.2.tgz", - "integrity": "sha512-pItrW0Z9HnDBnFmgiNrY1uxRdri32Uh9EjNYLPVC2zZ3ZRIIEqBoDgm4DkvDwNNDHTK7FNkmr8zAa77BYc9xNw==", - "license": "MIT" - }, - "node_modules/react": { - "version": "19.2.4", - "resolved": "http://localhost:4873/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-aria": { - "version": "3.47.0", - "resolved": "http://localhost:4873/react-aria/-/react-aria-3.47.0.tgz", - "integrity": "sha512-nvahimIqdByl/PXk/xPkG30LPRzcin+/Uk0uFfwbbKRRFC9aa22a6BRULZLqVHwa9GaNyKe6CDUxO1Dde4v0kA==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/string": "^3.2.7", - "@react-aria/breadcrumbs": "^3.5.32", - "@react-aria/button": "^3.14.5", - "@react-aria/calendar": "^3.9.5", - "@react-aria/checkbox": "^3.16.5", - "@react-aria/color": "^3.1.5", - "@react-aria/combobox": "^3.15.0", - "@react-aria/datepicker": "^3.16.1", - "@react-aria/dialog": "^3.5.34", - "@react-aria/disclosure": "^3.1.3", - "@react-aria/dnd": "^3.11.6", - "@react-aria/focus": "^3.21.5", - "@react-aria/gridlist": "^3.14.4", - "@react-aria/i18n": "^3.12.16", - "@react-aria/interactions": "^3.27.1", - "@react-aria/label": "^3.7.25", - "@react-aria/landmark": "^3.0.10", - "@react-aria/link": "^3.8.9", - "@react-aria/listbox": "^3.15.3", - "@react-aria/menu": "^3.21.0", - "@react-aria/meter": "^3.4.30", - "@react-aria/numberfield": "^3.12.5", - "@react-aria/overlays": "^3.31.2", - "@react-aria/progress": "^3.4.30", - "@react-aria/radio": "^3.12.5", - "@react-aria/searchfield": "^3.8.12", - "@react-aria/select": "^3.17.3", - "@react-aria/selection": "^3.27.2", - "@react-aria/separator": "^3.4.16", - "@react-aria/slider": "^3.8.5", - "@react-aria/ssr": "^3.9.10", - "@react-aria/switch": "^3.7.11", - "@react-aria/table": "^3.17.11", - "@react-aria/tabs": "^3.11.1", - "@react-aria/tag": "^3.8.1", - "@react-aria/textfield": "^3.18.5", - "@react-aria/toast": "^3.0.11", - "@react-aria/tooltip": "^3.9.2", - "@react-aria/tree": "^3.1.7", - "@react-aria/utils": "^3.33.1", - "@react-aria/visually-hidden": "^3.8.31", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/react-aria-components": { - "version": "1.16.0", - "resolved": "http://localhost:4873/react-aria-components/-/react-aria-components-1.16.0.tgz", - "integrity": "sha512-MjHbTLpMFzzD2Tv5KbeXoZwPczuUWZcRavVvQQlNHRtXHH38D+sToMEYpNeir7Wh3K/XWtzeX3EujfJW6QNkrw==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.12.0", - "@internationalized/string": "^3.2.7", - "@react-aria/autocomplete": "3.0.0-rc.6", - "@react-aria/collections": "^3.0.3", - "@react-aria/dnd": "^3.11.6", - "@react-aria/focus": "^3.21.5", - "@react-aria/interactions": "^3.27.1", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/overlays": "^3.31.2", - "@react-aria/ssr": "^3.9.10", - "@react-aria/textfield": "^3.18.5", - "@react-aria/toolbar": "3.0.0-beta.24", - "@react-aria/utils": "^3.33.1", - "@react-aria/virtualizer": "^4.1.13", - "@react-stately/autocomplete": "3.0.0-beta.4", - "@react-stately/layout": "^4.6.0", - "@react-stately/selection": "^3.20.9", - "@react-stately/table": "^3.15.4", - "@react-stately/utils": "^3.11.0", - "@react-stately/virtualizer": "^4.4.6", - "@react-types/form": "^3.7.18", - "@react-types/grid": "^3.3.8", - "@react-types/shared": "^3.33.1", - "@react-types/table": "^3.13.6", - "@swc/helpers": "^0.5.0", - "client-only": "^0.0.1", - "react-aria": "^3.47.0", - "react-stately": "^3.45.0", - "use-sync-external-store": "^1.6.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/react-dom": { - "version": "19.2.4", - "resolved": "http://localhost:4873/react-dom/-/react-dom-19.2.4.tgz", - "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.27.0" - }, - "peerDependencies": { - "react": "^19.2.4" - } - }, - "node_modules/react-hotkeys-hook": { - "version": "5.2.4", - "resolved": "http://localhost:4873/react-hotkeys-hook/-/react-hotkeys-hook-5.2.4.tgz", - "integrity": "sha512-BgKg+A1+TawkYluh5Bo4cTmcgMN5L29uhJbDUQdHwPX+qgXRjIPYU5kIDHyxnAwCkCBiu9V5OpB2mpyeluVF2A==", - "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/react-router": { - "version": "7.13.1", - "resolved": "http://localhost:4873/react-router/-/react-router-7.13.1.tgz", - "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==", - "license": "MIT", - "dependencies": { - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - } - } - }, - "node_modules/react-stately": { - "version": "3.45.0", - "resolved": "http://localhost:4873/react-stately/-/react-stately-3.45.0.tgz", - "integrity": "sha512-G3bYr0BIiookpt4H05VeZUuVS/FslQAj2TeT8vDfCiL314Y+LtPXIPe/a3eamCA0wljy7z1EDYKV50Qbz7pcJg==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/calendar": "^3.9.3", - "@react-stately/checkbox": "^3.7.5", - "@react-stately/collections": "^3.12.10", - "@react-stately/color": "^3.9.5", - "@react-stately/combobox": "^3.13.0", - "@react-stately/data": "^3.15.2", - "@react-stately/datepicker": "^3.16.1", - "@react-stately/disclosure": "^3.0.11", - "@react-stately/dnd": "^3.7.4", - "@react-stately/form": "^3.2.4", - "@react-stately/list": "^3.13.4", - "@react-stately/menu": "^3.9.11", - "@react-stately/numberfield": "^3.11.0", - "@react-stately/overlays": "^3.6.23", - "@react-stately/radio": "^3.11.5", - "@react-stately/searchfield": "^3.5.19", - "@react-stately/select": "^3.9.2", - "@react-stately/selection": "^3.20.9", - "@react-stately/slider": "^3.7.5", - "@react-stately/table": "^3.15.4", - "@react-stately/tabs": "^3.8.9", - "@react-stately/toast": "^3.1.3", - "@react-stately/toggle": "^3.9.5", - "@react-stately/tooltip": "^3.5.11", - "@react-stately/tree": "^3.9.6", - "@react-types/shared": "^3.33.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/rollup": { - "version": "4.59.0", - "resolved": "http://localhost:4873/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "http://localhost:4873/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT" - }, - "node_modules/sdp-transform": { - "version": "2.15.0", - "resolved": "http://localhost:4873/sdp-transform/-/sdp-transform-2.15.0.tgz", - "integrity": "sha512-KrOH82c/W+GYQ0LHqtr3caRpM3ITglq3ljGUIb8LTki7ByacJZ9z+piSGiwZDsRyhQbYBOBJgr2k6X4BZXi3Kw==", - "license": "MIT", - "bin": { - "sdp-verify": "checker.js" - } - }, - "node_modules/semver": { - "version": "7.7.4", - "resolved": "http://localhost:4873/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.2", - "resolved": "http://localhost:4873/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", - "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "http://localhost:4873/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "http://localhost:4873/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/size-sensor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.3.tgz", - "integrity": "sha512-+k9mJ2/rQMiRmQUcjn+qznch260leIXY8r4FyYKKyRBO/s5UoeMAHGkCJyE1R/4wrIhTJONfyloY55SkE7ve3A==", - "license": "ISC" - }, - "node_modules/slice-ansi": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", - "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.3", - "is-fullwidth-code-point": "^5.1.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/socket.io-client": { - "version": "4.8.3", - "resolved": "http://localhost:4873/socket.io-client/-/socket.io-client-4.8.3.tgz", - "integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==", - "license": "MIT", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.4.1", - "engine.io-client": "~6.6.1", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.5", - "resolved": "http://localhost:4873/socket.io-parser/-/socket.io-parser-4.2.5.tgz", - "integrity": "sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==", - "license": "MIT", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.4.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/sonner": { - "version": "2.0.7", - "resolved": "http://localhost:4873/sonner/-/sonner-2.0.7.tgz", - "integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==", - "license": "MIT", - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", - "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "http://localhost:4873/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-width": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", - "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.5.0", - "strip-ansi": "^7.1.2" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/tailwind-merge": { - "version": "3.5.0", - "resolved": "http://localhost:4873/tailwind-merge/-/tailwind-merge-3.5.0.tgz", - "integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/dcastil" - } - }, - "node_modules/tailwindcss": { - "version": "4.2.1", - "resolved": "http://localhost:4873/tailwindcss/-/tailwindcss-4.2.1.tgz", - "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", - "license": "MIT" - }, - "node_modules/tailwindcss-animate": { - "version": "1.0.7", - "resolved": "http://localhost:4873/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", - "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", - "license": "MIT", - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders" - } - }, - "node_modules/tailwindcss-react-aria-components": { - "version": "2.0.1", - "resolved": "http://localhost:4873/tailwindcss-react-aria-components/-/tailwindcss-react-aria-components-2.0.1.tgz", - "integrity": "sha512-yTAfYv9BE/gKczS+b8UiFMqxnrEYKKNE6Y4vAWzGadkHGb4Yuawp0SHbZKkZJQgFvK0KjO3JpCq/0kzR5jJ9tw==", - "license": "Apache-2.0", - "peerDependencies": { - "tailwindcss": "^4.0.0" - } - }, - "node_modules/tapable": { - "version": "2.3.0", - "resolved": "http://localhost:4873/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/tinyexec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", - "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "http://localhost:4873/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/ts-api-utils": { - "version": "2.4.0", - "resolved": "http://localhost:4873/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "http://localhost:4873/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "http://localhost:4873/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "http://localhost:4873/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.57.0", - "resolved": "http://localhost:4873/typescript-eslint/-/typescript-eslint-8.57.0.tgz", - "integrity": "sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.57.0", - "@typescript-eslint/parser": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0", - "@typescript-eslint/utils": "8.57.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "http://localhost:4873/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, - "license": "MIT" - }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "http://localhost:4873/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/use-sync-external-store": { - "version": "1.6.0", - "resolved": "http://localhost:4873/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "http://localhost:4873/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/vite": { - "version": "7.3.1", - "resolved": "http://localhost:4873/vite/-/vite-7.3.1.tgz", - "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "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 - } - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "http://localhost:4873/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "http://localhost:4873/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ws": { - "version": "8.18.3", - "resolved": "http://localhost:4873/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "license": "MIT", - "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 - } - } - }, - "node_modules/xmlhttprequest-ssl": { - "version": "2.1.2", - "resolved": "http://localhost:4873/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", - "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/yaml": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", - "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "http://localhost:4873/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-validation-error": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", - "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "zod": "^3.25.0 || ^4.0.0" - } - }, - "node_modules/zrender": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz", - "integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==", - "license": "BSD-3-Clause", - "dependencies": { - "tslib": "2.3.0" - } - }, - "node_modules/zrender/node_modules/tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", - "license": "0BSD" } - } } diff --git a/package.json b/package.json index 70d4490..8d8988d 100644 --- a/package.json +++ b/package.json @@ -1,75 +1,60 @@ { - "name": "helix-engage", - "version": "0.1.0", - "type": "module", - "private": true, - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "preview": "vite preview", - "format": "prettier --write \"src/**/*.{ts,tsx}\"", - "lint": "eslint src", - "lint:fix": "eslint src --fix", - "fix:imports": "node scripts/fix-duplicate-imports.mjs", - "prepare": "husky" - }, - "dependencies": { - "@fortawesome/fontawesome-svg-core": "^7.2.0", - "@fortawesome/free-solid-svg-icons": "^7.2.0", - "@fortawesome/pro-duotone-svg-icons": "^7.2.0", - "@fortawesome/pro-light-svg-icons": "^7.2.0", - "@fortawesome/pro-regular-svg-icons": "^7.2.0", - "@fortawesome/pro-solid-svg-icons": "^7.2.0", - "@fortawesome/react-fontawesome": "^3.2.0", - "@tailwindcss/typography": "^0.5.19", - "@tailwindcss/vite": "^4.1.18", - "@untitledui/file-icons": "^0.0.8", - "@untitledui/icons": "^0.0.21", - "echarts": "^6.0.0", - "echarts-for-react": "^3.0.6", - "input-otp": "^1.4.2", - "jotai": "^2.18.1", - "jssip": "^3.13.6", - "motion": "^12.29.0", - "qr-code-styling": "^1.9.2", - "react": "^19.2.3", - "react-aria": "^3.46.0", - "react-aria-components": "^1.16.0", - "react-dom": "^19.2.3", - "react-hotkeys-hook": "^5.2.3", - "react-router": "^7.13.0", - "socket.io-client": "^4.8.3", - "sonner": "^2.0.7", - "tailwind-merge": "^3.5.0", - "tailwindcss": "^4.1.18", - "tailwindcss-animate": "^1.0.7", - "tailwindcss-react-aria-components": "^2.0.1" - }, - "lint-staged": { - "src/**/*.{ts,tsx}": [ - "eslint --fix", - "prettier --write" - ] - }, - "devDependencies": { - "@eslint/js": "^10.0.1", - "@tailwindcss/postcss": "^4.1.18", - "@trivago/prettier-plugin-sort-imports": "^5.2.2", - "@types/jssip": "^3.5.3", - "@types/node": "^24.10.9", - "@types/react": "^19.2.9", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react-swc": "^4.2.2", - "eslint": "^10.1.0", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.5.2", - "globals": "^16.5.0", - "husky": "^9.1.7", - "lint-staged": "^16.4.0", - "prettier": "^3.8.1", - "prettier-plugin-tailwindcss": "^0.6.14", - "typescript": "^5.9.3", - "typescript-eslint": "^8.53.1", - "vite": "^7.3.1" - } -} \ No newline at end of file + "name": "helix-engage", + "version": "0.1.0", + "type": "module", + "private": true, + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@ai-sdk/react": "^1.2.12", + "@fortawesome/fontawesome-svg-core": "^7.2.0", + "@fortawesome/free-solid-svg-icons": "^7.2.0", + "@fortawesome/pro-duotone-svg-icons": "^7.2.0", + "@fortawesome/pro-light-svg-icons": "^7.2.0", + "@fortawesome/pro-regular-svg-icons": "^7.2.0", + "@fortawesome/pro-solid-svg-icons": "^7.2.0", + "@fortawesome/react-fontawesome": "^3.2.0", + "@tailwindcss/typography": "^0.5.19", + "@tailwindcss/vite": "^4.1.18", + "@untitledui/file-icons": "^0.0.8", + "@untitledui/icons": "^0.0.21", + "echarts": "^6.0.0", + "echarts-for-react": "^3.0.6", + "input-otp": "^1.4.2", + "jotai": "^2.18.1", + "jssip": "^3.13.6", + "motion": "^12.29.0", + "pptxgenjs": "^4.0.1", + "qr-code-styling": "^1.9.2", + "react": "^19.2.3", + "react-aria": "^3.46.0", + "react-aria-components": "^1.16.0", + "react-dom": "^19.2.3", + "react-hotkeys-hook": "^5.2.3", + "react-router": "^7.13.0", + "socket.io-client": "^4.8.3", + "sonner": "^2.0.7", + "tailwind-merge": "^3.5.0", + "tailwindcss": "^4.1.18", + "tailwindcss-animate": "^1.0.7", + "tailwindcss-react-aria-components": "^2.0.1" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.18", + "@trivago/prettier-plugin-sort-imports": "^5.2.2", + "@types/jssip": "^3.5.3", + "@types/node": "^24.10.9", + "@types/react": "^19.2.9", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react-swc": "^4.2.2", + "globals": "^16.5.0", + "prettier": "^3.8.1", + "prettier-plugin-tailwindcss": "^0.6.14", + "typescript": "^5.9.3", + "typescript-eslint": "^8.53.1", + "vite": "^7.3.1" + } +} diff --git a/src/components/application/app-navigation/base-components/nav-account-card.tsx b/src/components/application/app-navigation/base-components/nav-account-card.tsx index 3b792b6..340ffc9 100644 --- a/src/components/application/app-navigation/base-components/nav-account-card.tsx +++ b/src/components/application/app-navigation/base-components/nav-account-card.tsx @@ -1,23 +1,18 @@ -import { type FC, type HTMLAttributes, useCallback, useEffect, useRef } from "react"; -import { faArrowRightFromBracket, faGear, faPhoneVolume, faSort, faUser } from "@fortawesome/pro-duotone-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import type { FC, HTMLAttributes } from "react"; +import { useCallback, useEffect, useRef } from "react"; import type { Placement } from "@react-types/overlays"; -import { useFocusManager } from "react-aria"; -import { - Button as AriaButton, - Dialog as AriaDialog, - type DialogProps as AriaDialogProps, - DialogTrigger as AriaDialogTrigger, - Popover as AriaPopover, -} from "react-aria-components"; -import { AvatarLabelGroup } from "@/components/base/avatar/avatar-label-group"; -import { useBreakpoint } from "@/hooks/use-breakpoint"; -import { cx } from "@/utils/cx"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faArrowRightFromBracket, faSort, faUser, faGear } from "@fortawesome/pro-duotone-svg-icons"; const IconUser: FC<{ className?: string }> = ({ className }) => ; const IconSettings: FC<{ className?: string }> = ({ className }) => ; const IconLogout: FC<{ className?: string }> = ({ className }) => ; -const IconForceReady: FC<{ className?: string }> = ({ className }) => ; +import { useFocusManager } from "react-aria"; +import type { DialogProps as AriaDialogProps } from "react-aria-components"; +import { Button as AriaButton, Dialog as AriaDialog, DialogTrigger as AriaDialogTrigger, Popover as AriaPopover } from "react-aria-components"; +import { AvatarLabelGroup } from "@/components/base/avatar/avatar-label-group"; +import { useBreakpoint } from "@/hooks/use-breakpoint"; +import { cx } from "@/utils/cx"; type NavAccountType = { /** Unique identifier for the nav item. */ @@ -32,18 +27,14 @@ type NavAccountType = { status: "online" | "offline"; }; + export const NavAccountMenu = ({ className, onSignOut, - onForceReady, + onViewProfile, + onAccountSettings, ...dialogProps -}: AriaDialogProps & { - className?: string; - accounts?: NavAccountType[]; - selectedAccountId?: string; - onSignOut?: () => void; - onForceReady?: () => void; -}) => { +}: AriaDialogProps & { className?: string; accounts?: NavAccountType[]; selectedAccountId?: string; onSignOut?: () => void; onViewProfile?: () => void; onAccountSettings?: () => void }) => { const focusManager = useFocusManager(); const dialogRef = useRef(null); @@ -84,29 +75,12 @@ export const NavAccountMenu = ({ <>
- - - { - close(); - onForceReady?.(); - }} - /> + { close(); onViewProfile?.(); }} /> + { close(); onAccountSettings?.(); }} />
-
- { - close(); - onSignOut?.(); - }} - /> + { close(); onSignOut?.(); }} />
)} @@ -150,13 +124,15 @@ export const NavAccountCard = ({ selectedAccountId, items = [], onSignOut, - onForceReady, + onViewProfile, + onAccountSettings, }: { popoverPlacement?: Placement; selectedAccountId?: string; items?: NavAccountType[]; onSignOut?: () => void; - onForceReady?: () => void; + onViewProfile?: () => void; + onAccountSettings?: () => void; }) => { const triggerRef = useRef(null); const isDesktop = useBreakpoint("lg"); @@ -169,7 +145,7 @@ export const NavAccountCard = ({ } return ( -
+
- +
diff --git a/src/components/application/app-navigation/base-components/nav-item.tsx b/src/components/application/app-navigation/base-components/nav-item.tsx index 526abd9..e39e37f 100644 --- a/src/components/application/app-navigation/base-components/nav-item.tsx +++ b/src/components/application/app-navigation/base-components/nav-item.tsx @@ -1,13 +1,13 @@ import type { FC, MouseEventHandler, ReactNode } from "react"; -import { faArrowUpRightFromSquare, faChevronDown } from "@fortawesome/pro-duotone-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faChevronDown, faArrowUpRightFromSquare } from "@fortawesome/pro-duotone-svg-icons"; import { Link as AriaLink } from "react-aria-components"; import { Badge } from "@/components/base/badges/badges"; import { cx, sortCx } from "@/utils/cx"; const styles = sortCx({ - root: "group relative flex w-full cursor-pointer items-center rounded-md bg-primary outline-focus-ring transition duration-100 ease-linear select-none hover:bg-primary_hover focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2", - rootSelected: "border-l-2 border-l-brand-600 bg-active text-brand-secondary hover:bg-secondary_hover", + root: "group relative flex w-full cursor-pointer items-center rounded-md outline-focus-ring transition duration-100 ease-linear select-none focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2", + rootSelected: "bg-sidebar-active hover:bg-sidebar-active border-l-2 border-l-brand-600", }); interface NavItemBaseProps { @@ -20,7 +20,6 @@ interface NavItemBaseProps { /** Type of the nav item. */ type: "link" | "collapsible" | "collapsible-child"; /** Icon component to display. */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any icon?: FC>; /** Badge to display. */ badge?: ReactNode; @@ -49,9 +48,9 @@ export const NavItemBase = ({ current, type, badge, href, icon: Icon, children, const labelElement = ( {children} @@ -63,7 +62,9 @@ export const NavItemBase = ({ current, type, badge, href, icon: Icon, children, if (type === "collapsible") { return ( - + {iconElement} {labelElement} @@ -81,7 +82,7 @@ export const NavItemBase = ({ current, type, badge, href, icon: Icon, children, href={href!} target={isExternal ? "_blank" : "_self"} rel="noopener noreferrer" - className={cx("py-2 pr-3 pl-10", styles.root, current && styles.rootSelected)} + className={cx("py-2 pr-3 pl-10 bg-sidebar", !current && "hover:bg-sidebar-hover", styles.root, current && styles.rootSelected)} onClick={onClick} aria-current={current ? "page" : undefined} > @@ -97,7 +98,7 @@ export const NavItemBase = ({ current, type, badge, href, icon: Icon, children, href={href!} target={isExternal ? "_blank" : "_self"} rel="noopener noreferrer" - className={cx("px-3 py-2", styles.root, current && styles.rootSelected)} + className={cx("px-3 py-2 bg-sidebar", !current && "hover:bg-sidebar-hover", styles.root, current && styles.rootSelected)} onClick={onClick} aria-current={current ? "page" : undefined} > diff --git a/src/components/application/date-picker/date-picker.tsx b/src/components/application/date-picker/date-picker.tsx index 3ebceb9..bb5cfcb 100644 --- a/src/components/application/date-picker/date-picker.tsx +++ b/src/components/application/date-picker/date-picker.tsx @@ -46,7 +46,8 @@ export const DatePicker = ({ value: valueProp, defaultValue, onChange, onApply, cx( "origin-(--trigger-anchor-point) will-change-transform", diff --git a/src/components/application/pagination/pagination.tsx b/src/components/application/pagination/pagination.tsx index f7822f3..561bf78 100644 --- a/src/components/application/pagination/pagination.tsx +++ b/src/components/application/pagination/pagination.tsx @@ -1,14 +1,14 @@ import type { FC } from "react"; -import { faArrowLeft, faArrowRight } from "@fortawesome/pro-duotone-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { ButtonGroup, ButtonGroupItem } from "@/components/base/button-group/button-group"; +import { faArrowLeft, faArrowRight } from "@fortawesome/pro-duotone-svg-icons"; import { Button } from "@/components/base/buttons/button"; -import { useBreakpoint } from "@/hooks/use-breakpoint"; -import { cx } from "@/utils/cx"; -import { Pagination, type PaginationRootProps } from "./pagination-base"; const ArrowLeft: FC<{ className?: string }> = ({ className }) => ; const ArrowRight: FC<{ className?: string }> = ({ className }) => ; +import { useBreakpoint } from "@/hooks/use-breakpoint"; +import { cx } from "@/utils/cx"; +import type { PaginationRootProps } from "./pagination-base"; +import { Pagination } from "./pagination-base"; interface PaginationProps extends Partial> { /** Whether the pagination buttons are rounded. */ @@ -22,7 +22,7 @@ const PaginationItem = ({ value, rounded, isCurrent }: { value: number; rounded? isCurrent={isCurrent} className={({ isSelected }) => cx( - "flex size-10 cursor-pointer items-center justify-center p-3 text-sm font-medium text-quaternary outline-focus-ring transition duration-100 ease-linear hover:bg-primary_hover hover:text-secondary focus-visible:z-10 focus-visible:bg-primary_hover focus-visible:outline-2 focus-visible:outline-offset-2", + "flex size-9 cursor-pointer items-center justify-center p-3 text-sm font-medium text-quaternary outline-focus-ring transition duration-100 ease-linear hover:bg-primary_hover hover:text-secondary focus-visible:z-10 focus-visible:bg-primary_hover focus-visible:outline-2 focus-visible:outline-offset-2", rounded ? "rounded-full" : "rounded-lg", isSelected && "bg-primary_hover text-secondary", ) @@ -33,43 +33,6 @@ const PaginationItem = ({ value, rounded, isCurrent }: { value: number; rounded? ); }; -interface MobilePaginationProps { - /** The current page. */ - page?: number; - /** The total number of pages. */ - total?: number; - /** The class name of the pagination component. */ - className?: string; - /** The function to call when the page changes. */ - onPageChange?: (page: number) => void; -} - -const MobilePagination = ({ page = 1, total = 10, className, onPageChange }: MobilePaginationProps) => { - return ( - - ); -}; - export const PaginationPageDefault = ({ rounded, page = 1, total = 10, className, ...props }: PaginationProps) => { const isDesktop = useBreakpoint("md"); @@ -83,7 +46,7 @@ export const PaginationPageDefault = ({ rounded, page = 1, total = 10, className
@@ -102,7 +65,7 @@ export const PaginationPageDefault = ({ rounded, page = 1, total = 10, className page.type === "page" ? ( ) : ( - + ), @@ -158,7 +121,7 @@ export const PaginationPageMinimalCenter = ({ rounded, page = 1, total = 10, cla page.type === "page" ? ( ) : ( - + ), @@ -209,7 +172,7 @@ export const PaginationCardDefault = ({ rounded, page = 1, total = 10, ...props page.type === "page" ? ( ) : ( - + ), @@ -234,99 +197,3 @@ export const PaginationCardDefault = ({ rounded, page = 1, total = 10, ...props ); }; -interface PaginationCardMinimalProps { - /** The current page. */ - page?: number; - /** The total number of pages. */ - total?: number; - /** The alignment of the pagination. */ - align?: "left" | "center" | "right"; - /** The class name of the pagination component. */ - className?: string; - /** The function to call when the page changes. */ - onPageChange?: (page: number) => void; -} - -export const PaginationCardMinimal = ({ page = 1, total = 10, align = "left", onPageChange, className }: PaginationCardMinimalProps) => { - return ( -
- - - -
- ); -}; - -interface PaginationButtonGroupProps extends Partial> { - /** The alignment of the pagination. */ - align?: "left" | "center" | "right"; -} - -export const PaginationButtonGroup = ({ align = "left", page = 1, total = 10, ...props }: PaginationButtonGroupProps) => { - const isDesktop = useBreakpoint("md"); - - return ( -
- - - {({ pages }) => ( - - - {isDesktop ? "Previous" : undefined} - - - {pages.map((page, index) => - page.type === "page" ? ( - - - {page.value} - - - ) : ( - - - … - - - ), - )} - - - {isDesktop ? "Next" : undefined} - - - )} - - -
- ); -}; diff --git a/src/components/application/slideout-menus/slideout-menu.tsx b/src/components/application/slideout-menus/slideout-menu.tsx index 2cd1d3d..0571d7c 100644 --- a/src/components/application/slideout-menus/slideout-menu.tsx +++ b/src/components/application/slideout-menus/slideout-menu.tsx @@ -19,7 +19,7 @@ export const ModalOverlay = (props: ModalOverlayProps) => { {...props} className={(state) => cx( - "fixed inset-0 flex min-h-dvh w-full items-center justify-end bg-overlay/70 pl-6 outline-hidden ease-linear md:pl-10", + "fixed inset-0 z-50 flex min-h-dvh w-full items-center justify-end bg-overlay/70 pl-6 outline-hidden ease-linear md:pl-10", state.isEntering && "duration-300 animate-in fade-in", state.isExiting && "duration-500 animate-out fade-out", typeof props.className === "function" ? props.className(state) : props.className, @@ -84,7 +84,7 @@ const Menu = ({ children, dialogClassName, ...props }: SlideoutMenuProps) => { Menu.displayName = "SlideoutMenu"; const Content = ({ role = "main", ...props }: ComponentPropsWithRef<"div">) => { - return
; + return
; }; Content.displayName = "SlideoutContent"; diff --git a/src/components/application/table/column-toggle.tsx b/src/components/application/table/column-toggle.tsx new file mode 100644 index 0000000..7001f5c --- /dev/null +++ b/src/components/application/table/column-toggle.tsx @@ -0,0 +1,93 @@ +import { useState, useRef, useEffect } from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faColumns3 } from '@fortawesome/pro-duotone-svg-icons'; +import { Button } from '@/components/base/buttons/button'; +import type { FC } from 'react'; + +const ColumnsIcon: FC<{ className?: string }> = ({ className }) => ( + +); + +export type ColumnDef = { + id: string; + label: string; + defaultVisible?: boolean; +}; + +interface ColumnToggleProps { + columns: ColumnDef[]; + visibleColumns: Set; + onToggle: (columnId: string) => void; +} + +export const ColumnToggle = ({ columns, visibleColumns, onToggle }: ColumnToggleProps) => { + const [open, setOpen] = useState(false); + const panelRef = useRef(null); + + useEffect(() => { + if (!open) return; + const handler = (e: MouseEvent) => { + if (panelRef.current && !panelRef.current.contains(e.target as Node)) { + setOpen(false); + } + }; + document.addEventListener('mousedown', handler); + return () => document.removeEventListener('mousedown', handler); + }, [open]); + + return ( +
+ + + {open && ( +
+
+ Show/Hide Columns +
+
+ {columns.map(col => ( + + ))} +
+
+ )} +
+ ); +}; + +export const useColumnVisibility = (columns: ColumnDef[]) => { + const [visibleColumns, setVisibleColumns] = useState>(() => { + return new Set(columns.filter(c => c.defaultVisible !== false).map(c => c.id)); + }); + + const toggle = (columnId: string) => { + setVisibleColumns(prev => { + const next = new Set(prev); + if (next.has(columnId)) { + next.delete(columnId); + } else { + next.add(columnId); + } + return next; + }); + }; + + return { visibleColumns, toggle }; +}; diff --git a/src/components/application/table/dynamic-table.tsx b/src/components/application/table/dynamic-table.tsx new file mode 100644 index 0000000..f95eb33 --- /dev/null +++ b/src/components/application/table/dynamic-table.tsx @@ -0,0 +1,63 @@ +import type { ReactNode } from 'react'; +import { TableBody as AriaTableBody } from 'react-aria-components'; +import { Table } from './table'; + +export type DynamicColumn = { + id: string; + label: string; + headerRenderer?: () => ReactNode; + width?: string; +}; + +export type DynamicRow = { + id: string; + [key: string]: any; +}; + +interface DynamicTableProps { + columns: DynamicColumn[]; + rows: T[]; + renderCell: (row: T, columnId: string) => ReactNode; + rowClassName?: (row: T) => string; + size?: 'sm' | 'md'; + maxRows?: number; + className?: string; +} + +export const DynamicTable = ({ + columns, + rows, + renderCell, + rowClassName, + size = 'sm', + maxRows, + className, +}: DynamicTableProps) => { + const displayRows = maxRows ? rows.slice(0, maxRows) : rows; + + return ( + + + {columns.map(col => ( + + {col.headerRenderer?.()} + + ))} + + + {(row) => ( + + {columns.map(col => ( + + {renderCell(row, col.id)} + + ))} + + )} + +
+ ); +}; diff --git a/src/components/application/table/table.tsx b/src/components/application/table/table.tsx index 6b811f1..1d1ceb9 100644 --- a/src/components/application/table/table.tsx +++ b/src/components/application/table/table.tsx @@ -1,31 +1,29 @@ -import { - type ComponentPropsWithRef, - type FC, - type HTMLAttributes, - type ReactNode, - type Ref, - type TdHTMLAttributes, - type ThHTMLAttributes, - createContext, - isValidElement, - useContext, -} from "react"; -import { faArrowDown, faCircleQuestion, faCopy, faPenToSquare, faSort, faTrash } from "@fortawesome/pro-duotone-svg-icons"; +import type { ComponentPropsWithRef, FC, HTMLAttributes, ReactNode, Ref, TdHTMLAttributes, ThHTMLAttributes } from "react"; +import { createContext, isValidElement, useContext } from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faArrowDown, faSort, faCopy, faPenToSquare, faCircleQuestion, faTrash } from "@fortawesome/pro-duotone-svg-icons"; + +const Edit01: FC<{ className?: string }> = ({ className }) => ; +const Copy01: FC<{ className?: string }> = ({ className }) => ; +const Trash01: FC<{ className?: string }> = ({ className }) => ; +import type { + CellProps as AriaCellProps, + ColumnProps as AriaColumnProps, + RowProps as AriaRowProps, + TableHeaderProps as AriaTableHeaderProps, + TableProps as AriaTableProps, +} from "react-aria-components"; import { Cell as AriaCell, - type CellProps as AriaCellProps, Collection as AriaCollection, Column as AriaColumn, - type ColumnProps as AriaColumnProps, + ColumnResizer as AriaColumnResizer, Group as AriaGroup, + ResizableTableContainer as AriaResizableTableContainer, Row as AriaRow, - type RowProps as AriaRowProps, Table as AriaTable, TableBody as AriaTableBody, TableHeader as AriaTableHeader, - type TableHeaderProps as AriaTableHeaderProps, - type TableProps as AriaTableProps, useTableOptions, } from "react-aria-components"; import { Badge } from "@/components/base/badges/badges"; @@ -34,10 +32,6 @@ import { Dropdown } from "@/components/base/dropdown/dropdown"; import { Tooltip, TooltipTrigger } from "@/components/base/tooltip/tooltip"; import { cx } from "@/utils/cx"; -const Edit01: FC<{ className?: string }> = ({ className }) => ; -const Copy01: FC<{ className?: string }> = ({ className }) => ; -const Trash01: FC<{ className?: string }> = ({ className }) => ; - export const TableRowActionsDropdown = () => ( @@ -63,7 +57,7 @@ const TableContext = createContext<{ size: "sm" | "md" }>({ size: "md" }); const TableCardRoot = ({ children, className, size = "md", ...props }: HTMLAttributes & { size?: "sm" | "md" }) => { return ( -
+
{children}
@@ -89,7 +83,7 @@ const TableCardHeader = ({ title, badge, description, contentTrailing, className return (
{ return ( -
- cx("w-full overflow-x-hidden", typeof className === "function" ? className(state) : className)} {...props} /> -
+ + cx("w-full", typeof className === "function" ? className(state) : className)} {...props} /> +
); }; TableRoot.displayName = "Table"; interface TableHeaderProps - extends AriaTableHeaderProps, Omit, "children" | "className" | "slot" | "style"> { + extends AriaTableHeaderProps, + Omit, "children" | "className" | "slot" | "style"> { bordered?: boolean; } @@ -145,7 +140,7 @@ const TableHeader = ({ columns, children, bordered = true, cla {...props} className={(state) => cx( - "relative bg-secondary", + "relative bg-secondary sticky top-0 z-10", size === "sm" ? "h-9" : "h-11", // Row border—using an "after" pseudo-element to avoid the border taking up space. @@ -175,9 +170,10 @@ TableHeader.displayName = "TableHeader"; interface TableHeadProps extends AriaColumnProps, Omit, "children" | "className" | "style" | "id"> { label?: string; tooltip?: string; + resizable?: boolean; } -const TableHead = ({ className, tooltip, label, children, ...props }: TableHeadProps) => { +const TableHead = ({ className, tooltip, label, children, resizable = true, ...props }: TableHeadProps) => { const { selectionBehavior } = useTableOptions(); return ( @@ -193,8 +189,8 @@ const TableHead = ({ className, tooltip, label, children, ...props }: TableHeadP } > {(state) => ( - -
+ +
{label && {label}} {typeof children === "function" ? children(state) : children}
@@ -209,13 +205,16 @@ const TableHead = ({ className, tooltip, label, children, ...props }: TableHeadP {state.allowsSorting && (state.sortDirection ? ( - + ) : ( ))} + + {resizable && ( + + )}
)} @@ -224,7 +223,8 @@ const TableHead = ({ className, tooltip, label, children, ...props }: TableHeadP TableHead.displayName = "TableHead"; interface TableRowProps - extends AriaRowProps, Omit, "children" | "className" | "onClick" | "slot" | "style" | "id"> { + extends AriaRowProps, + Omit, "children" | "className" | "onClick" | "slot" | "style" | "id"> { highlightSelectedRow?: boolean; } diff --git a/src/components/base/avatar/avatar-label-group.tsx b/src/components/base/avatar/avatar-label-group.tsx index f9792e7..954a862 100644 --- a/src/components/base/avatar/avatar-label-group.tsx +++ b/src/components/base/avatar/avatar-label-group.tsx @@ -20,8 +20,8 @@ export const AvatarLabelGroup = ({ title, subtitle, className, ...props }: Avata
-

{title}

-

{subtitle}

+

{title}

+

{subtitle}

); diff --git a/src/components/base/avatar/base-components/avatar-count.tsx b/src/components/base/avatar/base-components/avatar-count.tsx new file mode 100644 index 0000000..b4fa214 --- /dev/null +++ b/src/components/base/avatar/base-components/avatar-count.tsx @@ -0,0 +1,14 @@ +import { cx } from "@/utils/cx"; + +interface AvatarCountProps { + count: number; + className?: string; +} + +export const AvatarCount = ({ count, className }: AvatarCountProps) => ( +
+
+ {count} +
+
+); diff --git a/src/components/base/pin-input/pin-input.tsx b/src/components/base/pin-input/pin-input.tsx index ff076cf..8008a62 100644 --- a/src/components/base/pin-input/pin-input.tsx +++ b/src/components/base/pin-input/pin-input.tsx @@ -65,7 +65,7 @@ const Group = ({ inputClassName, containerClassName, width, maxLength = 4, ...pr aria-label="Enter your pin" aria-labelledby={"pin-input-label-" + id} aria-describedby={"pin-input-description-" + id} - containerClassName={cx("flex flex-row gap-3", size === "sm" && "gap-2", heights[size], containerClassName)} + containerClassName={cx("flex flex-row items-center gap-3", size === "sm" && "gap-2", heights[size], containerClassName)} className={cx("w-full! disabled:cursor-not-allowed", inputClassName)} /> ); @@ -115,8 +115,8 @@ const FakeCaret = ({ size = "md" }: { size?: "sm" | "md" | "lg" }) => { const Separator = (props: ComponentPropsWithRef<"p">) => { return ( -
- - +
+ –
); }; diff --git a/src/components/base/select/select-shared.tsx b/src/components/base/select/select-shared.tsx new file mode 100644 index 0000000..0163b47 --- /dev/null +++ b/src/components/base/select/select-shared.tsx @@ -0,0 +1,49 @@ +import type { FC, ReactNode } from "react"; +import { createContext } from "react"; + +export type SelectItemType = { + /** Unique identifier for the item. */ + id: string | number; + /** The primary display text. */ + label?: string; + /** Avatar image URL. */ + avatarUrl?: string; + /** Whether the item is disabled. */ + isDisabled?: boolean; + /** Secondary text displayed alongside the label. */ + supportingText?: string; + /** Leading icon component or element. */ + icon?: FC | ReactNode; +}; + +export interface CommonProps { + /** Helper text displayed below the input. */ + hint?: string; + /** Field label displayed above the input. */ + label?: string; + /** Tooltip text for the help icon next to the label. */ + tooltip?: string; + /** + * The size of the component. + * @default "md" + */ + size?: "sm" | "md" | "lg"; + /** Placeholder text when no value is selected. */ + placeholder?: string; + /** Whether to hide the required indicator from the label. */ + hideRequiredIndicator?: boolean; +} + +export const sizes = { + sm: { + root: "py-2 pl-3 pr-2.5 gap-2 *:data-icon:size-4 *:data-icon:stroke-[2.25px]", + withIcon: "", + text: "text-sm", + textContainer: "gap-x-1.5", + shortcut: "pr-2.5", + }, + md: { root: "py-2 px-3 gap-2 *:data-icon:size-5", withIcon: "", text: "text-md", textContainer: "gap-x-1.5", shortcut: "pr-2.5" }, + lg: { root: "py-2.5 px-3.5 gap-2 *:data-icon:size-5", withIcon: "", text: "text-md", textContainer: "gap-x-1.5", shortcut: "pr-3" }, +}; + +export const SelectContext = createContext<{ size: "sm" | "md" | "lg" }>({ size: "md" }); diff --git a/src/components/call-desk/active-call-card.tsx b/src/components/call-desk/active-call-card.tsx index 62fe189..640aaed 100644 --- a/src/components/call-desk/active-call-card.tsx +++ b/src/components/call-desk/active-call-card.tsx @@ -1,34 +1,26 @@ -import { useRef, useState } from "react"; +import { useState, useRef, useEffect } from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { - faCalendarPlus, - faClipboardQuestion, - faMicrophone, - faMicrophoneSlash, - faPause, - faPhone, - faPhoneArrowRight, - faPhoneHangup, - faPlay, - faRecordVinyl, -} from "@fortawesome/pro-duotone-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { useSetAtom } from "jotai"; -import { Badge } from "@/components/base/badges/badges"; -import { Button } from "@/components/base/buttons/button"; -import { apiClient } from "@/lib/api-client"; -import { formatPhone } from "@/lib/format"; -import { notify } from "@/lib/toast"; -import { useSip } from "@/providers/sip-provider"; -import { setOutboundPending } from "@/state/sip-manager"; -import { sipCallStateAtom, sipCallUcidAtom, sipCallerNumberAtom } from "@/state/sip-state"; -import type { CallDisposition, Lead } from "@/types/entities"; -import { cx } from "@/utils/cx"; -import { AppointmentForm } from "./appointment-form"; -import { DispositionForm } from "./disposition-form"; -import { EnquiryForm } from "./enquiry-form"; -import { TransferDialog } from "./transfer-dialog"; - -type PostCallStage = "disposition" | "appointment" | "follow-up" | "done"; + faPhone, faPhoneHangup, faMicrophone, faMicrophoneSlash, + faPause, faPlay, faCalendarPlus, + faPhoneArrowRight, faRecordVinyl, faClipboardQuestion, +} from '@fortawesome/pro-duotone-svg-icons'; +import { Button } from '@/components/base/buttons/button'; +import { Badge } from '@/components/base/badges/badges'; +import { useSetAtom } from 'jotai'; +import { sipCallStateAtom, sipCallerNumberAtom, sipCallUcidAtom } from '@/state/sip-state'; +import { setOutboundPending } from '@/state/sip-manager'; +import { useSip } from '@/providers/sip-provider'; +import { DispositionModal } from './disposition-modal'; +import { AppointmentForm } from './appointment-form'; +import { TransferDialog } from './transfer-dialog'; +import { EnquiryForm } from './enquiry-form'; +import { formatPhone } from '@/lib/format'; +import { apiClient } from '@/lib/api-client'; +import { useAuth } from '@/providers/auth-provider'; +import { cx } from '@/utils/cx'; +import { notify } from '@/lib/toast'; +import type { Lead, CallDisposition } from '@/types/entities'; interface ActiveCallCardProps { lead: Lead | null; @@ -40,96 +32,111 @@ interface ActiveCallCardProps { const formatDuration = (seconds: number): string => { const m = Math.floor(seconds / 60); const s = seconds % 60; - return `${m}:${s.toString().padStart(2, "0")}`; + return `${m}:${s.toString().padStart(2, '0')}`; }; export const ActiveCallCard = ({ lead, callerPhone, missedCallId, onCallComplete }: ActiveCallCardProps) => { + const { user } = useAuth(); const { callState, callDuration, callUcid, isMuted, isOnHold, answer, reject, hangup, toggleMute, toggleHold } = useSip(); const setCallState = useSetAtom(sipCallStateAtom); const setCallerNumber = useSetAtom(sipCallerNumberAtom); const setCallUcid = useSetAtom(sipCallUcidAtom); - const [postCallStage, setPostCallStage] = useState(null); const [appointmentOpen, setAppointmentOpen] = useState(false); - const [appointmentBookedDuringCall, setAppointmentBookedDuringCall] = useState(false); const [transferOpen, setTransferOpen] = useState(false); const [recordingPaused, setRecordingPaused] = useState(false); const [enquiryOpen, setEnquiryOpen] = useState(false); - // Capture direction at mount — survives through disposition stage - const callDirectionRef = useRef(callState === "ringing-out" ? "OUTBOUND" : "INBOUND"); - // Track if the call was ever answered (reached 'active' state) - const wasAnsweredRef = useRef(callState === "active"); + const [dispositionOpen, setDispositionOpen] = useState(false); + const [callerDisconnected, setCallerDisconnected] = useState(false); + const [suggestedDisposition, setSuggestedDisposition] = useState(null); - const firstName = lead?.contactName?.firstName ?? ""; - const lastName = lead?.contactName?.lastName ?? ""; + const callDirectionRef = useRef(callState === 'ringing-out' ? 'OUTBOUND' : 'INBOUND'); + const wasAnsweredRef = useRef(callState === 'active'); + + useEffect(() => { + console.log(`[ACTIVE-CALL-CARD] Mounted: state=${callState} direction=${callDirectionRef.current} ucid=${callUcid ?? 'none'} lead=${lead?.id ?? 'none'} phone=${callerPhone}`); + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + // Detect caller disconnect: call was active and ended without agent pressing End + useEffect(() => { + if (wasAnsweredRef.current && !dispositionOpen && (callState === 'ended' || callState === 'failed')) { + setCallerDisconnected(true); + setDispositionOpen(true); + } + }, [callState, dispositionOpen]); + + const firstName = lead?.contactName?.firstName ?? ''; + const lastName = lead?.contactName?.lastName ?? ''; const fullName = `${firstName} ${lastName}`.trim(); const phone = lead?.contactPhone?.[0]; - const phoneDisplay = phone ? formatPhone(phone) : callerPhone || "Unknown"; + const phoneDisplay = phone ? formatPhone(phone) : callerPhone || 'Unknown'; const handleDisposition = async (disposition: CallDisposition, notes: string) => { - // Submit disposition to sidecar — handles Ozonetel ACW release - if (callUcid) { - apiClient - .post("/api/ozonetel/dispose", { - ucid: callUcid, - disposition, - callerPhone, - direction: callDirectionRef.current, - durationSec: callDuration, - leadId: lead?.id ?? null, - notes, - missedCallId: missedCallId ?? undefined, - }) - .catch((err) => console.warn("Disposition failed:", err)); + // Hangup if still connected + if (callState === 'active' || callState === 'ringing-out' || callState === 'ringing-in') { + hangup(); } - // Side effects per disposition type - if (disposition === "FOLLOW_UP_SCHEDULED") { + // Submit disposition to sidecar + if (callUcid) { + const disposePayload = { + ucid: callUcid, + disposition, + callerPhone, + direction: callDirectionRef.current, + durationSec: callDuration, + leadId: lead?.id ?? null, + notes, + missedCallId: missedCallId ?? undefined, + }; + console.log('[DISPOSE] Sending disposition:', JSON.stringify(disposePayload)); + apiClient.post('/api/ozonetel/dispose', disposePayload) + .then((res) => console.log('[DISPOSE] Response:', JSON.stringify(res))) + .catch((err) => console.error('[DISPOSE] Failed:', err)); + } else { + console.warn('[DISPOSE] No callUcid — skipping disposition'); + } + + // Side effects + if (disposition === 'FOLLOW_UP_SCHEDULED') { try { - await apiClient.graphql( - `mutation($data: FollowUpCreateInput!) { createFollowUp(data: $data) { id } }`, - { - data: { - name: `Follow-up — ${fullName || phoneDisplay}`, - typeCustom: "CALLBACK", - status: "PENDING", - assignedAgent: null, - priority: "NORMAL", - // eslint-disable-next-line react-hooks/purity - scheduledAt: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), - }, + await apiClient.graphql(`mutation($data: FollowUpCreateInput!) { createFollowUp(data: $data) { id } }`, { + data: { + name: `Follow-up — ${fullName || phoneDisplay}`, + typeCustom: 'CALLBACK', + status: 'PENDING', + assignedAgent: null, + priority: 'NORMAL', + scheduledAt: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), }, - { silent: true }, - ); - notify.success("Follow-up Created", "Callback scheduled for tomorrow"); + }, { silent: true }); + notify.success('Follow-up Created', 'Callback scheduled for tomorrow'); } catch { - notify.info("Follow-up", "Could not auto-create follow-up"); + notify.info('Follow-up', 'Could not auto-create follow-up'); } } - // Disposition is the last step — return to worklist immediately - notify.success("Call Logged", `Disposition: ${disposition.replace(/_/g, " ").toLowerCase()}`); + notify.success('Call Logged', `Disposition: ${disposition.replace(/_/g, ' ').toLowerCase()}`); handleReset(); }; const handleAppointmentSaved = () => { setAppointmentOpen(false); - notify.success("Appointment Booked", "Payment link will be sent to the patient"); - if (callState === "active") { - setAppointmentBookedDuringCall(true); - } + setSuggestedDisposition('APPOINTMENT_BOOKED'); + notify.success('Appointment Booked', 'Payment link will be sent to the patient'); }; const handleReset = () => { - setPostCallStage(null); - setCallState("idle"); + setDispositionOpen(false); + setCallerDisconnected(false); + setCallState('idle'); setCallerNumber(null); setCallUcid(null); setOutboundPending(false); onCallComplete?.(); }; - // Outbound ringing — agent initiated the call - if (callState === "ringing-out") { + // Outbound ringing + if (callState === 'ringing-out') { return (
@@ -140,21 +147,14 @@ export const ActiveCallCard = ({ lead, callerPhone, missedCallId, onCallComplete
-

Calling...

+

Calling...

{fullName || phoneDisplay}

{fullName &&

{phoneDisplay}

}
-
@@ -162,41 +162,37 @@ export const ActiveCallCard = ({ lead, callerPhone, missedCallId, onCallComplete } // Inbound ringing - if (callState === "ringing-in") { + if (callState === 'ringing-in') { return (
- +
-

Incoming Call

+

Incoming Call

{fullName || phoneDisplay}

{fullName &&

{phoneDisplay}

}
- - + +
); } - // Skip disposition for unanswered calls (ringing-in → ended without ever reaching active) - if (!wasAnsweredRef.current && postCallStage === null && (callState === "ended" || callState === "failed")) { + // Unanswered call (ringing → ended without ever reaching active) + if (!wasAnsweredRef.current && (callState === 'ended' || callState === 'failed')) { return (
- +

Missed Call

-

{phoneDisplay} — not answered

+

{phoneDisplay} — not answered

@@ -204,192 +200,145 @@ export const ActiveCallCard = ({ lead, callerPhone, missedCallId, onCallComplete ); } - // Post-call flow takes priority over active state (handles race between hangup + SIP ended event) - if (postCallStage !== null || callState === "ended" || callState === "failed") { - // Disposition form + enquiry access + // Active call + if (callState === 'active' || dispositionOpen) { + wasAnsweredRef.current = true; return ( <> -
-
-
-
- -
-
-

Call Ended — {fullName || phoneDisplay}

-

{formatDuration(callDuration)} · Log this call

+
+ {/* Pinned: caller info + controls */} +
+
+
+
+ +
+
+

{fullName || phoneDisplay}

+ {fullName &&

{phoneDisplay}

} +
+ {formatDuration(callDuration)}
- + + {/* Call controls */} +
+ + + + +
+ + + + + + +
+
- + + {/* Scrollable: expanded forms + transfer */} + {(appointmentOpen || enquiryOpen || transferOpen) && ( +
+ {transferOpen && callUcid && ( + setTransferOpen(false)} + onTransferred={() => { + setTransferOpen(false); + setSuggestedDisposition('FOLLOW_UP_SCHEDULED'); + setDispositionOpen(true); + }} + /> + )} + + + { + setEnquiryOpen(false); + setSuggestedDisposition('INFO_PROVIDED'); + notify.success('Enquiry Logged'); + }} + /> +
+ )}
- { - setEnquiryOpen(false); - notify.success("Enquiry Logged"); + + {/* Disposition Modal — the ONLY path to end a call */} + { + // Agent wants to continue the call — close modal, call stays active + if (!callerDisconnected) { + setDispositionOpen(false); + } else { + // Caller already disconnected — dismiss goes to worklist + handleReset(); + } }} /> ); } - // Active call - if (callState === "active") { - wasAnsweredRef.current = true; - return ( -
-
-
-
- -
-
-

{fullName || phoneDisplay}

- {fullName &&

{phoneDisplay}

} -
-
- - {formatDuration(callDuration)} - -
-
- {/* Icon-only toggles */} - - - - -
- - {/* Text+Icon primary actions */} - - - - -
- - {/* Transfer dialog */} - {transferOpen && callUcid && ( - setTransferOpen(false)} - onTransferred={() => { - setTransferOpen(false); - hangup(); - setPostCallStage("disposition"); - }} - /> - )} - - {/* Appointment form accessible during call */} - - - {/* Enquiry form */} - { - setEnquiryOpen(false); - notify.success("Enquiry Logged"); - }} - /> -
- ); - } - return null; }; diff --git a/src/components/call-desk/agent-status-toggle.tsx b/src/components/call-desk/agent-status-toggle.tsx index 159b5c3..d7c6b4e 100644 --- a/src/components/call-desk/agent-status-toggle.tsx +++ b/src/components/call-desk/agent-status-toggle.tsx @@ -1,97 +1,118 @@ -import { useState } from "react"; -import { faChevronDown, faCircle } from "@fortawesome/pro-duotone-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { apiClient } from "@/lib/api-client"; -import { notify } from "@/lib/toast"; -import { cx } from "@/utils/cx"; +import { useState } from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faCircle, faChevronDown } from '@fortawesome/pro-duotone-svg-icons'; +import { useAgentState } from '@/hooks/use-agent-state'; +import type { OzonetelState } from '@/hooks/use-agent-state'; +import { apiClient } from '@/lib/api-client'; +import { notify } from '@/lib/toast'; +import { cx } from '@/utils/cx'; -type AgentStatus = "ready" | "break" | "training" | "offline"; +type ToggleableStatus = 'ready' | 'break' | 'training'; -const statusConfig: Record = { - ready: { label: "Ready", color: "text-success-primary", dotColor: "text-fg-success-primary" }, - break: { label: "Break", color: "text-warning-primary", dotColor: "text-fg-warning-primary" }, - training: { label: "Training", color: "text-brand-secondary", dotColor: "text-fg-brand-primary" }, - offline: { label: "Offline", color: "text-tertiary", dotColor: "text-fg-quaternary" }, +const displayConfig: Record = { + ready: { label: 'Ready', color: 'text-success-primary', dotColor: 'text-fg-success-primary' }, + break: { label: 'Break', color: 'text-warning-primary', dotColor: 'text-fg-warning-primary' }, + training: { label: 'Training', color: 'text-brand-secondary', dotColor: 'text-fg-brand-primary' }, + calling: { label: 'Calling', color: 'text-brand-secondary', dotColor: 'text-fg-brand-primary' }, + 'in-call': { label: 'In Call', color: 'text-brand-secondary', dotColor: 'text-fg-brand-primary' }, + acw: { label: 'Wrapping up', color: 'text-warning-primary', dotColor: 'text-fg-warning-primary' }, + offline: { label: 'Offline', color: 'text-tertiary', dotColor: 'text-fg-quaternary' }, }; +const toggleOptions: Array<{ key: ToggleableStatus; label: string; color: string; dotColor: string }> = [ + { key: 'ready', label: 'Ready', color: 'text-success-primary', dotColor: 'text-fg-success-primary' }, + { key: 'break', label: 'Break', color: 'text-warning-primary', dotColor: 'text-fg-warning-primary' }, + { key: 'training', label: 'Training', color: 'text-brand-secondary', dotColor: 'text-fg-brand-primary' }, +]; + type AgentStatusToggleProps = { isRegistered: boolean; connectionStatus: string; }; export const AgentStatusToggle = ({ isRegistered, connectionStatus }: AgentStatusToggleProps) => { - const [status, setStatus] = useState(isRegistered ? "ready" : "offline"); + const agentConfig = localStorage.getItem('helix_agent_config'); + const agentId = agentConfig ? JSON.parse(agentConfig).ozonetelAgentId : null; + const ozonetelState = useAgentState(agentId); + const [menuOpen, setMenuOpen] = useState(false); const [changing, setChanging] = useState(false); - const handleChange = async (newStatus: AgentStatus) => { + const handleChange = async (newStatus: ToggleableStatus) => { setMenuOpen(false); - if (newStatus === status) return; + if (newStatus === ozonetelState) return; setChanging(true); try { - if (newStatus === "ready") { - await apiClient.post("/api/ozonetel/agent-state", { state: "Ready" }); - } else if (newStatus === "offline") { - await apiClient.post("/api/ozonetel/agent-logout", { - agentId: "global", - password: "Test123$", - }); + if (newStatus === 'ready') { + console.log('[AGENT-STATE] Changing to Ready'); + const res = await apiClient.post('/api/ozonetel/agent-state', { state: 'Ready' }); + console.log('[AGENT-STATE] Ready response:', JSON.stringify(res)); } else { - const pauseReason = newStatus === "break" ? "Break" : "Training"; - await apiClient.post("/api/ozonetel/agent-state", { state: "Pause", pauseReason }); + const pauseReason = newStatus === 'break' ? 'Break' : 'Training'; + console.log(`[AGENT-STATE] Changing to Pause: ${pauseReason}`); + const res = await apiClient.post('/api/ozonetel/agent-state', { state: 'Pause', pauseReason }); + console.log('[AGENT-STATE] Pause response:', JSON.stringify(res)); } - setStatus(newStatus); - } catch { - notify.error("Status Change Failed", "Could not update agent status"); + // Don't setStatus — SSE will push the real state + } catch (err) { + console.error('[AGENT-STATE] Status change failed:', err); + notify.error('Status Change Failed', 'Could not update agent status'); } finally { setChanging(false); } }; - // If SIP isn't connected, show connection status + // If SIP isn't connected, show connection status with user-friendly message if (!isRegistered) { + const statusMessages: Record = { + disconnected: 'Telephony unavailable', + connecting: 'Connecting to telephony...', + connected: 'Registering...', + error: 'Telephony error — check VPN', + }; return (
- - {connectionStatus} + + {statusMessages[connectionStatus] ?? connectionStatus}
); } - const current = statusConfig[status]; + const current = displayConfig[ozonetelState] ?? displayConfig.offline; + const canToggle = ozonetelState === 'ready' || ozonetelState === 'break' || ozonetelState === 'training' || ozonetelState === 'offline'; return (
{menuOpen && ( <>
setMenuOpen(false)} /> -
- {(Object.entries(statusConfig) as [AgentStatus, typeof current][]).map(([key, cfg]) => ( +
+ {toggleOptions.map((opt) => ( ))}
diff --git a/src/components/call-desk/ai-chat-panel.tsx b/src/components/call-desk/ai-chat-panel.tsx index ad360d6..6d73315 100644 --- a/src/components/call-desk/ai-chat-panel.tsx +++ b/src/components/call-desk/ai-chat-panel.tsx @@ -1,16 +1,14 @@ -import { type ReactNode, useCallback, useEffect, useRef, useState } from "react"; -import { faPaperPlaneTop, faRobot, faSparkles, faUserHeadset } from "@fortawesome/pro-duotone-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { apiClient } from "@/lib/api-client"; +import type { ReactNode } from 'react'; +import { useRef, useEffect } from 'react'; +import { useThemeTokens } from '@/providers/theme-token-provider'; +import { useChat } from '@ai-sdk/react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faPaperPlaneTop, faSparkles, faUserHeadset } from '@fortawesome/pro-duotone-svg-icons'; -type ChatMessage = { - id: string; - role: "user" | "assistant"; - content: string; - timestamp: Date; -}; +const API_URL = import.meta.env.VITE_API_URL ?? 'http://localhost:4100'; type CallerContext = { + type?: string; callerPhone?: string; leadId?: string; leadName?: string; @@ -18,154 +16,83 @@ type CallerContext = { interface AiChatPanelProps { callerContext?: CallerContext; - role?: "cc-agent" | "admin" | "executive"; + onChatStart?: () => void; } -const QUICK_ASK_AGENT = [ - { label: "Doctor availability", template: "What are the visiting hours for all doctors?" }, - { label: "Clinic timings", template: "What are the clinic locations and timings?" }, - { label: "Patient history", template: "Can you summarize this patient's history?" }, - { label: "Treatment packages", template: "What treatment packages are available?" }, -]; - -const QUICK_ASK_MANAGER = [ - { label: "Agent performance", template: "Which agents have the highest appointment conversion rates this week?" }, - { label: "Missed call risks", template: "Which missed calls have been waiting the longest without a callback?" }, - { label: "Pending leads", template: "How many leads are still pending first contact?" }, - { label: "Weekly summary", template: "Give me a summary of this week's team performance — total calls, conversions, missed calls." }, -]; - -export const AiChatPanel = ({ callerContext, role = "cc-agent" }: AiChatPanelProps) => { - const quickButtons = role === "admin" ? QUICK_ASK_MANAGER : QUICK_ASK_AGENT; - const [messages, setMessages] = useState([]); - const [input, setInput] = useState(""); - const [isLoading, setIsLoading] = useState(false); +export const AiChatPanel = ({ callerContext, onChatStart }: AiChatPanelProps) => { + const { tokens } = useThemeTokens(); + const quickActions = tokens.ai.quickActions; const messagesEndRef = useRef(null); - const inputRef = useRef(null); + const chatStartedRef = useRef(false); - const scrollToBottom = useCallback(() => { - // Scroll within the messages container only — don't scroll the parent panel + const token = localStorage.getItem('helix_access_token') ?? ''; + + const { messages, input, handleSubmit, handleInputChange, isLoading, append } = useChat({ + api: `${API_URL}/api/ai/stream`, + streamProtocol: 'text', + headers: { + 'Authorization': `Bearer ${token}`, + }, + body: { + context: callerContext, + }, + }); + + useEffect(() => { const el = messagesEndRef.current; if (el?.parentElement) { el.parentElement.scrollTop = el.parentElement.scrollHeight; } - }, []); + if (messages.length > 0 && !chatStartedRef.current) { + chatStartedRef.current = true; + onChatStart?.(); + } + }, [messages, onChatStart]); - useEffect(() => { - scrollToBottom(); - }, [messages, scrollToBottom]); - - const sendMessage = useCallback( - async (text?: string) => { - const messageText = (text ?? input).trim(); - if (messageText.length === 0 || isLoading) return; - - const userMessage: ChatMessage = { - id: `user-${Date.now()}`, - role: "user", - content: messageText, - timestamp: new Date(), - }; - - setMessages((prev) => [...prev, userMessage]); - setInput(""); - setIsLoading(true); - - try { - const data = await apiClient.post<{ reply: string; sources?: string[] }>("/api/ai/chat", { - message: messageText, - context: callerContext, - }); - - const assistantMessage: ChatMessage = { - id: `assistant-${Date.now()}`, - role: "assistant", - content: data.reply ?? "Sorry, I could not process that request.", - timestamp: new Date(), - }; - - setMessages((prev) => [...prev, assistantMessage]); - } catch { - const errorMessage: ChatMessage = { - id: `error-${Date.now()}`, - role: "assistant", - content: "Sorry, I'm having trouble connecting to the AI service. Please try again.", - timestamp: new Date(), - }; - setMessages((prev) => [...prev, errorMessage]); - } finally { - setIsLoading(false); - inputRef.current?.focus(); - } - }, - [input, isLoading, callerContext], - ); - - const handleKeyDown = useCallback( - (e: React.KeyboardEvent) => { - if (e.key === "Enter" && !e.shiftKey) { - e.preventDefault(); - sendMessage(); - } - }, - [sendMessage], - ); - - const handleQuickAsk = useCallback( - (template: string) => { - sendMessage(template); - }, - [sendMessage], - ); + const handleQuickAction = (prompt: string) => { + append({ role: 'user', content: prompt }); + }; return ( -
- {/* Caller context banner */} - {callerContext?.leadName && ( -
- - Talking to: {callerContext.leadName} - {callerContext.callerPhone ? ` (${callerContext.callerPhone})` : ""} - -
- )} - - {/* Quick ask buttons */} - {messages.length === 0 && ( -
- {quickButtons.map((btn) => ( - - ))} -
- )} - - {/* Messages area */} -
+
+
{messages.length === 0 && ( -
- -

Ask me about doctors, clinics, packages, or patient info.

+
+ +

+ Ask me about doctors, clinics, packages, or patient info. +

+
+ {quickActions.map((action) => ( + + ))} +
)} {messages.map((msg) => ( -
+
- {msg.role === "assistant" && ( + {msg.role === 'assistant' && (
- AI + AI
)} @@ -188,34 +115,31 @@ export const AiChatPanel = ({ callerContext, role = "cc-agent" }: AiChatPanelPro
- {/* Input area */} -
+
setInput(e.target.value)} - onKeyDown={handleKeyDown} + onChange={handleInputChange} placeholder="Ask the AI assistant..." disabled={isLoading} - className="flex-1 bg-transparent px-2 py-2 text-xs text-primary outline-none placeholder:text-placeholder disabled:cursor-not-allowed" + className="flex-1 bg-transparent px-2 py-2 text-xs text-primary placeholder:text-placeholder outline-none disabled:cursor-not-allowed" />
-
+
); }; +// Tool result cards will be added in Phase 2 when SDK versions are aligned for data stream protocol -// Parse simple markdown-like text into React nodes (safe, no innerHTML) const parseLine = (text: string): ReactNode[] => { const parts: ReactNode[] = []; const boldPattern = /\*\*(.+?)\*\*/g; @@ -223,42 +147,31 @@ const parseLine = (text: string): ReactNode[] => { let match: RegExpExecArray | null; while ((match = boldPattern.exec(text)) !== null) { - if (match.index > lastIndex) { - parts.push(text.slice(lastIndex, match.index)); - } - parts.push( - - {match[1]} - , - ); + if (match.index > lastIndex) parts.push(text.slice(lastIndex, match.index)); + parts.push({match[1]}); lastIndex = boldPattern.lastIndex; } - if (lastIndex < text.length) { - parts.push(text.slice(lastIndex)); - } - + if (lastIndex < text.length) parts.push(text.slice(lastIndex)); return parts.length > 0 ? parts : [text]; }; const MessageContent = ({ content }: { content: string }) => { - const lines = content.split("\n"); + if (!content) return null; + const lines = content.split('\n'); return (
{lines.map((line, i) => { if (line.trim().length === 0) return
; - - // Bullet points - if (line.trimStart().startsWith("- ")) { + if (line.trimStart().startsWith('- ')) { return (
- {parseLine(line.replace(/^\s*-\s*/, ""))} + {parseLine(line.replace(/^\s*-\s*/, ''))}
); } - return

{parseLine(line)}

; })}
diff --git a/src/components/call-desk/appointment-form.tsx b/src/components/call-desk/appointment-form.tsx index 79bc7d1..ec8f8e3 100644 --- a/src/components/call-desk/appointment-form.tsx +++ b/src/components/call-desk/appointment-form.tsx @@ -1,17 +1,13 @@ -import { useEffect, useState } from "react"; -import { faCalendarPlus, faXmark } from "@fortawesome/pro-duotone-svg-icons"; -import { Button } from "@/components/base/buttons/button"; -import { Checkbox } from "@/components/base/checkbox/checkbox"; -import { Input } from "@/components/base/input/input"; -import { Select } from "@/components/base/select/select"; -import { TextArea } from "@/components/base/textarea/textarea"; -import { apiClient } from "@/lib/api-client"; -import { faIcon } from "@/lib/icon-wrapper"; -import { notify } from "@/lib/toast"; -import { cx } from "@/utils/cx"; - -const CalendarPlus02 = faIcon(faCalendarPlus); -const XClose = faIcon(faXmark); +import { useState, useEffect } from 'react'; +import { Input } from '@/components/base/input/input'; +import { Select } from '@/components/base/select/select'; +import { TextArea } from '@/components/base/textarea/textarea'; +import { Button } from '@/components/base/buttons/button'; +import { DatePicker } from '@/components/application/date-picker/date-picker'; +import { parseDate } from '@internationalized/date'; +import { apiClient } from '@/lib/api-client'; +import { cx } from '@/utils/cx'; +import { notify } from '@/lib/toast'; type ExistingAppointment = { id: string; @@ -37,62 +33,71 @@ type AppointmentFormProps = { type DoctorRecord = { id: string; name: string; department: string; clinic: string }; const clinicItems = [ - { id: "koramangala", label: "Global Hospital - Koramangala" }, - { id: "whitefield", label: "Global Hospital - Whitefield" }, - { id: "indiranagar", label: "Global Hospital - Indiranagar" }, + { id: 'koramangala', label: 'Global Hospital - Koramangala' }, + { id: 'whitefield', label: 'Global Hospital - Whitefield' }, + { id: 'indiranagar', label: 'Global Hospital - Indiranagar' }, ]; const genderItems = [ - { id: "male", label: "Male" }, - { id: "female", label: "Female" }, - { id: "other", label: "Other" }, + { id: 'male', label: 'Male' }, + { id: 'female', label: 'Female' }, + { id: 'other', label: 'Other' }, ]; const timeSlotItems = [ - { id: "09:00", label: "9:00 AM" }, - { id: "09:30", label: "9:30 AM" }, - { id: "10:00", label: "10:00 AM" }, - { id: "10:30", label: "10:30 AM" }, - { id: "11:00", label: "11:00 AM" }, - { id: "11:30", label: "11:30 AM" }, - { id: "14:00", label: "2:00 PM" }, - { id: "14:30", label: "2:30 PM" }, - { id: "15:00", label: "3:00 PM" }, - { id: "15:30", label: "3:30 PM" }, - { id: "16:00", label: "4:00 PM" }, + { id: '09:00', label: '9:00 AM' }, + { id: '09:30', label: '9:30 AM' }, + { id: '10:00', label: '10:00 AM' }, + { id: '10:30', label: '10:30 AM' }, + { id: '11:00', label: '11:00 AM' }, + { id: '11:30', label: '11:30 AM' }, + { id: '14:00', label: '2:00 PM' }, + { id: '14:30', label: '2:30 PM' }, + { id: '15:00', label: '3:00 PM' }, + { id: '15:30', label: '3:30 PM' }, + { id: '16:00', label: '4:00 PM' }, ]; -const formatDeptLabel = (dept: string) => dept.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()); +const formatDeptLabel = (dept: string) => + dept.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()); -export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, leadId, patientId, onSaved, existingAppointment }: AppointmentFormProps) => { +export const AppointmentForm = ({ + isOpen, + onOpenChange, + callerNumber, + leadName, + leadId, + patientId, + onSaved, + existingAppointment, +}: AppointmentFormProps) => { const isEditMode = !!existingAppointment; // Doctor data from platform const [doctors, setDoctors] = useState([]); // Form state — initialized from existing appointment in edit mode - const [patientName, setPatientName] = useState(leadName ?? ""); - const [patientPhone, setPatientPhone] = useState(callerNumber ?? ""); - const [age, setAge] = useState(""); + const [patientName, setPatientName] = useState(leadName ?? ''); + const [patientPhone, setPatientPhone] = useState(callerNumber ?? ''); + const [age, setAge] = useState(''); const [gender, setGender] = useState(null); const [clinic, setClinic] = useState(null); const [department, setDepartment] = useState(existingAppointment?.department ?? null); const [doctor, setDoctor] = useState(existingAppointment?.doctorId ?? null); const [date, setDate] = useState(() => { - if (existingAppointment?.scheduledAt) return existingAppointment.scheduledAt.split("T")[0]; - return ""; + if (existingAppointment?.scheduledAt) return existingAppointment.scheduledAt.split('T')[0]; + return new Date().toISOString().split('T')[0]; }); const [timeSlot, setTimeSlot] = useState(() => { if (existingAppointment?.scheduledAt) { const dt = new Date(existingAppointment.scheduledAt); - return `${dt.getHours().toString().padStart(2, "0")}:${dt.getMinutes().toString().padStart(2, "0")}`; + return `${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}`; } return null; }); - const [chiefComplaint, setChiefComplaint] = useState(existingAppointment?.reasonForVisit ?? ""); - const [isReturning, setIsReturning] = useState(false); - const [source, setSource] = useState("Inbound Call"); - const [agentNotes, setAgentNotes] = useState(""); + const [chiefComplaint, setChiefComplaint] = useState(existingAppointment?.reasonForVisit ?? ''); + const [source, setSource] = useState('Inbound Call'); + const [agentNotes, setAgentNotes] = useState(''); // Availability state const [bookedSlots, setBookedSlots] = useState([]); @@ -104,23 +109,21 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, // Fetch doctors on mount useEffect(() => { if (!isOpen) return; - - apiClient - .graphql<{ doctors: { edges: Array<{ node: unknown }> } }>( - `{ doctors(first: 50) { edges { node { + apiClient.graphql<{ doctors: { edges: Array<{ node: any }> } }>( + `{ doctors(first: 50) { edges { node { id name fullName { firstName lastName } department clinic { id name clinicName } } } } }`, - ) - .then((data) => { - const docs = data.doctors.edges.map((e) => ({ - id: e.node.id, - name: e.node.fullName ? `Dr. ${e.node.fullName.firstName} ${e.node.fullName.lastName}`.trim() : e.node.name, - department: e.node.department ?? "", - clinic: e.node.clinic?.clinicName ?? e.node.clinic?.name ?? "", - })); - setDoctors(docs); - }) - .catch(() => {}); + ).then(data => { + const docs = data.doctors.edges.map(e => ({ + id: e.node.id, + name: e.node.fullName + ? `Dr. ${e.node.fullName.firstName} ${e.node.fullName.lastName}`.trim() + : e.node.name, + department: e.node.department ?? '', + clinic: e.node.clinic?.clinicName ?? e.node.clinic?.name ?? '', + })); + setDoctors(docs); + }).catch(() => {}); }, [isOpen]); // Fetch booked slots when doctor + date selected @@ -131,35 +134,31 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, } setLoadingSlots(true); - - apiClient - .graphql<{ appointments: { edges: Array<{ node: unknown }> } }>( - `{ appointments(filter: { + apiClient.graphql<{ appointments: { edges: Array<{ node: any }> } }>( + `{ appointments(filter: { doctorId: { eq: "${doctor}" }, scheduledAt: { gte: "${date}T00:00:00", lte: "${date}T23:59:59" } }) { edges { node { id scheduledAt durationMin status } } } }`, - ) - .then((data) => { - // Filter out cancelled/completed appointments client-side - const activeAppointments = data.appointments.edges.filter((e) => { - const status = e.node.status; - return status !== "CANCELLED" && status !== "COMPLETED" && status !== "NO_SHOW"; - }); - const slots = activeAppointments.map((e) => { - const dt = new Date(e.node.scheduledAt); - return `${dt.getHours().toString().padStart(2, "0")}:${dt.getMinutes().toString().padStart(2, "0")}`; - }); - // In edit mode, don't block the current appointment's slot - if (isEditMode && existingAppointment) { - const currentDt = new Date(existingAppointment.scheduledAt); - const currentSlot = `${currentDt.getHours().toString().padStart(2, "0")}:${currentDt.getMinutes().toString().padStart(2, "0")}`; - setBookedSlots(slots.filter((s) => s !== currentSlot)); - } else { - setBookedSlots(slots); - } - }) - .catch(() => setBookedSlots([])) - .finally(() => setLoadingSlots(false)); + ).then(data => { + // Filter out cancelled/completed appointments client-side + const activeAppointments = data.appointments.edges.filter(e => { + const status = e.node.status; + return status !== 'CANCELLED' && status !== 'COMPLETED' && status !== 'NO_SHOW'; + }); + const slots = activeAppointments.map(e => { + const dt = new Date(e.node.scheduledAt); + return `${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}`; + }); + // In edit mode, don't block the current appointment's slot + if (isEditMode && existingAppointment) { + const currentDt = new Date(existingAppointment.scheduledAt); + const currentSlot = `${currentDt.getHours().toString().padStart(2, '0')}:${currentDt.getMinutes().toString().padStart(2, '0')}`; + setBookedSlots(slots.filter(s => s !== currentSlot)); + } else { + setBookedSlots(slots); + } + }).catch(() => setBookedSlots([])) + .finally(() => setLoadingSlots(false)); }, [doctor, date, isEditMode, existingAppointment]); // Reset doctor when department changes @@ -174,12 +173,15 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, }, [doctor, date]); // Derive department and doctor lists from fetched data - const departmentItems = [...new Set(doctors.map((d) => d.department).filter(Boolean))].map((dept) => ({ id: dept, label: formatDeptLabel(dept) })); + const departmentItems = [...new Set(doctors.map(d => d.department).filter(Boolean))] + .map(dept => ({ id: dept, label: formatDeptLabel(dept) })); - const filteredDoctors = department ? doctors.filter((d) => d.department === department) : doctors; - const doctorSelectItems = filteredDoctors.map((d) => ({ id: d.id, label: d.name })); + const filteredDoctors = department + ? doctors.filter(d => d.department === department) + : doctors; + const doctorSelectItems = filteredDoctors.map(d => ({ id: d.id, label: d.name })); - const timeSlotSelectItems = timeSlotItems.map((slot) => ({ + const timeSlotSelectItems = timeSlotItems.map(slot => ({ ...slot, isDisabled: bookedSlots.includes(slot.id), label: bookedSlots.includes(slot.id) ? `${slot.label} (Booked)` : slot.label, @@ -187,7 +189,13 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, const handleSave = async () => { if (!date || !timeSlot || !doctor || !department) { - setError("Please fill in the required fields: date, time, doctor, and department."); + setError('Please fill in the required fields: date, time, doctor, and department.'); + return; + } + + const today = new Date().toISOString().split('T')[0]; + if (!isEditMode && date < today) { + setError('Appointment date cannot be in the past.'); return; } @@ -196,7 +204,7 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, try { const scheduledAt = new Date(`${date}T${timeSlot}:00`).toISOString(); - const selectedDoctor = doctors.find((d) => d.id === doctor); + const selectedDoctor = doctors.find(d => d.id === doctor); if (isEditMode && existingAppointment) { // Update existing appointment @@ -208,14 +216,14 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, id: existingAppointment.id, data: { scheduledAt, - doctorName: selectedDoctor?.name ?? "", - department: selectedDoctor?.department ?? "", + doctorName: selectedDoctor?.name ?? '', + department: selectedDoctor?.department ?? '', doctorId: doctor, reasonForVisit: chiefComplaint || null, }, }, ); - notify.success("Appointment Updated"); + notify.success('Appointment Updated'); } else { // Create appointment await apiClient.graphql( @@ -226,10 +234,10 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, data: { scheduledAt, durationMin: 30, - appointmentType: "CONSULTATION", - status: "SCHEDULED", - doctorName: selectedDoctor?.name ?? "", - department: selectedDoctor?.department ?? "", + appointmentType: 'CONSULTATION', + status: 'SCHEDULED', + doctorName: selectedDoctor?.name ?? '', + department: selectedDoctor?.department ?? '', doctorId: doctor, reasonForVisit: chiefComplaint || null, ...(patientId ? { patientId } : {}), @@ -237,29 +245,48 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, }, ); - // Update lead status if we have a matched lead + // Update patient name if we have a name and a linked patient + if (patientId && patientName.trim()) { + await apiClient.graphql( + `mutation UpdatePatient($id: UUID!, $data: PatientUpdateInput!) { + updatePatient(id: $id, data: $data) { id } + }`, + { + id: patientId, + data: { + fullName: { firstName: patientName.split(' ')[0], lastName: patientName.split(' ').slice(1).join(' ') || '' }, + }, + }, + ).catch((err: unknown) => console.warn('Failed to update patient name:', err)); + } + + // Update lead status + name if we have a matched lead if (leadId) { - await apiClient - .graphql( - `mutation UpdateLead($id: UUID!, $data: LeadUpdateInput!) { + await apiClient.graphql( + `mutation UpdateLead($id: UUID!, $data: LeadUpdateInput!) { updateLead(id: $id, data: $data) { id } }`, - { - id: leadId, - data: { - leadStatus: "APPOINTMENT_SET", - lastContactedAt: new Date().toISOString(), - }, + { + id: leadId, + data: { + leadStatus: 'APPOINTMENT_SET', + lastContactedAt: new Date().toISOString(), + ...(patientName.trim() ? { contactName: { firstName: patientName.split(' ')[0], lastName: patientName.split(' ').slice(1).join(' ') || '' } } : {}), }, - ) - .catch((err: unknown) => console.warn("Failed to update lead:", err)); + }, + ).catch((err: unknown) => console.warn('Failed to update lead:', err)); + } + + // Invalidate caller cache so next lookup gets the real name + if (callerNumber) { + apiClient.post('/api/caller/invalidate', { phone: callerNumber }, { silent: true }).catch(() => {}); } } onSaved?.(); } catch (err) { - console.error("Failed to save appointment:", err); - setError(err instanceof Error ? err.message : "Failed to save appointment. Please try again."); + console.error('Failed to save appointment:', err); + setError(err instanceof Error ? err.message : 'Failed to save appointment. Please try again.'); } finally { setIsSaving(false); } @@ -275,13 +302,13 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, }`, { id: existingAppointment.id, - data: { status: "CANCELLED" }, + data: { status: 'CANCELLED' }, }, ); - notify.success("Appointment Cancelled"); + notify.success('Appointment Cancelled'); onSaved?.(); } catch (err) { - setError(err instanceof Error ? err.message : "Failed to cancel appointment"); + setError(err instanceof Error ? err.message : 'Failed to cancel appointment'); } finally { setIsSaving(false); } @@ -290,40 +317,40 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, if (!isOpen) return null; return ( -
- {/* Header with close button */} -
-
-
- -
-
-

{isEditMode ? "Edit Appointment" : "Book Appointment"}

-

{isEditMode ? "Modify or cancel this appointment" : "Schedule a new patient visit"}

-
-
- -
- - {/* Form fields */} +
+ {/* Form fields — scrollable */} +
{/* Patient Info — only for new appointments */} {!isEditMode && ( <>
- Patient Information + + Patient Information +
- +
- - + +
)} - +
+ - + +
- +
+ Date * + setDate(val ? val.toString() : '')} + granularity="day" + isDisabled={!doctor} + /> +
{/* Time slot grid */} {doctor && date && (
- {loadingSlots ? "Checking availability..." : "Available Slots"} + + {loadingSlots ? 'Checking availability...' : 'Available Slots'} +
- {timeSlotSelectItems.map((slot) => { + {timeSlotSelectItems.map(slot => { const isBooked = slot.isDisabled; const isSelected = timeSlot === slot.id; return ( @@ -398,15 +437,15 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName, disabled={isBooked} onClick={() => setTimeSlot(slot.id)} className={cx( - "rounded-lg px-1 py-2 text-xs font-medium transition duration-100 ease-linear", + 'rounded-lg py-2 px-1 text-xs font-medium transition duration-100 ease-linear', isBooked - ? "cursor-not-allowed bg-disabled text-disabled line-through" + ? 'cursor-not-allowed bg-disabled text-disabled line-through' : isSelected - ? "bg-brand-solid text-white ring-2 ring-brand" - : "cursor-pointer bg-secondary text-secondary hover:bg-secondary_hover hover:text-secondary_hover", + ? 'bg-brand-solid text-white ring-2 ring-brand' + : 'cursor-pointer bg-secondary text-secondary hover:bg-secondary_hover hover:text-secondary_hover', )} > - {timeSlotItems.find((t) => t.id === slot.id)?.label ?? slot.id} + {timeSlotItems.find(t => t.id === slot.id)?.label ?? slot.id} ); })} @@ -414,28 +453,50 @@ export const AppointmentForm = ({ isOpen, onOpenChange, callerNumber, leadName,
)} - {!doctor || !date ?

Select a doctor and date to see available time slots

: null} + {!doctor || !date ? ( +

Select a doctor and date to see available time slots

+ ) : null} -