commit 4b8af23f5f92a7da74605ef6bf6389b8081c002a Author: sandhiya-hepl Date: Tue Jul 14 15:20:26 2026 +0530 first commit diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ecaba9c --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +PORT=3001 +JWT_SECRET=change-this-to-a-random-64-char-string +ADMIN_USERNAME=admin +ADMIN_PASSWORD=admin123 +CORS_ORIGIN=http://localhost:5173 +UPLOAD_DIR=./server/uploads +DATA_DIR=./server/data diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5013185 --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# Environment variables +.env +.env*.local + +# CMS data & uploads +server/data/ +server/uploads/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..a36934d --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. diff --git a/admin.html b/admin.html new file mode 100644 index 0000000..fd32410 --- /dev/null +++ b/admin.html @@ -0,0 +1,12 @@ + + + + + + CITPL Admin + + +
+ + + diff --git a/api/send.js b/api/send.js new file mode 100644 index 0000000..7ddd167 --- /dev/null +++ b/api/send.js @@ -0,0 +1,61 @@ +export default async function handler(req, res) { + // Set CORS headers for local development if needed + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + + if (req.method === 'OPTIONS') { + return res.status(200).end(); + } + + if (req.method !== 'POST') { + return res.status(405).json({ error: 'Method Not Allowed' }); + } + + const { type, name, email, phone, mobile, designation, dateTime, interests, resumeName } = req.body; + + const serviceId = process.env.EMAILJS_SERVICE_ID || 'vishva_cavintest'; + const publicKey = process.env.EMAILJS_PUBLIC_KEY || 'YOUR_EMAILJS_PUBLIC_KEY'; + + let templateId = ''; + if (type === 'careers') { + templateId = process.env.EMAILJS_TEMPLATE_ID_CAREERS || 'YOUR_EMAILJS_TEMPLATE_ID_CAREERS'; + } else { + templateId = process.env.EMAILJS_TEMPLATE_ID_STRATEGY || 'YOUR_EMAILJS_TEMPLATE_ID_STRATEGY'; + } + + const templateParams = { + type: type, + name: name, + email: email, + phone: phone || mobile || '', + mobile: mobile || phone || '', + designation: designation || 'N/A', + dateTime: dateTime || 'N/A', + interests: interests || 'N/A', + resumeName: resumeName || 'None' + }; + + try { + const response = await fetch('https://api.emailjs.com/api/v1.0/email/send', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + service_id: serviceId, + template_id: templateId, + user_id: publicKey, + template_params: templateParams + }), + }); + + const data = await response.text(); + if (!response.ok) { + return res.status(response.status).json({ error: data }); + } + return res.status(200).json({ success: true, message: data }); + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} diff --git a/docs/superpowers/specs/2026-07-09-dynamic-cms-design.md b/docs/superpowers/specs/2026-07-09-dynamic-cms-design.md new file mode 100644 index 0000000..9dca38a --- /dev/null +++ b/docs/superpowers/specs/2026-07-09-dynamic-cms-design.md @@ -0,0 +1,398 @@ +# Dynamic CMS with Admin Panel — Design Spec + +**Date:** 2026-07-09 +**Status:** Approved (architecture) +**Goal:** Convert the static CITPL marketing site into a dynamic site with instant content updates via a password-protected admin panel hosted on a VPS. + +--- + +## Requirements + +| Requirement | Decision | +|-------------|----------| +| Content updates | Instant — no rebuild required | +| Data model | Latest data only (no versioning/drafts) | +| Hosting | Self-hosted VPS | +| Admin users | Single admin login | +| Editable content | Text, links, and image/video uploads | +| Public site | Existing React SPA, same visual design | + +--- + +## Architecture + +``` +┌──────────────────────────────────────────────────────────┐ +│ VPS (Ubuntu + Nginx) │ +│ │ +│ citpl.com/ citpl.com/admin │ +│ │ │ │ +│ ▼ ▼ │ +│ React SPA (dist/) Admin SPA (dist/admin/) │ +│ │ │ │ +│ └────────────┬────────────┘ │ +│ ▼ │ +│ Express API :3001 │ +│ GET /api/content (public) │ +│ POST /api/auth/login (public) │ +│ PUT /api/content/:section (auth required) │ +│ POST /api/upload (auth required) │ +│ │ │ +│ ┌──────────┴──────────┐ │ +│ ▼ ▼ │ +│ SQLite (content.db) /var/www/citpl/uploads/ │ +│ - admin user images, videos, logos │ +│ - content sections │ +└──────────────────────────────────────────────────────────┘ +``` + +### Tech Stack + +| Layer | Technology | +|-------|------------| +| Public frontend | React 19 + Vite 8 (existing) | +| Admin frontend | React 19 + Vite 8 (new entry point) | +| API | Express.js 4 | +| Database | better-sqlite3 (SQLite) | +| Auth | bcrypt + jsonwebtoken (JWT, 24h expiry) | +| File uploads | multer (max 50MB, images + video) | +| Process manager | PM2 | +| Reverse proxy | Nginx | + +--- + +## Content Schema + +All site content is stored as JSON documents in a single `content` table, keyed by section ID. On first boot, the API seeds the database from current hardcoded values. + +### Sections + +```typescript +type SiteContent = { + site: { + title: string + logo: string // URL path e.g. /uploads/logo.svg + copyright: string + } + + navigation: Array<{ + label: string + href: string + type: 'hash' | 'modal' + }> + + hero: { + video: string + badge: string + headline: string + subheadline: string + } + + metrics: Array<{ + value: string + label: string + }> + + about: { + heading: string + badgeImage: string + badgeAlt: string + backgroundImage: string + } + + partners: { + heading: string + subheading: string + body: string + logos: Array<{ name: string; image: string }> + } + + certifications: { + heading: string + items: Array<{ image: string; alt: string }> + } + + services: { + eyebrow: string + title: string + intro: string + items: Array<{ + id: string + number: string + title: string + boldStatement: string + description: string + capabilities: string[] + cta: string + glowColor: string + borderColor: string + }> + } + + whyUs: { + eyebrow: string + title: string + cards: Array<{ title: string; description: string }> + images: Array<{ src: string; alt: string }> + } + + gallery: { + eyebrow: string + title: string + subtitle: string + items: Array<{ + id: number + title: string + category: string + excerpt: string + image: string + readTime: string + }> + } + + products: { + eyebrow: string + title: string + subtitle: string + items: Array<{ + name: string + description: string + image: string + stats: Array<{ value: string; label: string }> + }> + } + + insights: { + title: string + subtitle: string + items: Array<{ + category: string + title: string + date: string + image: string + excerpt: string + }> + } + + footer: { + cta: { + headline: string + body: string + image: string + primaryButton: string + secondaryButton: string + } + quickLinks: Array<{ label: string; href: string }> + productLinks: Array<{ label: string; href: string }> + social: Array<{ platform: string; url: string }> + legal: Array<{ label: string; href: string }> + } +} +``` + +--- + +## API Design + +### Public Endpoints + +| Method | Path | Description | +|--------|------|-------------| +| GET | `/api/content` | Returns full `SiteContent` object | +| GET | `/api/health` | Health check for PM2/Nginx | + +### Auth Endpoints + +| Method | Path | Body | Response | +|--------|------|------|----------| +| POST | `/api/auth/login` | `{ username, password }` | `{ token, expiresAt }` | +| GET | `/api/auth/me` | Bearer token | `{ username }` | + +### Protected Endpoints (require `Authorization: Bearer `) + +| Method | Path | Body | Description | +|--------|------|------|-------------| +| PUT | `/api/content/:section` | Section JSON | Update one section (e.g. `hero`, `services`) | +| PUT | `/api/content` | Full `SiteContent` | Bulk update all sections | +| POST | `/api/upload` | `multipart/form-data` field `file` | Upload image/video, returns `{ url }` | +| DELETE | `/api/upload/:filename` | — | Remove uploaded file | + +### Error Responses + +```json +{ "error": "Human-readable message", "code": "UNAUTHORIZED" } +``` + +HTTP codes: 400 (validation), 401 (auth), 404 (not found), 413 (file too large), 500 (server). + +--- + +## Admin Panel + +**URL:** `/admin` +**Login:** Single username/password set via environment variable on first deploy. + +### Pages + +| Page | Edits | +|------|-------| +| Dashboard | Quick links to all sections, last-updated timestamp | +| Hero & Metrics | Headline, video upload, badge text, stat values | +| About & Partners | Headings, partner logos (upload + reorder) | +| Certifications | Upload/replace badge images | +| Services | CRUD for all 6 service cards | +| Why Us | 4 value cards + 3 image uploads | +| Gallery | CRUD gallery items with image upload | +| Products | 3 product cards with stats and screenshots | +| Insights | CRUD blog cards with image upload | +| Footer & Links | CTA text, social URLs, quick links | +| Settings | Change admin password | + +### Admin UX + +- Sidebar navigation matching section list above +- Inline form fields with save button per section +- Image fields show current preview + upload/replace button +- Toast notifications on save success/failure +- Redirect to `/admin/login` if token expired + +--- + +## Frontend Changes (Public Site) + +1. **Content hook** — `useContent()` fetches `/api/content` on mount, shows loading skeleton, caches in React context +2. **Refactor `App.jsx`** — Replace hardcoded strings/arrays with `content.hero`, `content.services`, etc. +3. **Refactor `FeaturedGallery.jsx`** — Accept `content.gallery` as prop instead of inline data +4. **Image URLs** — All image paths become absolute URLs from API (`/uploads/...` or external) +5. **Fallback** — If API unreachable, show cached content or graceful error banner (not blank page) + +### New Files + +``` +server/ + index.js # Express app entry + db.js # SQLite setup + seed + auth.js # JWT middleware + routes/ + content.js + auth.js + upload.js + seed/ + default-content.json # Current site content extracted from App.jsx + +src/ + context/ContentContext.jsx + hooks/useContent.js + admin/ + main.jsx + App.jsx + pages/ + Login.jsx + Dashboard.jsx + HeroEditor.jsx + ServicesEditor.jsx + ... (one per section) + components/ + ImageUpload.jsx + SectionForm.jsx + AdminLayout.jsx +``` + +--- + +## Security + +| Concern | Mitigation | +|---------|------------| +| Brute-force login | Rate limit `/api/auth/login` (5 attempts/min per IP) | +| JWT theft | HttpOnly not possible cross-origin; use short 24h expiry + secure flag in production | +| File uploads | Whitelist MIME types: `image/*`, `video/mp4`; max 50MB; sanitize filenames | +| SQL injection | Parameterized queries only (better-sqlite3 prepared statements) | +| Admin password | bcrypt hash (cost 12); initial password via `ADMIN_PASSWORD` env var | +| CORS | Restrict to production domain only | + +--- + +## Deployment (VPS) + +### Environment Variables + +```env +PORT=3001 +JWT_SECRET= +ADMIN_USERNAME=admin +ADMIN_PASSWORD= +UPLOAD_DIR=/var/www/citpl/uploads +DB_PATH=/var/www/citpl/data/content.db +NODE_ENV=production +CORS_ORIGIN=https://citpl.com +``` + +### Nginx Config (summary) + +```nginx +server { + listen 80; + server_name citpl.com; + + # Public site + location / { + root /var/www/citpl/dist; + try_files $uri $uri/ /index.html; + } + + # Admin panel + location /admin { + alias /var/www/citpl/dist-admin; + try_files $uri $uri/ /admin/index.html; + } + + # API + location /api { + proxy_pass http://127.0.0.1:3001; + } + + # Uploaded media + location /uploads { + alias /var/www/citpl/uploads; + expires 30d; + } +} +``` + +### PM2 + +```bash +pm2 start server/index.js --name citpl-api +pm2 save +``` + +### Deploy Script + +```bash +npm run build # public site → dist/ +npm run build:admin # admin panel → dist-admin/ +rsync dist/ dist-admin/ server/ → VPS +pm2 restart citpl-api +``` + +--- + +## Out of Scope (v1) + +- Multiple admin users / roles +- Content versioning or drafts +- Careers / Strategy Call form backend (keep EmailJS as-is) +- Blog detail pages (insights remain cards only) +- SSL setup (assumed handled separately via Certbot) +- CI/CD pipeline (manual deploy script provided) + +--- + +## Success Criteria + +1. Admin can log in at `/admin` with username/password +2. Admin can edit any section and save — changes appear on public site within seconds (page refresh) +3. Admin can upload/replace images and hero video +4. Public site loads all content from API with no hardcoded copy remaining +5. API + site run stably on a 1GB RAM VPS via PM2 diff --git a/env copy b/env copy new file mode 100644 index 0000000..3bfd9c8 --- /dev/null +++ b/env copy @@ -0,0 +1,4 @@ +VITE_EMAILJS_SERVICE_ID=vishva_cavintest +VITE_EMAILJS_PUBLIC_KEY=bdFwOnjhuMUeUeIe7 +VITE_EMAILJS_TEMPLATE_ID_CAREERS=template_i6pkzka +VITE_EMAILJS_TEMPLATE_ID_STRATEGY=template_ueukbd8 diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..ea36dd3 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,21 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{js,jsx}'], + extends: [ + js.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + globals: globals.browser, + parserOptions: { ecmaFeatures: { jsx: true } }, + }, + }, +]) diff --git a/index.html b/index.html new file mode 100644 index 0000000..42ca20d --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Cavin Infotech | One Trusted Technology Partner + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..12d01cf --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3873 @@ +{ + "name": "cavin-infotech-website-project", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cavin-infotech-website-project", + "version": "0.0.0", + "dependencies": { + "bcryptjs": "^3.0.3", + "cors": "^2.8.6", + "dotenv": "^17.4.2", + "express": "^5.2.1", + "framer-motion": "^12.40.0", + "jsonwebtoken": "^9.0.3", + "lucide-react": "^1.18.0", + "multer": "^2.2.0", + "react": "^19.2.6", + "react-dom": "^19.2.6" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "concurrently": "^10.0.3", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.6.0", + "vite": "^8.0.12" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@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/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@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.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/@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.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "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 + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@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": "https://registry.npmjs.org/@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/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "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": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", + "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@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/@vitejs/plugin-react": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz", + "integrity": "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/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.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "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-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/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/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.37", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz", + "integrity": "sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bcryptjs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.3.tgz", + "integrity": "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g==", + "license": "BSD-3-Clause", + "bin": { + "bcrypt": "bin/bcrypt" + } + }, + "node_modules/body-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^2.0.0", + "debug": "^4.4.3", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", + "on-finished": "^2.4.1", + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "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.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001799", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", + "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", + "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/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concurrently": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-10.0.3.tgz", + "integrity": "sha512-hc3LH4UaKWd/bbyDK/IGVa4RB6PtQ3CUYwtrkzqHn+wIG3Hr5fhpRlk0L/gCa8ZE1L/Ufj50Zho69cI5w8SQBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "5.6.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.4", + "supports-color": "10.2.2", + "tree-kill": "1.2.2", + "yargs": "18.0.0" + }, + "bin": { + "conc": "dist/bin/index.js", + "concurrently": "dist/bin/index.js" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/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/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.373", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.373.tgz", + "integrity": "sha512-G2Hym8JIf/QreuseqkDibgH8Ci8KfJzqGDKdakbhSx9UltwRBH2cBLAWU/lBX0sCdv0TlhyxQyDCnSfxgMWsjA==", + "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/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.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-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/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.5.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.5.0.tgz", + "integrity": "sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==", + "dev": true, + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.6.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@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.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "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 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.3.tgz", + "integrity": "sha512-5EMmLCV98Pi4o/f/3DP/v/tNqLHMIc9I8LKClNDWhZ9JTho89/kQcitCXQBMG7sAfVRK0Ie3T2EDOzp1YXYiVA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": "^9 || ^10" + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/framer-motion": { + "version": "12.40.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.40.0.tgz", + "integrity": "sha512-uaBd3qC1v3KQqBEjwTUd183K6PbS+j0yR9w9VmEOLWA/tnUcSn8Xa3uck7t4dgpDoUss8xQTcj8W2L07lrnLFg==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.40.0", + "motion-utils": "^12.39.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/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/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/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/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": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/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/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "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.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "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": "https://registry.npmjs.org/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.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "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/lucide-react": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.18.0.tgz", + "integrity": "sha512-LZDb7H/0YfM+RJncD0hDQRCAu+vSGODqpe35TuVI8EuXaRjkczbsx7p8dY4J87F/MUSj6bpYqeI8nw8qXaAdmA==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/motion-dom": { + "version": "12.40.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.40.0.tgz", + "integrity": "sha512-HxU3ZaBwNPVQUBQf1xxgq+7JrPNZvjLVxgbpEZL7RrWJnsxOf0/OM+yrHG9ogLQ31Do/r57Oz2gQWPK+6q62mg==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.39.0" + } + }, + "node_modules/motion-utils": { + "version": "12.39.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.39.0.tgz", + "integrity": "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.2.0.tgz", + "integrity": "sha512-6rdyFg2kLrMh9Jee7/BMPuV9lEAd7lLW2YUpF9/YxR7njyoUwwQ0ZPh3TaIY50Sw6vlyD2HW3wGOkTS4P79xrQ==", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.6.0", + "concat-stream": "^2.0.0", + "type-is": "^1.6.18" + }, + "engines": { + "node": ">= 10.16.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/multer/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "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": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-releases": { + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "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.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "license": "BSD-3-Clause", + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/rolldown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.133.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "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/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/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": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.4.tgz", + "integrity": "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "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/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/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/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/type-is": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "license": "MIT", + "dependencies": { + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", + "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.15", + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" + }, + "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", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.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 + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "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": "https://registry.npmjs.org/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": "https://registry.npmjs.org/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/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "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/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/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.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "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" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..b6bc917 --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "cavin-infotech-website-project", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "concurrently \"npm run server\" \"vite\"", + "dev:client": "vite", + "server": "node server/index.js", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "bcryptjs": "^3.0.3", + "cors": "^2.8.6", + "dotenv": "^17.4.2", + "express": "^5.2.1", + "framer-motion": "^12.40.0", + "jsonwebtoken": "^9.0.3", + "lucide-react": "^1.18.0", + "multer": "^2.2.0", + "react": "^19.2.6", + "react-dom": "^19.2.6" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "concurrently": "^10.0.3", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.6.0", + "vite": "^8.0.12" + } +} diff --git a/preview.html b/preview.html new file mode 100644 index 0000000..93168c9 --- /dev/null +++ b/preview.html @@ -0,0 +1,12 @@ + + + + + + CITPL Preview + + +
+ + + diff --git a/public/assets/Citpl Hero Dubai(1).mp4 b/public/assets/Citpl Hero Dubai(1).mp4 new file mode 100644 index 0000000..1b59f45 Binary files /dev/null and b/public/assets/Citpl Hero Dubai(1).mp4 differ diff --git a/public/assets/Citpl Hero(1).mp4 b/public/assets/Citpl Hero(1).mp4 new file mode 100644 index 0000000..0fdb931 Binary files /dev/null and b/public/assets/Citpl Hero(1).mp4 differ diff --git a/public/assets/Footer CTA Section.png b/public/assets/Footer CTA Section.png new file mode 100644 index 0000000..f0c6f99 Binary files /dev/null and b/public/assets/Footer CTA Section.png differ diff --git a/public/assets/Frame 1686554967.png b/public/assets/Frame 1686554967.png new file mode 100644 index 0000000..bcaf5b1 Binary files /dev/null and b/public/assets/Frame 1686554967.png differ diff --git a/public/assets/Frame 1686554968.png b/public/assets/Frame 1686554968.png new file mode 100644 index 0000000..5261624 Binary files /dev/null and b/public/assets/Frame 1686554968.png differ diff --git a/public/assets/Frame 1686554969.png b/public/assets/Frame 1686554969.png new file mode 100644 index 0000000..ab84b03 Binary files /dev/null and b/public/assets/Frame 1686554969.png differ diff --git a/public/assets/Frame 1686557969.png b/public/assets/Frame 1686557969.png new file mode 100644 index 0000000..d48f379 Binary files /dev/null and b/public/assets/Frame 1686557969.png differ diff --git a/public/assets/Frame 1686558351.png b/public/assets/Frame 1686558351.png new file mode 100644 index 0000000..de9f348 Binary files /dev/null and b/public/assets/Frame 1686558351.png differ diff --git a/public/assets/Frame 1686558446.png b/public/assets/Frame 1686558446.png new file mode 100644 index 0000000..3bc74cb Binary files /dev/null and b/public/assets/Frame 1686558446.png differ diff --git a/public/assets/Frame 199.png b/public/assets/Frame 199.png new file mode 100644 index 0000000..acd52b1 Binary files /dev/null and b/public/assets/Frame 199.png differ diff --git a/public/assets/Frame 25.png b/public/assets/Frame 25.png new file mode 100644 index 0000000..a8ce3d1 Binary files /dev/null and b/public/assets/Frame 25.png differ diff --git a/public/assets/Frame 27.png b/public/assets/Frame 27.png new file mode 100644 index 0000000..acba5aa Binary files /dev/null and b/public/assets/Frame 27.png differ diff --git a/public/assets/Frame 27.svg b/public/assets/Frame 27.svg new file mode 100644 index 0000000..cb6b382 --- /dev/null +++ b/public/assets/Frame 27.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/Frame 28.png b/public/assets/Frame 28.png new file mode 100644 index 0000000..2883b46 Binary files /dev/null and b/public/assets/Frame 28.png differ diff --git a/public/assets/Frame 28.svg b/public/assets/Frame 28.svg new file mode 100644 index 0000000..1814cb1 --- /dev/null +++ b/public/assets/Frame 28.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/Frame 30.png b/public/assets/Frame 30.png new file mode 100644 index 0000000..d4ca878 Binary files /dev/null and b/public/assets/Frame 30.png differ diff --git a/public/assets/Frame 30.svg b/public/assets/Frame 30.svg new file mode 100644 index 0000000..370b611 --- /dev/null +++ b/public/assets/Frame 30.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/Frame 31.png b/public/assets/Frame 31.png new file mode 100644 index 0000000..296c485 Binary files /dev/null and b/public/assets/Frame 31.png differ diff --git a/public/assets/Frame 31.svg b/public/assets/Frame 31.svg new file mode 100644 index 0000000..f54a3d0 --- /dev/null +++ b/public/assets/Frame 31.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/Frame 32.png b/public/assets/Frame 32.png new file mode 100644 index 0000000..d5f10e4 Binary files /dev/null and b/public/assets/Frame 32.png differ diff --git a/public/assets/Frame 32.svg b/public/assets/Frame 32.svg new file mode 100644 index 0000000..69949d0 --- /dev/null +++ b/public/assets/Frame 32.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/assets/Frame 33.png b/public/assets/Frame 33.png new file mode 100644 index 0000000..ea4103b Binary files /dev/null and b/public/assets/Frame 33.png differ diff --git a/public/assets/Frame 33.svg b/public/assets/Frame 33.svg new file mode 100644 index 0000000..dbbc074 --- /dev/null +++ b/public/assets/Frame 33.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/assets/Frame 34.png b/public/assets/Frame 34.png new file mode 100644 index 0000000..2f25d7f Binary files /dev/null and b/public/assets/Frame 34.png differ diff --git a/public/assets/Frame 34.svg b/public/assets/Frame 34.svg new file mode 100644 index 0000000..1910ad0 --- /dev/null +++ b/public/assets/Frame 34.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/Frame 35.png b/public/assets/Frame 35.png new file mode 100644 index 0000000..40e5f0c Binary files /dev/null and b/public/assets/Frame 35.png differ diff --git a/public/assets/Frame 35.svg b/public/assets/Frame 35.svg new file mode 100644 index 0000000..0742f58 --- /dev/null +++ b/public/assets/Frame 35.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/assets/Frame 36.png b/public/assets/Frame 36.png new file mode 100644 index 0000000..e994385 Binary files /dev/null and b/public/assets/Frame 36.png differ diff --git a/public/assets/Frame 36.svg b/public/assets/Frame 36.svg new file mode 100644 index 0000000..c604a35 --- /dev/null +++ b/public/assets/Frame 36.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/Frame 6.png b/public/assets/Frame 6.png new file mode 100644 index 0000000..5c81ea5 Binary files /dev/null and b/public/assets/Frame 6.png differ diff --git a/public/assets/Frame 87.png b/public/assets/Frame 87.png new file mode 100644 index 0000000..124abd0 Binary files /dev/null and b/public/assets/Frame 87.png differ diff --git a/public/assets/Frame 92.png b/public/assets/Frame 92.png new file mode 100644 index 0000000..a2baaba Binary files /dev/null and b/public/assets/Frame 92.png differ diff --git a/public/assets/Frame 95.png b/public/assets/Frame 95.png new file mode 100644 index 0000000..3a54920 Binary files /dev/null and b/public/assets/Frame 95.png differ diff --git a/public/assets/Frame 97.png b/public/assets/Frame 97.png new file mode 100644 index 0000000..0acd974 Binary files /dev/null and b/public/assets/Frame 97.png differ diff --git a/public/assets/Frame.png b/public/assets/Frame.png new file mode 100644 index 0000000..d2a16ce Binary files /dev/null and b/public/assets/Frame.png differ diff --git a/public/assets/GlobeVector.svg b/public/assets/GlobeVector.svg new file mode 100644 index 0000000..e8d78e7 --- /dev/null +++ b/public/assets/GlobeVector.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/Infotech Footer image.png b/public/assets/Infotech Footer image.png new file mode 100644 index 0000000..f1ae142 Binary files /dev/null and b/public/assets/Infotech Footer image.png differ diff --git a/public/assets/budgie_dashboard.png b/public/assets/budgie_dashboard.png new file mode 100644 index 0000000..acdc1cf Binary files /dev/null and b/public/assets/budgie_dashboard.png differ diff --git a/public/assets/button_container.png b/public/assets/button_container.png new file mode 100644 index 0000000..8901f0a Binary files /dev/null and b/public/assets/button_container.png differ diff --git a/public/assets/button_container.svg b/public/assets/button_container.svg new file mode 100644 index 0000000..23de0a6 --- /dev/null +++ b/public/assets/button_container.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/button_hover_effect.png b/public/assets/button_hover_effect.png new file mode 100644 index 0000000..c6a4f4d Binary files /dev/null and b/public/assets/button_hover_effect.png differ diff --git a/public/assets/cavin_logo.png b/public/assets/cavin_logo.png new file mode 100644 index 0000000..5c81ea5 Binary files /dev/null and b/public/assets/cavin_logo.png differ diff --git a/public/assets/cavin_logo.svg b/public/assets/cavin_logo.svg new file mode 100644 index 0000000..e0ad4c5 --- /dev/null +++ b/public/assets/cavin_logo.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/public/assets/cert_1.png b/public/assets/cert_1.png new file mode 100644 index 0000000..7e8629b Binary files /dev/null and b/public/assets/cert_1.png differ diff --git a/public/assets/cert_2.png b/public/assets/cert_2.png new file mode 100644 index 0000000..7e8629b Binary files /dev/null and b/public/assets/cert_2.png differ diff --git a/public/assets/cert_gptw_2026.png b/public/assets/cert_gptw_2026.png new file mode 100644 index 0000000..8f1623b Binary files /dev/null and b/public/assets/cert_gptw_2026.png differ diff --git a/public/assets/cert_iso_27001.png b/public/assets/cert_iso_27001.png new file mode 100644 index 0000000..d462caa Binary files /dev/null and b/public/assets/cert_iso_27001.png differ diff --git a/public/assets/cert_iso_9001.png b/public/assets/cert_iso_9001.png new file mode 100644 index 0000000..7e8629b Binary files /dev/null and b/public/assets/cert_iso_9001.png differ diff --git a/public/assets/cert_logo_1.png b/public/assets/cert_logo_1.png new file mode 100644 index 0000000..444f3a2 Binary files /dev/null and b/public/assets/cert_logo_1.png differ diff --git a/public/assets/cert_logo_2.png b/public/assets/cert_logo_2.png new file mode 100644 index 0000000..5bfb995 Binary files /dev/null and b/public/assets/cert_logo_2.png differ diff --git a/public/assets/cert_logo_3.png b/public/assets/cert_logo_3.png new file mode 100644 index 0000000..2efe699 Binary files /dev/null and b/public/assets/cert_logo_3.png differ diff --git a/public/assets/cert_logo_4.png b/public/assets/cert_logo_4.png new file mode 100644 index 0000000..9e48734 Binary files /dev/null and b/public/assets/cert_logo_4.png differ diff --git a/public/assets/cert_soc.png b/public/assets/cert_soc.png new file mode 100644 index 0000000..b5f116b Binary files /dev/null and b/public/assets/cert_soc.png differ diff --git a/public/assets/citp_footer_design.png b/public/assets/citp_footer_design.png new file mode 100644 index 0000000..f1ae142 Binary files /dev/null and b/public/assets/citp_footer_design.png differ diff --git a/public/assets/evido_dashboard.png b/public/assets/evido_dashboard.png new file mode 100644 index 0000000..03187cc Binary files /dev/null and b/public/assets/evido_dashboard.png differ diff --git a/public/assets/frost_sullivan.svg b/public/assets/frost_sullivan.svg new file mode 100644 index 0000000..69452cd --- /dev/null +++ b/public/assets/frost_sullivan.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/gold_confetti.svg b/public/assets/gold_confetti.svg new file mode 100644 index 0000000..cd3dc64 --- /dev/null +++ b/public/assets/gold_confetti.svg @@ -0,0 +1,2989 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/great_place_work.jpg b/public/assets/great_place_work.jpg new file mode 100644 index 0000000..e928bad Binary files /dev/null and b/public/assets/great_place_work.jpg differ diff --git a/public/assets/hero_cube.png b/public/assets/hero_cube.png new file mode 100644 index 0000000..3bc74cb Binary files /dev/null and b/public/assets/hero_cube.png differ diff --git a/public/assets/iso.svg b/public/assets/iso.svg new file mode 100644 index 0000000..f436ed4 --- /dev/null +++ b/public/assets/iso.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/iso_9001.png b/public/assets/iso_9001.png new file mode 100644 index 0000000..7e8629b Binary files /dev/null and b/public/assets/iso_9001.png differ diff --git a/public/assets/kone.png b/public/assets/kone.png new file mode 100644 index 0000000..3e37a9f Binary files /dev/null and b/public/assets/kone.png differ diff --git a/public/assets/light_ray.png b/public/assets/light_ray.png new file mode 100644 index 0000000..011c8e3 Binary files /dev/null and b/public/assets/light_ray.png differ diff --git a/public/assets/nasscom.png b/public/assets/nasscom.png new file mode 100644 index 0000000..85e148a Binary files /dev/null and b/public/assets/nasscom.png differ diff --git a/public/assets/new_logos_banner.png b/public/assets/new_logos_banner.png new file mode 100644 index 0000000..acbfa98 Binary files /dev/null and b/public/assets/new_logos_banner.png differ diff --git a/public/assets/partner_bg.png b/public/assets/partner_bg.png new file mode 100644 index 0000000..55b12e6 Binary files /dev/null and b/public/assets/partner_bg.png differ diff --git a/public/assets/prodmax_dashboard.png b/public/assets/prodmax_dashboard.png new file mode 100644 index 0000000..a8064bd Binary files /dev/null and b/public/assets/prodmax_dashboard.png differ diff --git a/public/assets/product_card_bg.png b/public/assets/product_card_bg.png new file mode 100644 index 0000000..5e5bfa9 Binary files /dev/null and b/public/assets/product_card_bg.png differ diff --git a/public/assets/soc2.svg b/public/assets/soc2.svg new file mode 100644 index 0000000..9d708ad --- /dev/null +++ b/public/assets/soc2.svg @@ -0,0 +1,144 @@ + + + + + + + + diff --git a/public/assets/user_upload_cert_1.png b/public/assets/user_upload_cert_1.png new file mode 100644 index 0000000..7e8629b Binary files /dev/null and b/public/assets/user_upload_cert_1.png differ diff --git a/public/assets/user_upload_cert_2.png b/public/assets/user_upload_cert_2.png new file mode 100644 index 0000000..94fa62a Binary files /dev/null and b/public/assets/user_upload_cert_2.png differ diff --git a/public/assets/user_upload_cert_soc.png b/public/assets/user_upload_cert_soc.png new file mode 100644 index 0000000..94fa62a Binary files /dev/null and b/public/assets/user_upload_cert_soc.png differ diff --git a/public/assets/whyus_arab_meeting.jpg b/public/assets/whyus_arab_meeting.jpg new file mode 100644 index 0000000..83f59af Binary files /dev/null and b/public/assets/whyus_arab_meeting.jpg differ diff --git a/public/assets/whyus_collaboration.png b/public/assets/whyus_collaboration.png new file mode 100644 index 0000000..27e50dd Binary files /dev/null and b/public/assets/whyus_collaboration.png differ diff --git a/public/assets/whyus_conference.png b/public/assets/whyus_conference.png new file mode 100644 index 0000000..ff8cd91 Binary files /dev/null and b/public/assets/whyus_conference.png differ diff --git a/public/assets/whyus_hologram.jpg b/public/assets/whyus_hologram.jpg new file mode 100644 index 0000000..5ae941e Binary files /dev/null and b/public/assets/whyus_hologram.jpg differ diff --git a/public/assets/whyus_teamwork.png b/public/assets/whyus_teamwork.png new file mode 100644 index 0000000..d8116bc Binary files /dev/null and b/public/assets/whyus_teamwork.png differ diff --git a/public/assets/whyus_teamwork_user.jpg b/public/assets/whyus_teamwork_user.jpg new file mode 100644 index 0000000..d8116bc Binary files /dev/null and b/public/assets/whyus_teamwork_user.jpg differ diff --git a/public/assets/whyus_vr_man.jpg b/public/assets/whyus_vr_man.jpg new file mode 100644 index 0000000..183fc0c Binary files /dev/null and b/public/assets/whyus_vr_man.jpg differ diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons.svg b/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/auth.js b/server/auth.js new file mode 100644 index 0000000..ce49e9d --- /dev/null +++ b/server/auth.js @@ -0,0 +1,26 @@ +import jwt from 'jsonwebtoken'; + +const JWT_SECRET = process.env.JWT_SECRET || 'dev-secret-change-in-production'; +const JWT_EXPIRY = '24h'; + +export function signToken(username) { + return jwt.sign({ username }, JWT_SECRET, { expiresIn: JWT_EXPIRY }); +} + +export function verifyToken(token) { + return jwt.verify(token, JWT_SECRET); +} + +export function requireAuth(req, res, next) { + const header = req.headers.authorization; + if (!header?.startsWith('Bearer ')) { + return res.status(401).json({ error: 'Authentication required', code: 'UNAUTHORIZED' }); + } + + try { + req.user = verifyToken(header.slice(7)); + next(); + } catch { + return res.status(401).json({ error: 'Invalid or expired token', code: 'UNAUTHORIZED' }); + } +} diff --git a/server/db.js b/server/db.js new file mode 100644 index 0000000..bfada3d --- /dev/null +++ b/server/db.js @@ -0,0 +1,80 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import bcrypt from 'bcryptjs'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const DATA_DIR = process.env.DATA_DIR || path.join(__dirname, 'data'); +const CONTENT_FILE = path.join(DATA_DIR, 'content.json'); +const ADMIN_FILE = path.join(DATA_DIR, 'admin.json'); +const SEED_FILE = path.join(__dirname, 'seed', 'default-content.json'); + +function ensureDataDir() { + if (!fs.existsSync(DATA_DIR)) { + fs.mkdirSync(DATA_DIR, { recursive: true }); + } +} + +function readJson(filePath, fallback = null) { + if (!fs.existsSync(filePath)) return fallback; + return JSON.parse(fs.readFileSync(filePath, 'utf-8')); +} + +function writeJson(filePath, data) { + ensureDataDir(); + fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); +} + +export function initDb() { + ensureDataDir(); + + if (!fs.existsSync(CONTENT_FILE)) { + const seed = readJson(SEED_FILE); + writeJson(CONTENT_FILE, { ...seed, updatedAt: new Date().toISOString() }); + console.log('Seeded content database from default-content.json'); + } + + if (!fs.existsSync(ADMIN_FILE)) { + const password = process.env.ADMIN_PASSWORD || 'admin123'; + const hash = bcrypt.hashSync(password, 12); + writeJson(ADMIN_FILE, { + username: process.env.ADMIN_USERNAME || 'admin', + passwordHash: hash, + }); + console.log(`Admin user created (username: ${process.env.ADMIN_USERNAME || 'admin'})`); + } +} + +export function getContent() { + const data = readJson(CONTENT_FILE, {}); + const { updatedAt, ...content } = data; + return { content, updatedAt }; +} + +export function getFullContentRecord() { + return readJson(CONTENT_FILE, {}); +} + +export function updateSection(section, sectionData) { + const record = getFullContentRecord(); + record[section] = sectionData; + record.updatedAt = new Date().toISOString(); + writeJson(CONTENT_FILE, record); + return record.updatedAt; +} + +export function updateAllContent(content) { + const record = { ...content, updatedAt: new Date().toISOString() }; + writeJson(CONTENT_FILE, record); + return record.updatedAt; +} + +export function getAdmin() { + return readJson(ADMIN_FILE); +} + +export function updateAdminPassword(passwordHash) { + const admin = getAdmin(); + admin.passwordHash = passwordHash; + writeJson(ADMIN_FILE, admin); +} diff --git a/server/index.js b/server/index.js new file mode 100644 index 0000000..bc7e6c2 --- /dev/null +++ b/server/index.js @@ -0,0 +1,46 @@ +import 'dotenv/config'; +import express from 'express'; +import cors from 'cors'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { initDb } from './db.js'; +import authRoutes from './routes/auth.js'; +import contentRoutes from './routes/content.js'; +import uploadRoutes from './routes/upload.js'; +import multer from 'multer'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const PORT = process.env.PORT || 3001; +const UPLOAD_DIR = process.env.UPLOAD_DIR || path.join(__dirname, 'uploads'); + +initDb(); + +const app = express(); + +app.use(cors({ + origin: process.env.CORS_ORIGIN || true, + credentials: true, +})); + +app.use(express.json({ limit: '10mb' })); +app.use('/uploads', express.static(UPLOAD_DIR)); + +app.get('/api/health', (_req, res) => { + res.json({ status: 'ok', timestamp: new Date().toISOString() }); +}); + +app.use('/api/auth', authRoutes); +app.use('/api/content', contentRoutes); +app.use('/api/upload', uploadRoutes); + +app.use((err, _req, res, _next) => { + if (err instanceof multer.MulterError && err.code === 'LIMIT_FILE_SIZE') { + return res.status(413).json({ error: 'File too large (max 50MB)', code: 'FILE_TOO_LARGE' }); + } + console.error(err); + res.status(500).json({ error: err.message || 'Internal server error', code: 'SERVER_ERROR' }); +}); + +app.listen(PORT, () => { + console.log(`API server running on http://localhost:${PORT}`); +}); diff --git a/server/routes/auth.js b/server/routes/auth.js new file mode 100644 index 0000000..db462cf --- /dev/null +++ b/server/routes/auth.js @@ -0,0 +1,62 @@ +import { Router } from 'express'; +import bcrypt from 'bcryptjs'; +import { getAdmin, updateAdminPassword } from '../db.js'; +import { requireAuth, signToken } from '../auth.js'; + +const router = Router(); +const loginAttempts = new Map(); + +function checkRateLimit(ip) { + const now = Date.now(); + const record = loginAttempts.get(ip) || { count: 0, resetAt: now + 60000 }; + if (now > record.resetAt) { + loginAttempts.set(ip, { count: 1, resetAt: now + 60000 }); + return true; + } + if (record.count >= 5) return false; + record.count++; + loginAttempts.set(ip, record); + return true; +} + +router.post('/login', (req, res) => { + const ip = req.ip; + if (!checkRateLimit(ip)) { + return res.status(429).json({ error: 'Too many login attempts', code: 'RATE_LIMITED' }); + } + + const { username, password } = req.body; + if (!username || !password) { + return res.status(400).json({ error: 'Username and password required', code: 'VALIDATION' }); + } + + const admin = getAdmin(); + if (!admin || username !== admin.username || !bcrypt.compareSync(password, admin.passwordHash)) { + return res.status(401).json({ error: 'Invalid credentials', code: 'UNAUTHORIZED' }); + } + + const token = signToken(username); + const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); + res.json({ token, expiresAt }); +}); + +router.get('/me', requireAuth, (req, res) => { + res.json({ username: req.user.username }); +}); + +router.put('/password', requireAuth, (req, res) => { + const { currentPassword, newPassword } = req.body; + if (!currentPassword || !newPassword || newPassword.length < 6) { + return res.status(400).json({ error: 'Valid current and new password (min 6 chars) required', code: 'VALIDATION' }); + } + + const admin = getAdmin(); + if (!bcrypt.compareSync(currentPassword, admin.passwordHash)) { + return res.status(401).json({ error: 'Current password is incorrect', code: 'UNAUTHORIZED' }); + } + + updateAdminPassword(bcrypt.hashSync(newPassword, 12)); + res.json({ message: 'Password updated' }); +}); + +export default router; diff --git a/server/routes/content.js b/server/routes/content.js new file mode 100644 index 0000000..265bcd7 --- /dev/null +++ b/server/routes/content.js @@ -0,0 +1,30 @@ +import { Router } from 'express'; +import { getContent, updateSection, updateAllContent } from '../db.js'; +import { requireAuth } from '../auth.js'; +import seedContent from '../seed/default-content.json' with { type: 'json' }; + +const VALID_SECTIONS = Object.keys(seedContent); + +const router = Router(); + +router.get('/', (_req, res) => { + const { content, updatedAt } = getContent(); + res.json({ ...content, _updatedAt: updatedAt }); +}); + +router.put('/', requireAuth, (req, res) => { + const { _updatedAt, ...content } = req.body; + const updatedAt = updateAllContent(content); + res.json({ message: 'Content updated', updatedAt }); +}); + +router.put('/:section', requireAuth, (req, res) => { + const { section } = req.params; + if (!VALID_SECTIONS.includes(section)) { + return res.status(404).json({ error: `Unknown section: ${section}`, code: 'NOT_FOUND' }); + } + const updatedAt = updateSection(section, req.body); + res.json({ message: `${section} updated`, updatedAt }); +}); + +export default router; diff --git a/server/routes/upload.js b/server/routes/upload.js new file mode 100644 index 0000000..a073bfa --- /dev/null +++ b/server/routes/upload.js @@ -0,0 +1,49 @@ +import { Router } from 'express'; +import multer from 'multer'; +import path from 'path'; +import fs from 'fs'; +import { fileURLToPath } from 'url'; +import { requireAuth } from '../auth.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const UPLOAD_DIR = process.env.UPLOAD_DIR || path.join(__dirname, '..', 'uploads'); + +if (!fs.existsSync(UPLOAD_DIR)) { + fs.mkdirSync(UPLOAD_DIR, { recursive: true }); +} + +const storage = multer.diskStorage({ + destination: (_req, _file, cb) => cb(null, UPLOAD_DIR), + filename: (_req, file, cb) => { + const ext = path.extname(file.originalname).toLowerCase(); + const base = path.basename(file.originalname, ext).replace(/[^a-zA-Z0-9-_]/g, '_').slice(0, 50); + cb(null, `${base}-${Date.now()}${ext}`); + }, +}); + +const upload = multer({ + storage, + limits: { fileSize: 50 * 1024 * 1024 }, + fileFilter: (_req, file, cb) => { + const allowed = /^image\/|^video\/mp4$/; + if (allowed.test(file.mimetype)) cb(null, true); + else cb(new Error('Only images and MP4 videos are allowed')); + }, +}); + +const router = Router(); + +router.post('/', requireAuth, upload.single('file'), (req, res) => { + if (!req.file) { + return res.status(400).json({ error: 'No file uploaded', code: 'VALIDATION' }); + } + res.json({ url: `/uploads/${req.file.filename}`, filename: req.file.filename }); +}); + +router.delete('/:filename', requireAuth, (req, res) => { + const filePath = path.join(UPLOAD_DIR, path.basename(req.params.filename)); + if (fs.existsSync(filePath)) fs.unlinkSync(filePath); + res.json({ message: 'File deleted' }); +}); + +export default router; diff --git a/server/seed/default-content.json b/server/seed/default-content.json new file mode 100644 index 0000000..c6be220 --- /dev/null +++ b/server/seed/default-content.json @@ -0,0 +1,251 @@ +{ + "site": { + "title": "Cavin Infotech | One Trusted Technology Partner", + "logo": "/assets/cavin_logo.svg", + "copyright": "Copyrights reserved to CAVIN INFOTECH" + }, + "navigation": [ + { "label": "Home", "href": "#home", "type": "hash" }, + { "label": "About Us", "href": "#aboutus", "type": "hash" }, + { "label": "Products", "href": "#products", "type": "hash" }, + { "label": "Careers", "href": "#careers", "type": "modal" }, + { "label": "Contact Us", "href": "#contactus", "type": "hash" } + ], + "hero": { + "video": "/assets/Citpl Hero Dubai(1).mp4", + "badge": "Chennai & Dubai • Trusted by 100+ Clients", + "headline": "Infinite Possibilities", + "subheadline": "One Trusted Technology Partner" + }, + "metrics": [ + { "value": "100+", "label": "Clients" }, + { "value": "5+", "label": "Years of Global Operations" }, + { "value": "4", "label": "Group Companies" }, + { "value": "2", "label": "Global Offices" } + ], + "about": { + "heading": "Trusted Technology Partner", + "badgeImage": "/assets/frost_sullivan.svg", + "badgeAlt": "Frost & Sullivan Logo", + "backgroundImage": "/assets/partner_bg.png" + }, + "partners": { + "heading": "Trusted By Leaders", + "subheading": "from various industries", + "body": "Professionals Trust Our Solutions And Complete Their Journeys.", + "logos": [ + { "name": "CavinKare", "image": "/assets/Frame 27.svg" }, + { "name": "Valeo", "image": "/assets/Frame 28.svg" }, + { "name": "Polyhose", "image": "/assets/Frame 30.svg" }, + { "name": "ACA Global", "image": "/assets/Frame 31.svg" }, + { "name": "Dawn Pictures", "image": "/assets/Frame 32.svg" }, + { "name": "MRF", "image": "/assets/Frame 33.svg" }, + { "name": "Chola MS", "image": "/assets/Frame 34.svg" }, + { "name": "Hero", "image": "/assets/Frame 35.svg" }, + { "name": "BorgWarner", "image": "/assets/Frame 36.svg" }, + { "name": "KONE", "image": "/assets/kone.png" } + ] + }, + "certifications": { + "heading": "Certified to build what enterprises trust", + "items": [ + { "image": "/assets/cert_iso_27001.png", "alt": "ISO 27001:2022 Certification" }, + { "image": "/assets/cert_iso_9001.png", "alt": "ISO 9001:2015 Certification" }, + { "image": "/assets/cert_soc.png", "alt": "SOC Certification" }, + { "image": "/assets/nasscom.png", "alt": "Nasscom Member Logo" }, + { "image": "/assets/cert_gptw_2026.png", "alt": "Great Place to Work Certified 2026 INDIA" } + ] + }, + "services": { + "eyebrow": "TECHNOLOGY THAT MOVES YOUR BUSINESS FORWARD.", + "title": "Our Services", + "intro": "From market leaders to high-growth innovators, enterprises trust Cavin Infotech to deliver secure, scalable, and future-ready digital solutions that create measurable business value.", + "items": [ + { + "id": "ai-data-services", + "number": "01", + "title": "AI & Data Services", + "boldStatement": "Your Data, Unlocked.", + "description": "Harness Generative AI, Agentic AI, and predictive analytics to automate complex workflows, predict market shifts, and unlock hidden revenue — powered by modern AI architectures.", + "capabilities": ["Generative AI & LLM Solutions", "Agentic AI & Autonomous Systems", "Predictive Analytics & Forecasting", "Conversational AI & Enterprise Assistants"], + "cta": "Explore AI Solutions", + "glowColor": "radial-gradient(circle at bottom right, rgba(255, 120, 0, 0.15) 0%, rgba(2, 7, 16, 0) 70%)", + "borderColor": "rgba(255, 120, 0, 0.12)" + }, + { + "id": "sap-managed-services", + "number": "02", + "title": "SAP Managed Services", + "boldStatement": "SAP That Works. So You Can Focus.", + "description": "Certified SAP consultants delivering functional expertise, ABAP development, security, upgrades, and license optimization — keeping your enterprise running smooth and audit-ready.", + "capabilities": ["SAP Functional Consulting", "SAP ABAP Development", "SAP Security & Compliance", "SAP Upgrades & Optimization"], + "cta": "Explore SAP Solutions", + "glowColor": "radial-gradient(circle at bottom right, rgba(0, 240, 255, 0.15) 0%, rgba(2, 7, 16, 0) 70%)", + "borderColor": "rgba(0, 240, 255, 0.12)" + }, + { + "id": "enterprise-development", + "number": "03", + "title": "Enterprise Development", + "boldStatement": "Built to Scale With You.", + "description": "Custom enterprise applications that modernize legacy workflows, connect business systems, and deliver reliable digital operations as your organization evolves.", + "capabilities": ["Custom Enterprise Applications", "Mobile & Web Platforms", "Modernization of Legacy Systems", "Workflow Automation"], + "cta": "Explore Enterprise Solutions", + "glowColor": "radial-gradient(circle at bottom right, rgba(59, 130, 246, 0.12) 0%, rgba(255, 120, 0, 0.08) 50%, rgba(2, 7, 16, 0) 100%)", + "borderColor": "rgba(59, 130, 246, 0.12)" + }, + { + "id": "architecture-as-a-service", + "number": "04", + "title": "Architecture as a Service", + "boldStatement": "Design the Foundation Before You Build.", + "description": "We help businesses define scalable technology architecture, integration models, cloud strategy, and modernization roadmaps before execution begins.", + "capabilities": ["Enterprise Architecture", "Solution Architecture", "Cloud Architecture", "Integration Architecture"], + "cta": "Explore Architecture Solutions", + "glowColor": "radial-gradient(circle at bottom right, rgba(29, 78, 216, 0.15) 0%, rgba(2, 7, 16, 0) 70%)", + "borderColor": "rgba(29, 78, 216, 0.12)" + }, + { + "id": "smart-factory-iot", + "number": "05", + "title": "Smart Factory / Industrial IoT", + "boldStatement": "Make Operations Visible, Connected, and Intelligent.", + "description": "Connect machines, sensors, production systems, and dashboards to enable real-time monitoring, predictive maintenance, and smarter factory decisions.", + "capabilities": ["Industrial IoT Integration", "Real-Time Machine Monitoring", "Predictive Maintenance", "Factory Dashboards"], + "cta": "Explore Smart Factory Solutions", + "glowColor": "radial-gradient(circle at bottom right, rgba(255, 120, 0, 0.08) 0%, rgba(59, 130, 246, 0.08) 50%, rgba(2, 7, 16, 0) 100%)", + "borderColor": "rgba(255, 120, 0, 0.1)" + }, + { + "id": "ar-vr-solutions-digifox", + "number": "06", + "title": "AR/VR Solutions — DigiFox", + "boldStatement": "Immersive Experiences for Training, Learning, and Visualization.", + "description": "Create virtual environments, simulations, AR product experiences, and immersive learning platforms that improve engagement, understanding, and retention.", + "capabilities": ["VR Training Simulations", "AR Product Visualization", "Immersive Learning Experiences", "3D Interaction Design"], + "cta": "Explore DigiFox Solutions", + "glowColor": "radial-gradient(circle at bottom right, rgba(139, 92, 246, 0.15) 0%, rgba(2, 7, 16, 0) 70%)", + "borderColor": "rgba(139, 92, 246, 0.12)" + } + ] + }, + "whyUs": { + "eyebrow": "Why Cavin Infotech", + "title": "Designed For High Scalability", + "cards": [ + { + "title": "Innovation Driven", + "description": "We deliver future-ready solutions powered by Gen AI, Agentic AI, automation, IoT, and emerging tech that keep you ahead of the curve." + }, + { + "title": "Industry Expertise", + "description": "Deep domain knowledge across manufacturing, enterprise tech, smart manufacturing, and digital operations built from years of real-world implementation." + }, + { + "title": "Secure & Reliable", + "description": "Every solution is built on globally recognized standards with uncompromising focus on security, compliance, and operational excellence." + }, + { + "title": "Outcome Focused", + "description": "We don't just implement technology we design every solution to reduce complexity, boost efficiency, and deliver clear, measurable business impact." + } + ], + "images": [ + { "src": "/assets/whyus_arab_meeting.jpg", "alt": "Corporate collaboration" }, + { "src": "/assets/whyus_vr_man.jpg", "alt": "VR technology" }, + { "src": "/assets/whyus_hologram.jpg", "alt": "Hologram technology" } + ] + }, + "gallery": { + "eyebrow": "Featured Gallery", + "title": "Real Transformations. Proven Business Outcomes.", + "subtitle": "From transformation stories to team innovation, explore how we build future-ready experiences.", + "items": [ + { "id": 1, "title": "Relentless Brand Growth & Innovation", "category": "Case Study", "excerpt": "Discover how we engineered a scalable digital platform that boosted brand engagement by 150% and accelerated global market reach.", "image": "https://images.unsplash.com/photo-1460925895917-afdab827c52f?auto=format&fit=crop&w=800&q=80", "readTime": "5 Min Read" }, + { "id": 2, "title": "How We Transformed Billing at TTK", "category": "Transformation", "excerpt": "Transitioning legacy paper billing to an automated IoT-driven workflow, reducing checkout delays and improving customer satisfaction.", "image": "https://images.unsplash.com/photo-1554224155-8d04cb21cd6c?auto=format&fit=crop&w=800&q=80", "readTime": "8 Min Read" }, + { "id": 3, "title": "How We Transformed Retail Operations", "category": "Retail", "excerpt": "Unifying online inventory with physical retail networks, enabling smart warehouse tracking and seamless order fulfillment.", "image": "https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?auto=format&fit=crop&w=800&q=80", "readTime": "6 Min Read" }, + { "id": 4, "title": "How We Transformed Enterprise Workflows", "category": "Workflow", "excerpt": "Re-engineering internal communication channels and operations with Gen AI assistants, saving thousands of operational hours.", "image": "https://images.unsplash.com/photo-1531538606174-0f90ff5dce83?auto=format&fit=crop&w=800&q=80", "readTime": "10 Min Read" }, + { "id": 5, "title": "Digital Product Showcase", "category": "Showcase", "excerpt": "A curation of sleek web interfaces, user-centric mobile applications, and custom enterprise portals designed by our UI/UX experts.", "image": "https://images.unsplash.com/photo-1507238691740-187a5b1d37b8?auto=format&fit=crop&w=800&q=80", "readTime": "7 Min Read" }, + { "id": 6, "title": "Innovation Lab", "category": "Innovation", "excerpt": "Step inside our workshop where we prototype Agentic AI, smart hardware sensors, and computer vision systems for next-generation industries.", "image": "https://images.unsplash.com/photo-1485827404703-89b55fcc595e?auto=format&fit=crop&w=800&q=80", "readTime": "12 Min Read" } + ] + }, + "products": { + "eyebrow": "Our Products Suite", + "title": "Powering Digital Growth", + "subtitle": "Powerful products built to simplify operations, improve visibility, and accelerate digital growth.", + "items": [ + { + "name": "Prodmax", + "description": "AI-powered Industrial IoT platform for smart manufacturing delivering real-time monitoring, advanced analytics, traceability, and operational intelligence.", + "image": "/assets/prodmax_dashboard.png", + "stats": [ + { "value": "5%+", "label": "OEE Improvement" }, + { "value": "15%", "label": "Reduction in Downtime" } + ] + }, + { + "name": "EVIDO", + "description": "Intelligent audit management platform that standardizes inspections, automates issue tracking, and provides complete operational visibility.", + "image": "/assets/evido_dashboard.png", + "stats": [ + { "value": "60%", "label": "Faster Process Automation" }, + { "value": "24/7", "label": "AI Driven Assistance" } + ] + }, + { + "name": "Budgie - HRMS", + "description": "Modern workforce management platform that simplifies employee operations, boosts engagement, and streamlines organizational processes.", + "image": "/assets/budgie_dashboard.png", + "stats": [ + { "value": "40%", "label": "HR Operations Efficiency" }, + { "value": "99.8%", "label": "Payroll Accuracy" } + ] + } + ] + }, + "insights": { + "title": "Explore the Latest in Technology & Innovation", + "subtitle": "Stay ahead with insights, stories, and updates on digital transformation, AI, automation, product design, and enterprise technology.", + "items": [ + { "category": "AI & Analytics", "title": "How AI is Reshaping Enterprise Decision Making", "date": "June 15, 2026", "image": "https://images.unsplash.com/photo-1620712943543-bcc4688e7485?auto=format&fit=crop&w=800&q=80", "excerpt": "Explore how deep learning models and agentic decision trees are replacing traditional business intelligence systems to drive proactive operations." }, + { "category": "Digital Strategy", "title": "Why Digital Transformation Needs More Than Technology", "date": "June 02, 2026", "image": "https://images.unsplash.com/photo-1519389950473-47ba0277781c?auto=format&fit=crop&w=800&q=80", "excerpt": "Technology is only half the battle. True organizational agility requires architectural alignment, structural changes, and cultural evolution." }, + { "category": "Product Design", "title": "Designing Enterprise Software Users Actually Love", "date": "May 18, 2026", "image": "https://images.unsplash.com/photo-1586717791821-3f44a563fa4c?auto=format&fit=crop&w=800&q=80", "excerpt": "Applying consumer-grade user experience principles to complex B2B systems reduces training costs and accelerates daily workflows." }, + { "category": "Automation", "title": "The Future of Automation in Business Workflows", "date": "May 05, 2026", "image": "https://images.unsplash.com/photo-1485827404703-89b55fcc595e?auto=format&fit=crop&w=800&q=80", "excerpt": "From robotic process automation (RPA) to generative AI pipelines, learn how workflow automation is changing modern business scaling." }, + { "category": "Cloud Architecture", "title": "Building Scalable Cloud-Native Infrastructure for Enterprises", "date": "April 22, 2026", "image": "https://images.unsplash.com/photo-1544197150-b99a580bb7a8?auto=format&fit=crop&w=800&q=80", "excerpt": "Microservices, Kubernetes, and serverless patterns are redefining how large-scale enterprise systems handle performance at unpredictable loads." }, + { "category": "Cybersecurity", "title": "Zero Trust Security Models in the Age of Remote Work", "date": "April 08, 2026", "image": "https://images.unsplash.com/photo-1563986768494-4dee2763ff3f?auto=format&fit=crop&w=800&q=80", "excerpt": "As perimeter-based security crumbles, zero trust frameworks enforce identity verification at every layer — from endpoint to data center." }, + { "category": "Data Engineering", "title": "Real-Time Data Pipelines That Power Smarter Decisions", "date": "March 25, 2026", "image": "https://images.unsplash.com/photo-1551288049-bebda4e38f71?auto=format&fit=crop&w=800&q=80", "excerpt": "Event-driven architectures and streaming platforms like Apache Kafka enable organizations to act on data the moment it is generated." } + ] + }, + "footer": { + "cta": { + "headline": "Ready to Accelerate Your Digital Transformation Journey?", + "body": "Whether you're exploring AI solutions, smart manufacturing, enterprise software, immersive technologies, or full-scale digital transformation, our experts are ready to help you build scalable solutions that deliver real business outcomes.", + "image": "/assets/Footer CTA Section.png", + "primaryButton": "Schedule a Consultation", + "secondaryButton": "Request a Product Demo" + }, + "quickLinks": [ + { "label": "Home", "href": "#home" }, + { "label": "About Us", "href": "#certifications" }, + { "label": "Our Services", "href": "#services" } + ], + "productLinks": [ + { "label": "PRODMAX", "href": "#products" }, + { "label": "Budgie HRMS", "href": "#products" }, + { "label": "EVIDO", "href": "#products" } + ], + "social": [ + { "platform": "Facebook", "url": "#" }, + { "platform": "Instagram", "url": "#" }, + { "platform": "LinkedIn", "url": "#" }, + { "platform": "Telegram", "url": "#" }, + { "platform": "WhatsApp", "url": "#" }, + { "platform": "X", "url": "#" }, + { "platform": "YouTube", "url": "#" } + ], + "legal": [ + { "label": "Privacy Policy", "href": "#" }, + { "label": "Terms & Conditions", "href": "#" } + ] + } +} diff --git a/src/App.css b/src/App.css new file mode 100644 index 0000000..f90339d --- /dev/null +++ b/src/App.css @@ -0,0 +1,184 @@ +.counter { + font-size: 16px; + padding: 5px 10px; + border-radius: 5px; + color: var(--accent); + background: var(--accent-bg); + border: 2px solid transparent; + transition: border-color 0.3s; + margin-bottom: 24px; + + &:hover { + border-color: var(--accent-border); + } + &:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } +} + +.hero { + position: relative; + + .base, + .framework, + .vite { + inset-inline: 0; + margin: 0 auto; + } + + .base { + width: 170px; + position: relative; + z-index: 0; + } + + .framework, + .vite { + position: absolute; + } + + .framework { + z-index: 1; + top: 34px; + height: 28px; + transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg) + scale(1.4); + } + + .vite { + z-index: 0; + top: 107px; + height: 26px; + width: auto; + transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg) + scale(0.8); + } +} + +#center { + display: flex; + flex-direction: column; + gap: 25px; + place-content: center; + place-items: center; + flex-grow: 1; + + @media (max-width: 1024px) { + padding: 32px 20px 24px; + gap: 18px; + } +} + +#next-steps { + display: flex; + border-top: 1px solid var(--border); + text-align: left; + + & > div { + flex: 1 1 0; + padding: 32px; + @media (max-width: 1024px) { + padding: 24px 20px; + } + } + + .icon { + margin-bottom: 16px; + width: 22px; + height: 22px; + } + + @media (max-width: 1024px) { + flex-direction: column; + text-align: center; + } +} + +#docs { + border-right: 1px solid var(--border); + + @media (max-width: 1024px) { + border-right: none; + border-bottom: 1px solid var(--border); + } +} + +#next-steps ul { + list-style: none; + padding: 0; + display: flex; + gap: 8px; + margin: 32px 0 0; + + .logo { + height: 18px; + } + + a { + color: var(--text-h); + font-size: 16px; + border-radius: 6px; + background: var(--social-bg); + display: flex; + padding: 6px 12px; + align-items: center; + gap: 8px; + text-decoration: none; + transition: box-shadow 0.3s; + + &:hover { + box-shadow: var(--shadow); + } + .button-icon { + height: 18px; + width: 18px; + } + } + + @media (max-width: 1024px) { + margin-top: 20px; + flex-wrap: wrap; + justify-content: center; + + li { + flex: 1 1 calc(50% - 8px); + } + + a { + width: 100%; + justify-content: center; + box-sizing: border-box; + } + } +} + +#spacer { + height: 88px; + border-top: 1px solid var(--border); + @media (max-width: 1024px) { + height: 48px; + } +} + +.ticks { + position: relative; + width: 100%; + + &::before, + &::after { + content: ''; + position: absolute; + top: -4.5px; + border: 5px solid transparent; + } + + &::before { + left: 0; + border-left-color: var(--border); + } + &::after { + right: 0; + border-right-color: var(--border); + } +} diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..3927614 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,2852 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { motion, useScroll, useTransform, useMotionValueEvent, useReducedMotion } from 'framer-motion'; +import { useContent } from './context/ContentContext'; +import { usePreviewMode } from './context/PreviewContext'; +import ServiceDial from './components/ServiceDial'; +import FeaturedGallery from './components/FeaturedGallery'; +import ProductCard from './components/ProductCard'; + +// Reusable Scroll Reveal Wrapper with Reduced Motion Support +function Reveal({ children, delay = 0, style }) { + const shouldReduceMotion = useReducedMotion(); + const previewMode = usePreviewMode(); + if (shouldReduceMotion && !previewMode) return
{children}
; + return ( + + {children} + + ); +} +import { + ArrowRight, + Sparkles, + Database, + Cpu, + LineChart, + Layers, + Activity, + Settings, + Shield, + TrendingUp, + Globe, + ChevronRight, + ChevronLeft, + Mail, + CheckCircle, + Clock, + Compass, + Zap, + Layout, + ExternalLink, + ChevronDown, + BrainCircuit, + Factory, + Network, + UsersRound, + ShieldCheck, + Code2, + CloudCog, + Glasses, + Menu, + X +} from 'lucide-react'; + +const iconMap = { + BrainCircuit, + Factory, + Network, + UsersRound, + ShieldCheck, + Code2, + CloudCog, + Glasses, + Sparkles +}; + +// Reusable Orbital Logo Component for animated paths around header text +const OrbitalLogo = ({ src, alt, radiusX, radiusY, startAngle, duration, clockwise = true, size = 120 }) => { + const [position, setPosition] = useState({ x: 0, y: 0 }); + + useEffect(() => { + const speed = (2 * Math.PI) / (duration * 1000); // radians per millisecond + const direction = clockwise ? 1 : -1; + const startRad = (startAngle * Math.PI) / 180; + + let animFrame; + const update = () => { + const elapsed = performance.now(); + const angle = startRad + direction * speed * elapsed; + + const x = radiusX * Math.cos(angle); + const y = radiusY * Math.sin(angle); + + setPosition({ x, y }); + animFrame = requestAnimationFrame(update); + }; + + animFrame = requestAnimationFrame(update); + return () => cancelAnimationFrame(animFrame); + }, [radiusX, radiusY, startAngle, duration, clockwise]); + + return ( + + {alt} + + ); +}; + +function ServiceCard({ service, isMobile, index = 0 }) { + const IconComponent = iconMap[service.icon] || Sparkles; + const shouldReduceMotion = useReducedMotion(); + + const revealProps = shouldReduceMotion ? {} : { + initial: { opacity: 0, y: 40 }, + whileInView: { opacity: 1, y: 0 }, + viewport: { once: true, amount: 0.15 }, + transition: { + y: { type: 'tween', duration: 0.8, ease: [0.22, 1, 0.36, 1], delay: index * 0.1 }, + opacity: { duration: 0.8, ease: 'easeOut', delay: index * 0.1 } + } + }; + + return ( + + {/* Subtle bottom-right color mood radial gradient glow */} +
+ + {/* Background Watermark Number */} +
+ {service.number} +
+ +
+ {/* Title */} +

+ {service.title} +

+ + {/* Bold Statement with left border/line */} +
+
+

+ {service.boldStatement} +

+
+ + {/* Description */} +

+ {service.description} +

+ + {/* Capabilities bullet list */} +
    + {service.capabilities.map((capability, idx) => ( +
  • + » + {capability} +
  • + ))} +
+
+ + {/* CTA link at bottom */} + + + ); +} + +export default function App({ previewMode = false }) { + const { content, loading } = useContent(); + const services = content.services?.items ?? []; + const insights = content.insights?.items ?? []; + const metrics = content.metrics ?? []; + const hero = content.hero ?? {}; + const about = content.about ?? {}; + const partners = content.partners ?? { logos: [] }; + const certifications = content.certifications ?? { items: [] }; + const whyUs = content.whyUs ?? { cards: [], images: [] }; + const products = content.products ?? { items: [] }; + const footer = content.footer ?? { cta: {}, quickLinks: [], productLinks: [], social: [], legal: [] }; + + // Tabs for Hero Section + const [activeHeroTab, setActiveHeroTab] = useState('agile'); + // Carousel slide for Products + const [activeProductIndex, setActiveProductIndex] = useState(0); + // Active detail index in Services Section + const [activeServiceIndex, setActiveServiceIndex] = useState(0); + const [isMobile, setIsMobile] = useState(false); + const [isCareersOpen, setIsCareersOpen] = useState(false); + const [activeSection, setActiveSection] = useState('home'); + const [hoveredItem, setHoveredItem] = useState(null); + const [showCareersAcknowledgement, setShowCareersAcknowledgement] = useState(false); + const [isStrategyOpen, setIsStrategyOpen] = useState(false); + const [showStrategyAcknowledgement, setShowStrategyAcknowledgement] = useState(false); + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + + // Careers Form Fields + const [careersName, setCareersName] = useState(''); + const [careersEmail, setCareersEmail] = useState(''); + const [careersPhone, setCareersPhone] = useState(''); + const [careersFile, setCareersFile] = useState(null); + + // Strategy Form Fields + const [strategyName, setStrategyName] = useState(''); + const [strategyEmail, setStrategyEmail] = useState(''); + const [strategyMobile, setStrategyMobile] = useState(''); + const [strategyDesignation, setStrategyDesignation] = useState(''); + const [strategyDateTime, setStrategyDateTime] = useState(''); + const [strategyInterests, setStrategyInterests] = useState({ + 'AI & Analytics': false, + 'SAP Services': false, + 'XR Platforms': false, + 'Smart Factory': false, + 'Cloud Engineering': false, + 'Enterprise Software': false, + }); + useEffect(() => { + const checkMobile = () => { + setIsMobile(window.innerWidth < 1024); + }; + checkMobile(); + window.addEventListener('resize', checkMobile); + return () => window.removeEventListener('resize', checkMobile); + }, []); + + const [flippingLogo, setFlippingLogo] = useState(null); + + useEffect(() => { + const triggerRandomFlip = () => { + const logoNumbers = [27, 28, 30, 31, 32, 33, 34, 35, 36]; + const randomNum = logoNumbers[Math.floor(Math.random() * logoNumbers.length)]; + setFlippingLogo(randomNum); + + // Clear flip after animation completes + setTimeout(() => { + setFlippingLogo(null); + }, 1000); + }; + + // Trigger random flip every 3.5 seconds + const interval = setInterval(triggerRandomFlip, 3500); + return () => clearInterval(interval); + }, []); + + useEffect(() => { + if (previewMode) return; + + const handleScroll = () => { + const sections = ['home', 'aboutus', 'services', 'whyus', 'products', 'insights', 'contactus']; + const scrollPosition = window.scrollY + 120; // 120px offset for header height and visual center + + // Special case: if at the very bottom of the page, contactus is active + if (window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 50) { + setActiveSection('contactus'); + return; + } + + for (const sectionId of sections) { + const el = document.getElementById(sectionId); + if (el) { + const top = el.offsetTop; + const height = el.offsetHeight; + if (scrollPosition >= top && scrollPosition < top + height) { + setActiveSection(sectionId); + break; + } + } + } + }; + + window.addEventListener('scroll', handleScroll); + handleScroll(); // run once on mount + return () => window.removeEventListener('scroll', handleScroll); + }, [previewMode]); + + const getActiveNavItem = () => { + switch (activeSection) { + case 'home': + return 'Home'; + case 'aboutus': + case 'services': + case 'whyus': + return 'About Us'; + case 'products': + case 'insights': + return 'Products'; + case 'contactus': + return 'Contact Us'; + default: + return 'Home'; + } + }; + + const servicesScrollRef = useRef(null); + + const scrollServices = (direction) => { + if (servicesScrollRef.current) { + const scrollAmount = isMobile ? 310 : 444; // card width + gap + servicesScrollRef.current.scrollBy({ + left: direction === 'left' ? -scrollAmount : scrollAmount, + behavior: 'smooth' + }); + } + }; + + // Carousel for Insights + const [insightIndex, setInsightIndex] = useState(0); + const blogCarouselRef = useRef(null); + + const scrollBlogCarousel = (dir) => { + if (blogCarouselRef.current) { + const cardWidth = (isMobile ? window.innerWidth * 0.72 : 340) + 24; + blogCarouselRef.current.scrollBy({ left: dir * cardWidth, behavior: 'smooth' }); + } + }; + + const sectionX = isMobile ? '1.25rem' : '8%'; + const navItems = ['Home', 'About Us', 'Products', 'Careers', 'Contact Us']; + const NAV_OFFSET = isMobile ? 72 : 88; + + const scrollToSection = (sectionId) => { + if (sectionId === 'contactus') { + const footer = document.getElementById('contactus'); + if (footer) { + const top = footer.getBoundingClientRect().top + window.scrollY - NAV_OFFSET; + window.scrollTo({ top: Math.max(0, top), behavior: 'smooth' }); + } else { + window.scrollTo({ top: document.documentElement.scrollHeight, behavior: 'smooth' }); + } + setActiveSection('contactus'); + return; + } + + const el = document.getElementById(sectionId); + if (!el) return; + const top = el.getBoundingClientRect().top + window.scrollY - NAV_OFFSET; + window.scrollTo({ top: Math.max(0, top), behavior: 'smooth' }); + setActiveSection(sectionId); + }; + + const handleNavClick = (item) => { + setMobileMenuOpen(false); + if (item === 'Careers') { + setIsCareersOpen(true); + return; + } + const sectionMap = { + Home: 'home', + 'About Us': 'aboutus', + Products: 'products', + 'Contact Us': 'contactus', + }; + const id = sectionMap[item]; + if (!id) return; + setTimeout(() => scrollToSection(id), isMobile ? 150 : 0); + }; + + useEffect(() => { + document.body.style.overflow = mobileMenuOpen ? 'hidden' : ''; + return () => { document.body.style.overflow = ''; }; + }, [mobileMenuOpen]); + + const heroTabs = [ + { id: 'agile', label: 'Agile Dev' }, + { id: 'fullstack', label: 'Full-Stack Tech' }, + { id: 'ai', label: 'AI & Analytics' }, + { id: 'devops', label: 'DevOps' } + ]; + + // Dummy contents for Hero tabs to make it feel alive + const heroTabContent = { + agile: { title: 'Rapid Iterative Delivery', desc: 'Accelerating release cycles through agile management and continuous deployment pipelines.' }, + fullstack: { title: 'Modern Core Architectures', desc: 'Scalable frontend, backend, and database infrastructures designed for ultimate reliability.' }, + ai: { title: 'Intelligent Automation', desc: 'Harnessing ML and LLM integrations to optimize workflows and drive business intelligence.' }, + devops: { title: 'Automated Operations', desc: 'Secure cloud hosting, zero-downtime deployments, and real-time environment monitoring.' } + }; + + const clients = [ + { name: 'TVS', logo: 'TVS' }, + { name: 'Hero', logo: 'Hero' }, + { name: 'V-Guard', logo: 'V-Guard' }, + { name: 'Muthoot', logo: 'Muthoot' }, + { name: 'MRF', logo: 'MRF' }, + { name: 'HDFC', logo: 'HDFC' } + ]; + + const whyChooseUs = [ + { + title: 'Innovation Driven', + desc: 'Integrating state-of-the-art technologies and custom automation architectures into your core workflows to future-proof business value.', + icon: + }, + { + title: 'Industry Expertise', + desc: 'Deep industry knowledge spanning insurance, fintech, operations, logistics, and highly regulated enterprise application suites.', + icon: + }, + { + title: 'Outcome Focused', + desc: 'Committed to delivering measurable business impact, reduced infrastructure overhead, and highly optimized operational metrics.', + icon: + }, + { + title: 'Customer Centric', + desc: 'Collaborating hand-in-hand to build solutions tailored specifically to your unique workflow demands, users, and scaling plans.', + icon: + } + ]; + + if (loading) { + return ( +
+ Loading... +
+ ); + } + + return ( +
+ + {/* Main Content Wrapper with solid background and higher z-index */} +
+ + {/* Background Glows */} +
+
+
+ + {/* Navigation Bar */} + + + {isMobile && mobileMenuOpen && ( +
setMobileMenuOpen(false)} + style={{ + position: 'fixed', + inset: 0, + background: 'rgba(2, 7, 16, 0.75)', + backdropFilter: 'blur(6px)', + zIndex: 60, + display: 'flex', + justifyContent: 'flex-end', + }} + > +
e.stopPropagation()} + style={{ + width: 'min(85vw, 320px)', + height: '100%', + background: '#0a1628', + borderLeft: '1px solid rgba(255,255,255,0.08)', + padding: '1.5rem 1.25rem', + display: 'flex', + flexDirection: 'column', + gap: '0.25rem', + }} + > + {navItems.map((item) => ( + + ))} + +
+
+ )} + + {/* Hero Section */} +
+ {/* Background Video */} + + + + + +
+ + {hero.badge} + +
+ +

+ {hero.headline} + {hero.subheadline?.includes('Technology Partner') ? ( + <>{hero.subheadline.replace('Technology Partner', '').trim()} Technology Partner + ) : hero.subheadline} +

+
+
+ + + {/* Metrics Section */} +
+ {/* Statistics Panel */} + +
+ {/* Metrics from CMS */} + {metrics.map((metric, idx) => ( + + {idx > 0 && !isMobile &&
} +
+
+ {[, , , ][idx % 4]} +
+
+ {metric.value} + {metric.label} +
+
+ + ))} +
+ +
+ + {/* Frost & Sullivan Alliance Section */} +
+ + {/* Subtle center spotlight lighting effect behind badge */} +
+ +

+ {about.heading} +

+ + {/* Frost & Sullivan Badge container */} +
+ {about.badgeAlt} +
+ +
+ + + {/* Redesigned Trusted Brands Section */} +
+ {/* Subtle grid background */} +
+ + {/* Ambient Glows */} +
+ + + {isMobile ? ( + /* Mobile Layout: Clean vertical hierarchy */ +
+
+

+ {partners.heading} +

+

+ {partners.subheading} +

+

+ {partners.body} +

+
+ + {/* Globe Visual */} +
+ Globe Map +
+ + {/* Grid of Logos */} +
+ {partners.logos.map((logo, idx) => ( +
+ {logo.name} +
+ ))} +
+
+ ) : ( + /* Desktop Layout: Orbital Globe Layout as per reference image */ +
+ + {/* Globe in background - Increased Size & Brightness */} + Globe Map + + {/* Center Text Panel */} +
+

+ {partners.heading} +

+ + {partners.subheading} + +

+ {partners.body} +

+
+ + {/* orbital logos with smooth continuous motion in horizontally elongated oval paths - No Skewing */} + {/* Outer Orbit - Increased size further to radiusX=520, radiusY=320 */} + + + + + + + {/* Inner Orbit - Adjusted size to radiusX=360, radiusY=225 */} + + + + + + +
+ )} +
+
+ + + {/* Certifications Section */} +
+ +

+ {certifications.heading} +

+
+ +
+ {certifications.items.map((cert, idx) => ( + +
+ {cert.alt} +
+
+ ))} +
+
+ {/* Services Section */} +
+ {/* Background Ambient Glows */} +
+
+ +
+ {/* Left Column - Intro Panel */} + +
+ + {content.services.eyebrow} + +

+ {content.services.title} +

+

+ {content.services.intro} +

+
+ + {/* Navigation buttons at the bottom */} +
+ + +
+
+ + {/* Right Column - Horizontal scroll container */} +
+ +
+ {services.map((service, index) => ( + + ))} +
+
+
+
+
+ + {/* Why Cavin Infotech Section */} + {/* Why Cavin Infotech Section */} +
+
+
+ + {whyUs.eyebrow} +

{whyUs.title}

+
+
+ + {isMobile ? ( +
+ {/* Innovation Driven */} + +
+

Innovation Driven

+
+

+ We deliver future-ready solutions powered by Gen AI, Agentic AI, automation, IoT, and emerging tech that keep you ahead of the curve. +

+
+ + + {/* Industry Expertise */} + +
+

Industry Expertise

+
+

+ Deep domain knowledge across manufacturing, enterprise tech, smart manufacturing, and digital operations built from years of real-world implementation. +

+
+ + + {/* Secure & Reliable */} + +
+

Secure & Reliable

+
+

+ Every solution is built on globally recognized standards with uncompromising focus on security, compliance, and operational excellence. +

+
+ + + {/* Outcome Focused */} + +
+

Outcome Focused

+
+

+ We don't just implement technology we design every solution to reduce complexity, boost efficiency, and deliver clear, measurable business impact. +

+
+ +
+ ) : ( +
+ {/* Innovation Driven Card (Col 1, Row 1) */} + +
+ {/* Concentric rings */} +
+
+ +

+ Innovation Driven +

+
+

+ We deliver future-ready solutions powered by Gen AI, Agentic AI, automation, IoT, and emerging tech that keep you ahead of the curve. +

+
+ + + {/* Collaboration Image (Col 1, Row 2) */} + +
+ Corporate collaboration +
+
+ + {/* Industry Expertise Card (Col 2 & 3, Row 1) */} + +
+
+
+ +

+ Industry Expertise +

+
+

+ Deep domain knowledge across manufacturing, enterprise tech, smart manufacturing, and digital operations built from years of real-world implementation. +

+
+ + + {/* Secure & Reliable Card (Col 2, Row 2) */} + +
+
+
+ +

+ Secure & Reliable +

+
+

+ Every solution is built on globally recognized standards with uncompromising focus on security, compliance, and operational excellence. +

+
+ + + {/* Conference Room Image (Col 3, Row 2) */} + +
+ Sunset boardroom +
+
+ + {/* Outcome Focused Tall Card (Col 4, Row 1/2) */} + +
+
+

+ Outcome Focused +

+
+

+ We don't just implement technology we design every solution to reduce complexity, boost efficiency, and deliver clear, measurable business impact. +

+
+
{/* Flex spacer to push text up and reveal team background */} +
+ +
+ )} +
+
+ + {/* Featured Gallery Section */} + + + + + {/* Products Suite */} +
+ {/* Header */} + +
+ + {products.eyebrow} + +

+ {products.title} +

+

+ {products.subtitle} +

+
+
+ + {/* Product Cards Grid */} +
+ {products.items.map((item, index) => ( + + ))} +
+
+ + {/* Insights Section */} +
+ {/* Header */} + +
+

+ {content.insights.title} +

+

+ {content.insights.subtitle} +

+
+ + {/* Nav Arrows */} +
+ + +
+
+ + {/* Carousel Container */} + +
+ {insights.map((insight, idx) => ( + +
{ + e.currentTarget.style.borderColor = 'rgba(255,170,0,0.35)'; + e.currentTarget.style.boxShadow = '0 16px 48px rgba(255,170,0,0.12)'; + e.currentTarget.style.transform = 'translateY(-5px)'; + }} + onMouseLeave={e => { + e.currentTarget.style.borderColor = 'rgba(255,255,255,0.08)'; + e.currentTarget.style.boxShadow = '0 4px 30px rgba(0,0,0,0.5)'; + e.currentTarget.style.transform = 'translateY(0)'; + }} + > + {/* Full-bleed image */} + {insight.title} + + {/* Subtle top gradient so image top isn't too harsh */} +
+ + {/* Frosted glass panel — pinned to bottom */} +
+ {/* Category */} + + {insight.category} + + + {/* Title */} +

+ {insight.title} +

+ + {/* Read Blog */} +
+ Read Blog +
+
+
+ + ))} +
+
+
+ + {/* Brand Logo Divider Section */} +
+ Cavin Infotech Logo Divider +
+
{/* Close Content Wrapper */} + + + + {/* Careers Modal Popup */} + {isCareersOpen && !previewMode && ( +
+
+ + {/* Close Button */} + + + {!showCareersAcknowledgement ? ( +
{ + e.preventDefault(); + try { + const serviceId = import.meta.env.VITE_EMAILJS_SERVICE_ID || 'vishva_cavintest'; + const publicKey = import.meta.env.VITE_EMAILJS_PUBLIC_KEY || 'YOUR_EMAILJS_PUBLIC_KEY'; + const templateId = import.meta.env.VITE_EMAILJS_TEMPLATE_ID_CAREERS || 'YOUR_EMAILJS_TEMPLATE_ID_CAREERS'; + + if (publicKey === 'YOUR_EMAILJS_PUBLIC_KEY' || templateId === 'YOUR_EMAILJS_TEMPLATE_ID_CAREERS') { + console.warn('EmailJS Credentials not configured in .env. Please configure VITE_EMAILJS_PUBLIC_KEY and VITE_EMAILJS_TEMPLATE_ID_CAREERS'); + alert('EmailJS credentials are not configured in your .env file.'); + return; + } + + const res = await fetch('https://api.emailjs.com/api/v1.0/email/send', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + service_id: serviceId, + template_id: templateId, + user_id: publicKey, + template_params: { + type: 'careers', + name: careersName, + email: careersEmail, + phone: careersPhone, + mobile: '', + designation: 'N/A', + dateTime: 'N/A', + interests: 'N/A', + resumeName: careersFile ? careersFile.name : 'None', + from_name: careersName, + reply_to: careersEmail, + message: `New Careers Application:\nName: ${careersName}\nEmail: ${careersEmail}\nPhone: ${careersPhone}\nResume File: ${careersFile ? careersFile.name : 'None'}` + } + }) + }); + + if (!res.ok) { + const errMsg = await res.text(); + console.error('EmailJS Error:', errMsg); + alert(`Failed to send email: ${errMsg}`); + return; + } + + setShowCareersAcknowledgement(true); + } catch (err) { + console.error('Error sending application:', err); + alert(`Error sending application: ${err.message}`); + } + }}> +

+ Join Our Team +

+

+ Submit your details and resume below. Our recruitment team will review your application. +

+ +
+ {/* Name Input */} +
+ + setCareersName(e.target.value)} + placeholder="John Doe" + style={{ + background: 'rgba(255, 255, 255, 0.03)', + border: '1px solid rgba(255, 255, 255, 0.08)', + borderRadius: '8px', + padding: '0.75rem 1rem', + color: '#ffffff', + fontSize: '0.9rem', + outline: 'none', + transition: 'all 0.3s ease', + }} + onFocus={e => { + e.currentTarget.style.borderColor = '#ffaa00'; + e.currentTarget.style.boxShadow = '0 0 10px rgba(255, 170, 0, 0.15)'; + }} + onBlur={e => { + e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.08)'; + e.currentTarget.style.boxShadow = 'none'; + }} + /> +
+ + {/* Email Input */} +
+ + setCareersEmail(e.target.value)} + placeholder="john@example.com" + style={{ + background: 'rgba(255, 255, 255, 0.03)', + border: '1px solid rgba(255, 255, 255, 0.08)', + borderRadius: '8px', + padding: '0.75rem 1rem', + color: '#ffffff', + fontSize: '0.9rem', + outline: 'none', + transition: 'all 0.3s ease', + }} + onFocus={e => { + e.currentTarget.style.borderColor = '#ffaa00'; + e.currentTarget.style.boxShadow = '0 0 10px rgba(255, 170, 0, 0.15)'; + }} + onBlur={e => { + e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.08)'; + e.currentTarget.style.boxShadow = 'none'; + }} + /> +
+ + {/* Phone Input */} +
+ + setCareersPhone(e.target.value)} + placeholder="+91 00000 00000" + style={{ + background: 'rgba(255, 255, 255, 0.03)', + border: '1px solid rgba(255, 255, 255, 0.08)', + borderRadius: '8px', + padding: '0.75rem 1rem', + color: '#ffffff', + fontSize: '0.9rem', + outline: 'none', + transition: 'all 0.3s ease', + }} + onFocus={e => { + e.currentTarget.style.borderColor = '#ffaa00'; + e.currentTarget.style.boxShadow = '0 0 10px rgba(255, 170, 0, 0.15)'; + }} + onBlur={e => { + e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.08)'; + e.currentTarget.style.boxShadow = 'none'; + }} + /> +
+ + {/* File Attachment Input */} +
+ +
{ + e.currentTarget.style.borderColor = '#ffaa00'; + e.currentTarget.style.background = 'rgba(255, 170, 0, 0.05)'; + }} + onMouseLeave={e => { + e.currentTarget.style.borderColor = 'rgba(255, 170, 0, 0.3)'; + e.currentTarget.style.background = 'rgba(255, 170, 0, 0.02)'; + }} + > + { + const file = e.target.files[0]; + setCareersFile(file); + const fileName = file?.name; + const labelEl = document.getElementById('file-upload-label'); + if (labelEl && fileName) { + labelEl.textContent = fileName; + } + }} + /> + + Click to upload your Resume (.pdf, .doc, .docx) + +
+
+
+ + {/* Submit Button */} + +
+ ) : ( + /* Acknowledgement Panel */ +
+
+ + + +
+

+ Application Received! +

+

+ Thank you for applying to Cavin Infotech. We have received your resume and details successfully. Our recruitment team will review your application and contact you if your qualifications match our current needs. +

+ +
+ )} +
+
+ )} + + {/* Book a Strategy Call Modal Popup */} + {isStrategyOpen && !previewMode && ( +
+
+ + {/* Close Button */} + + + {!showStrategyAcknowledgement ? ( +
{ + e.preventDefault(); + const selectedInterests = Object.keys(strategyInterests).filter(key => strategyInterests[key]).join(', '); + try { + const serviceId = import.meta.env.VITE_EMAILJS_SERVICE_ID || 'vishva_cavintest'; + const publicKey = import.meta.env.VITE_EMAILJS_PUBLIC_KEY || 'YOUR_EMAILJS_PUBLIC_KEY'; + const templateId = import.meta.env.VITE_EMAILJS_TEMPLATE_ID_STRATEGY || 'YOUR_EMAILJS_TEMPLATE_ID_STRATEGY'; + + if (publicKey === 'YOUR_EMAILJS_PUBLIC_KEY' || templateId === 'YOUR_EMAILJS_TEMPLATE_ID_STRATEGY') { + console.warn('EmailJS Credentials not configured in .env. Please configure VITE_EMAILJS_PUBLIC_KEY and VITE_EMAILJS_TEMPLATE_ID_STRATEGY'); + alert('EmailJS credentials are not configured in your .env file.'); + return; + } + + const res = await fetch('https://api.emailjs.com/api/v1.0/email/send', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + service_id: serviceId, + template_id: templateId, + user_id: publicKey, + template_params: { + type: 'strategy', + name: strategyName, + email: strategyEmail, + phone: strategyMobile, + mobile: strategyMobile, + designation: strategyDesignation, + dateTime: strategyDateTime, + interests: selectedInterests || 'None', + resumeName: 'None', + from_name: strategyName, + reply_to: strategyEmail, + message: `New Strategy Session Booking:\nName: ${strategyName}\nEmail: ${strategyEmail}\nMobile: ${strategyMobile}\nDesignation: ${strategyDesignation}\nPreferred Date & Time: ${strategyDateTime}\nAreas of Interest: ${selectedInterests || 'None'}` + } + }) + }); + + if (!res.ok) { + const errMsg = await res.text(); + console.error('EmailJS Error:', errMsg); + alert(`Failed to send email: ${errMsg}`); + return; + } + + setShowStrategyAcknowledgement(true); + } catch (err) { + console.error('Error scheduling strategy session:', err); + alert(`Error scheduling strategy session: ${err.message}`); + } + }}> +

+ Book a Strategy Call +

+

+ Fill in the details below to schedule a session with our experts. +

+ +
+ {/* Name Input */} +
+ + setStrategyName(e.target.value)} + placeholder="John Doe" + style={{ + background: 'rgba(255, 255, 255, 0.03)', + border: '1px solid rgba(255, 255, 255, 0.08)', + borderRadius: '8px', + padding: '0.7rem 0.9rem', + color: '#ffffff', + fontSize: '0.88rem', + outline: 'none', + transition: 'all 0.3s ease', + }} + onFocus={e => { + e.currentTarget.style.borderColor = '#ffaa00'; + e.currentTarget.style.boxShadow = '0 0 10px rgba(255, 170, 0, 0.15)'; + }} + onBlur={e => { + e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.08)'; + e.currentTarget.style.boxShadow = 'none'; + }} + /> +
+ + {/* Email Input */} +
+ + setStrategyEmail(e.target.value)} + placeholder="john@example.com" + style={{ + background: 'rgba(255, 255, 255, 0.03)', + border: '1px solid rgba(255, 255, 255, 0.08)', + borderRadius: '8px', + padding: '0.7rem 0.9rem', + color: '#ffffff', + fontSize: '0.88rem', + outline: 'none', + transition: 'all 0.3s ease', + }} + onFocus={e => { + e.currentTarget.style.borderColor = '#ffaa00'; + e.currentTarget.style.boxShadow = '0 0 10px rgba(255, 170, 0, 0.15)'; + }} + onBlur={e => { + e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.08)'; + e.currentTarget.style.boxShadow = 'none'; + }} + /> +
+ + {/* Mobile Input */} +
+ + setStrategyMobile(e.target.value)} + placeholder="+91 00000 00000" + style={{ + background: 'rgba(255, 255, 255, 0.03)', + border: '1px solid rgba(255, 255, 255, 0.08)', + borderRadius: '8px', + padding: '0.7rem 0.9rem', + color: '#ffffff', + fontSize: '0.88rem', + outline: 'none', + transition: 'all 0.3s ease', + }} + onFocus={e => { + e.currentTarget.style.borderColor = '#ffaa00'; + e.currentTarget.style.boxShadow = '0 0 10px rgba(255, 170, 0, 0.15)'; + }} + onBlur={e => { + e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.08)'; + e.currentTarget.style.boxShadow = 'none'; + }} + /> +
+ + {/* Designation Input */} +
+ + setStrategyDesignation(e.target.value)} + placeholder="e.g. Chief Technology Officer" + style={{ + background: 'rgba(255, 255, 255, 0.03)', + border: '1px solid rgba(255, 255, 255, 0.08)', + borderRadius: '8px', + padding: '0.7rem 0.9rem', + color: '#ffffff', + fontSize: '0.88rem', + outline: 'none', + transition: 'all 0.3s ease', + }} + onFocus={e => { + e.currentTarget.style.borderColor = '#ffaa00'; + e.currentTarget.style.boxShadow = '0 0 10px rgba(255, 170, 0, 0.15)'; + }} + onBlur={e => { + e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.08)'; + e.currentTarget.style.boxShadow = 'none'; + }} + /> +
+ + {/* Preferred Date & Time Input */} +
+ + setStrategyDateTime(e.target.value)} + style={{ + background: 'rgba(255, 255, 255, 0.03)', + border: '1px solid rgba(255, 255, 255, 0.08)', + borderRadius: '8px', + padding: '0.7rem 0.9rem', + color: '#ffffff', + fontSize: '0.88rem', + outline: 'none', + transition: 'all 0.3s ease', + }} + onFocus={e => { + e.currentTarget.style.borderColor = '#ffaa00'; + e.currentTarget.style.boxShadow = '0 0 10px rgba(255, 170, 0, 0.15)'; + }} + onBlur={e => { + e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.08)'; + e.currentTarget.style.boxShadow = 'none'; + }} + /> +
+ + {/* Areas of Interest Checkboxes */} +
+ +
+ {[ + 'AI & Analytics', + 'SAP Services', + 'XR Platforms', + 'Smart Factory', + 'Cloud Engineering', + 'Enterprise Software' + ].map((interest) => ( + + ))} +
+
+
+ + {/* Submit Button */} + +
+ ) : ( + /* Acknowledgement Panel */ +
+
+ + + +
+

+ Strategy Session Scheduled! +

+

+ Thank you for booking a Strategy Call. We have successfully received your information and areas of interest. A technology consultant from Cavin Infotech will reach out to you within 24 hours with an invitation link and slot confirmation. +

+ +
+ )} +
+
+ )} +
+ ); +} diff --git a/src/admin/App.jsx b/src/admin/App.jsx new file mode 100644 index 0000000..5b1ce68 --- /dev/null +++ b/src/admin/App.jsx @@ -0,0 +1,624 @@ +import { useEffect, useRef, useState, Component } from 'react'; +import { + LayoutDashboard, + Sparkles, + Building2, + Award, + Layers, + Target, + Images, + Package, + FileText, + Link2, + Settings, + LogOut, + ExternalLink, + Save, + Menu, + X, + CheckCircle2, + AlertCircle, + Clock, +} from 'lucide-react'; +import { adminApi, getToken, setToken, clearToken } from './api'; +import { Field, ImageUpload, ArrayEditor } from './components/FormFields'; +import { SectionPreview } from './components/SectionPreview'; +import { pickSectionData } from './contentHelpers'; +import defaultContent from '../../server/seed/default-content.json'; + +const NAV_GROUPS = [ + { + label: 'Overview', + items: [ + { id: 'dashboard', label: 'Dashboard', icon: LayoutDashboard, desc: 'Overview and quick access to all sections' }, + ], + }, + { + label: 'Page Content', + items: [ + { id: 'hero', label: 'Hero & Metrics', icon: Sparkles, desc: 'Homepage headline, video, and statistics' }, + { id: 'about', label: 'About & Partners', icon: Building2, desc: 'About section and partner logos' }, + { id: 'certifications', label: 'Certifications', icon: Award, desc: 'Certification badges and headings' }, + { id: 'services', label: 'Services', icon: Layers, desc: 'Service cards and section copy' }, + { id: 'whyUs', label: 'Why Us', icon: Target, desc: 'Value propositions and images' }, + { id: 'gallery', label: 'Gallery', icon: Images, desc: 'Featured case studies and gallery items' }, + { id: 'products', label: 'Products', icon: Package, desc: 'Product suite cards and stats' }, + { id: 'insights', label: 'Insights', icon: FileText, desc: 'Blog and insight carousel items' }, + { id: 'footer', label: 'Footer & Links', icon: Link2, desc: 'CTA, social links, and footer navigation' }, + ], + }, + { + label: 'Account', + items: [ + { id: 'settings', label: 'Settings', icon: Settings, desc: 'Password and account preferences' }, + ], + }, +]; + +const ALL_SECTIONS = NAV_GROUPS.flatMap((g) => g.items); + +const SECTION_DESCRIPTIONS = Object.fromEntries(ALL_SECTIONS.map((s) => [s.id, s.desc])); + +function Toast({ message, type }) { + if (!message) return null; + return ( +
+ {type === 'success' ? : } + {message} +
+ ); +} + +function LoginPreview() { + const viewportRef = useRef(null); + const [scale, setScale] = useState(0.5); + const previewWidth = 1280; + const previewHeight = 800; + + useEffect(() => { + const el = viewportRef.current; + if (!el) return; + + const updateScale = () => { + const nextScale = el.clientWidth / previewWidth; + setScale(nextScale); + }; + + updateScale(); + const observer = new ResizeObserver(updateScale); + observer.observe(el); + return () => observer.disconnect(); + }, []); + + return ( +
+
+ Cavin Infotech +
+

Content Manager

+

Preview the live website before you sign in. Edits publish instantly after login.

+
+ + + Open full site + +
+ +
+
+ + + + cavininfotech.com +
+
+
+