From 2cc7c52755f7f662ee2c6c22fe2c4a3594164251 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Sun, 16 Nov 2025 20:19:02 -0700 Subject: [PATCH] refactor: remove OddJS dependency and fix Automerge sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major Changes: - Fix Automerge "Document unavailable" error by awaiting repo.find() - Remove @oddjs/odd package and all related dependencies (205 packages) - Remove location sharing features (OddJS filesystem-dependent) - Simplify auth to use only CryptoAuthService (WebCryptoAPI-based) Auth System Changes: - Refactor AuthService to remove OddJS filesystem integration - Update AuthContext to remove FileSystem references - Delete unused auth files (account.ts, backup.ts, linking.ts) - Delete unused auth components (Register.tsx, LinkDevice.tsx) Location Features Removed: - Delete all location components and routes - Remove LocationShareShape from shape registry - Clean up location references across codebase Documentation Updates: - Update WEBCRYPTO_AUTH.md to remove OddJS references - Correct component names (CryptoLogin → CryptID) - Update file structure and dependencies - Fix Automerge README WebSocket path documentation Build System: - Successfully builds without OddJS dependencies - All TypeScript errors resolved - Production bundle size optimized 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/WEBCRYPTO_AUTH.md | 94 +- package-lock.json | 2535 +---------------- package.json | 1 - src/App.tsx | 20 - src/automerge/AutomergeToTLStore.ts | 2 +- src/automerge/README.md | 4 +- src/automerge/useAutomergeStoreV2.ts | 3 +- src/automerge/useAutomergeSyncRepo.ts | 13 +- src/components/auth/LinkDevice.tsx | 102 - src/components/auth/Register.tsx | 64 - src/components/location/LocationCapture.tsx | 187 -- src/components/location/LocationDashboard.tsx | 270 -- src/components/location/LocationMap.tsx | 241 -- .../location/LocationShareDialog.tsx | 45 - src/components/location/LocationViewer.tsx | 183 -- src/components/location/ShareLocation.tsx | 279 -- src/components/location/ShareSettings.tsx | 150 - src/context/AuthContext.tsx | 57 +- src/lib/auth/account.ts | 259 -- src/lib/auth/authService.ts | 275 +- src/lib/auth/backup.ts | 22 - src/lib/auth/linking.ts | 58 - src/lib/location/locationStorage.ts | 302 -- src/lib/location/types.ts | 55 - src/routes/Board.tsx | 3 +- src/routes/LocationDashboardRoute.tsx | 37 - src/routes/LocationShareCreate.tsx | 37 - src/routes/LocationShareView.tsx | 51 - src/shapes/LocationShareShapeUtil.tsx | 61 - src/types/odd.d.ts | 36 - src/ui/CustomMainMenu.tsx | 2 +- src/ui/CustomToolbar.tsx | 1 - src/utils/shapeCollisionUtils.ts | 4 +- 33 files changed, 143 insertions(+), 5310 deletions(-) delete mode 100644 src/components/auth/LinkDevice.tsx delete mode 100644 src/components/auth/Register.tsx delete mode 100644 src/components/location/LocationCapture.tsx delete mode 100644 src/components/location/LocationDashboard.tsx delete mode 100644 src/components/location/LocationMap.tsx delete mode 100644 src/components/location/LocationShareDialog.tsx delete mode 100644 src/components/location/LocationViewer.tsx delete mode 100644 src/components/location/ShareLocation.tsx delete mode 100644 src/components/location/ShareSettings.tsx delete mode 100644 src/lib/auth/account.ts delete mode 100644 src/lib/auth/backup.ts delete mode 100644 src/lib/auth/linking.ts delete mode 100644 src/lib/location/locationStorage.ts delete mode 100644 src/lib/location/types.ts delete mode 100644 src/routes/LocationDashboardRoute.tsx delete mode 100644 src/routes/LocationShareCreate.tsx delete mode 100644 src/routes/LocationShareView.tsx delete mode 100644 src/shapes/LocationShareShapeUtil.tsx delete mode 100644 src/types/odd.d.ts diff --git a/docs/WEBCRYPTO_AUTH.md b/docs/WEBCRYPTO_AUTH.md index c345b70..298cdf3 100644 --- a/docs/WEBCRYPTO_AUTH.md +++ b/docs/WEBCRYPTO_AUTH.md @@ -4,7 +4,7 @@ This document describes the complete WebCryptoAPI authentication system implemen ## Overview -The WebCryptoAPI authentication system provides cryptographic authentication using ECDSA P-256 key pairs, challenge-response authentication, and secure key storage. It integrates with the existing ODD (Open Data Directory) framework while providing a fallback authentication mechanism. +The WebCryptoAPI authentication system provides cryptographic authentication using ECDSA P-256 key pairs, challenge-response authentication, and secure key storage. This is the primary authentication mechanism for the application. ## Architecture @@ -23,13 +23,14 @@ The WebCryptoAPI authentication system provides cryptographic authentication usi - User registration and login - Credential verification -3. **Enhanced AuthService** (`src/lib/auth/authService.ts`) - - Integrates crypto authentication with ODD - - Fallback mechanisms +3. **AuthService** (`src/lib/auth/authService.ts`) + - Simplified authentication service - Session management + - Integration with CryptoAuthService 4. **UI Components** - - `CryptoLogin.tsx` - Cryptographic authentication UI + - `CryptID.tsx` - Cryptographic authentication UI + - `CryptoDebug.tsx` - Debug component for verification - `CryptoTest.tsx` - Test component for verification ## Features @@ -41,7 +42,6 @@ The WebCryptoAPI authentication system provides cryptographic authentication usi - **Public Key Infrastructure**: Store and verify public keys - **Browser Support Detection**: Checks for WebCryptoAPI availability - **Secure Context Validation**: Ensures HTTPS requirement -- **Fallback Authentication**: Works with existing ODD system - **Modern UI**: Responsive design with dark mode support - **Comprehensive Testing**: Test component for verification @@ -86,7 +86,7 @@ const isValid = await crypto.verifySignature(publicKey, signature, challenge); ### Feature Detection ```typescript -const hasWebCrypto = typeof window.crypto !== 'undefined' && +const hasWebCrypto = typeof window.crypto !== 'undefined' && typeof window.crypto.subtle !== 'undefined'; const isSecure = window.isSecureContext; ``` @@ -98,26 +98,26 @@ const isSecure = window.isSecureContext; 1. **Secure Context Requirement**: Only works over HTTPS 2. **ECDSA P-256**: Industry-standard elliptic curve 3. **Challenge-Response**: Prevents replay attacks -4. **Key Storage**: Public keys stored securely +4. **Key Storage**: Public keys stored securely in localStorage 5. **Input Validation**: Username format validation 6. **Error Handling**: Comprehensive error management ### ⚠️ Security Notes -1. **Private Key Storage**: Currently simplified for demo purposes - - In production, use Web Crypto API's key storage +1. **Private Key Storage**: Currently uses localStorage for demo purposes + - In production, consider using Web Crypto API's non-extractable keys - Consider hardware security modules (HSM) - Implement proper key derivation -2. **Session Management**: - - Integrates with existing ODD session system - - Consider implementing JWT tokens - - Add session expiration +2. **Session Management**: + - Uses localStorage for session persistence + - Consider implementing JWT tokens for server-side verification + - Add session expiration and refresh logic 3. **Network Security**: - All crypto operations happen client-side - No private keys transmitted over network - - Consider adding server-side verification + - Consider adding server-side signature verification ## Usage @@ -146,11 +146,22 @@ import { useAuth } from './context/AuthContext'; const { login, register } = useAuth(); -// The AuthService automatically tries crypto auth first, -// then falls back to ODD authentication +// AuthService automatically uses crypto auth const success = await login('username'); ``` +### Using the CryptID Component + +```typescript +import CryptID from './components/auth/CryptID'; + +// Render the authentication component + console.log('Login successful')} + onCancel={() => console.log('Login cancelled')} +/> +``` + ### Testing the Implementation ```typescript @@ -166,31 +177,42 @@ import CryptoTest from './components/auth/CryptoTest'; src/ ├── lib/ │ ├── auth/ -│ │ ├── crypto.ts # WebCryptoAPI wrapper -│ │ ├── cryptoAuthService.ts # High-level auth service -│ │ ├── authService.ts # Enhanced auth service -│ │ └── account.ts # User account management +│ │ ├── crypto.ts # WebCryptoAPI wrapper +│ │ ├── cryptoAuthService.ts # High-level auth service +│ │ ├── authService.ts # Simplified auth service +│ │ ├── sessionPersistence.ts # Session storage utilities +│ │ └── types.ts # TypeScript types │ └── utils/ -│ └── browser.ts # Browser support detection +│ └── browser.ts # Browser support detection ├── components/ │ └── auth/ -│ ├── CryptoLogin.tsx # Crypto auth UI -│ └── CryptoTest.tsx # Test component +│ ├── CryptID.tsx # Main crypto auth UI +│ ├── CryptoDebug.tsx # Debug component +│ └── CryptoTest.tsx # Test component +├── context/ +│ └── AuthContext.tsx # React context for auth state └── css/ - └── crypto-auth.css # Styles for crypto components + └── crypto-auth.css # Styles for crypto components ``` ## Dependencies ### Required Packages - `one-webcrypto`: WebCryptoAPI polyfill (^1.0.3) -- `@oddjs/odd`: Open Data Directory framework (^0.37.2) ### Browser APIs Used - `window.crypto.subtle`: WebCryptoAPI -- `window.localStorage`: Key storage +- `window.localStorage`: Key and session storage - `window.isSecureContext`: Security context check +## Storage + +### localStorage Keys Used +- `registeredUsers`: Array of registered usernames +- `${username}_publicKey`: User's public key (Base64) +- `${username}_authData`: Authentication data (challenge, signature, timestamp) +- `session`: Current user session data + ## Testing ### Manual Testing @@ -208,6 +230,7 @@ src/ - [x] User registration - [x] User login - [x] Credential verification +- [x] Session persistence ## Troubleshooting @@ -228,13 +251,13 @@ src/ - Try refreshing the page 4. **"Authentication failed"** - - Verify user exists + - Verify user exists in localStorage - Check stored credentials - Clear browser data and retry ### Debug Mode -Enable debug logging by setting: +Enable debug logging by opening the browser console: ```typescript localStorage.setItem('debug_crypto', 'true'); ``` @@ -242,7 +265,7 @@ localStorage.setItem('debug_crypto', 'true'); ## Future Enhancements ### Planned Improvements -1. **Enhanced Key Storage**: Use Web Crypto API's key storage +1. **Enhanced Key Storage**: Use Web Crypto API's non-extractable keys 2. **Server-Side Verification**: Add server-side signature verification 3. **Multi-Factor Authentication**: Add additional authentication factors 4. **Key Rotation**: Implement automatic key rotation @@ -254,6 +277,15 @@ localStorage.setItem('debug_crypto', 'true'); 3. **Post-Quantum Cryptography**: Prepare for quantum threats 4. **Biometric Integration**: Add biometric authentication +## Integration with Automerge Sync + +The authentication system works seamlessly with the Automerge-based real-time collaboration: + +- **User Identification**: Each user is identified by their username in Automerge +- **Session Management**: Sessions persist across page reloads via localStorage +- **Collaboration**: Authenticated users can join shared canvas rooms +- **Privacy**: Only authenticated users can access canvas data + ## Contributing When contributing to the WebCryptoAPI authentication system: @@ -269,4 +301,4 @@ When contributing to the WebCryptoAPI authentication system: - [WebCryptoAPI Specification](https://www.w3.org/TR/WebCryptoAPI/) - [ECDSA Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) - [P-256 Curve](https://en.wikipedia.org/wiki/NIST_Curve_P-256) -- [Challenge-Response Authentication](https://en.wikipedia.org/wiki/Challenge%E2%80%93response_authentication) \ No newline at end of file +- [Challenge-Response Authentication](https://en.wikipedia.org/wiki/Challenge%E2%80%93response_authentication) diff --git a/package-lock.json b/package-lock.json index 21ecdfc..4d1f49c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,14 +16,12 @@ "@chengsokdara/use-whisper": "^0.2.0", "@daily-co/daily-js": "^0.60.0", "@daily-co/daily-react": "^0.20.0", - "@oddjs/odd": "^0.37.2", "@tldraw/assets": "^3.15.4", "@tldraw/tldraw": "^3.15.4", "@tldraw/tlschema": "^3.15.4", "@types/markdown-it": "^14.1.1", "@types/marked": "^5.0.2", "@uiw/react-md-editor": "^4.0.5", - "@vercel/analytics": "^1.2.2", "@xenova/transformers": "^2.17.2", "ai": "^4.1.0", "ajv": "^8.17.1", @@ -51,7 +49,6 @@ "recoil": "^0.7.7", "tldraw": "^3.15.4", "use-whisper": "^0.0.1", - "vercel": "^39.1.1", "webcola": "^3.4.0", "webnative": "^0.36.3" }, @@ -788,6 +785,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -800,6 +798,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -840,54 +839,6 @@ "recoil": "^0.7.0" } }, - "node_modules/@edge-runtime/format": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@edge-runtime/format/-/format-2.2.1.tgz", - "integrity": "sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==", - "license": "MPL-2.0", - "engines": { - "node": ">=16" - } - }, - "node_modules/@edge-runtime/node-utils": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@edge-runtime/node-utils/-/node-utils-2.3.0.tgz", - "integrity": "sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ==", - "license": "MPL-2.0", - "engines": { - "node": ">=16" - } - }, - "node_modules/@edge-runtime/ponyfill": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@edge-runtime/ponyfill/-/ponyfill-2.4.2.tgz", - "integrity": "sha512-oN17GjFr69chu6sDLvXxdhg0Qe8EZviGSuqzR9qOiKh4MhFYGdBBcqRNzdmYeAdeRzOW2mM9yil4RftUQ7sUOA==", - "license": "MPL-2.0", - "engines": { - "node": ">=16" - } - }, - "node_modules/@edge-runtime/primitives": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-4.1.0.tgz", - "integrity": "sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==", - "license": "MPL-2.0", - "engines": { - "node": ">=16" - } - }, - "node_modules/@edge-runtime/vm": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-3.2.0.tgz", - "integrity": "sha512-0dEVyRLM/lG4gp1R/Ik5bfPl/1wX00xFwd5KcNH602tzBa09oF7pbTKETEhR1GjZ75K6OJnYFu8II2dyMhONMw==", - "license": "MPL-2.0", - "dependencies": { - "@edge-runtime/primitives": "4.1.0" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/@emnapi/runtime": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", @@ -1865,27 +1816,6 @@ "npm": ">=7.0.0" } }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@isaacs/fs-minipass/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -2299,132 +2229,6 @@ "npm": ">=7.0.0" } }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.0.tgz", - "integrity": "sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==", - "license": "BSD-3-Clause", - "dependencies": { - "consola": "^3.2.3", - "detect-libc": "^2.0.0", - "https-proxy-agent": "^7.0.5", - "node-fetch": "^2.6.7", - "nopt": "^8.0.0", - "semver": "^7.5.3", - "tar": "^7.4.0" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/minizlib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", - "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/@multiformats/dns": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@multiformats/dns/-/dns-1.0.6.tgz", @@ -2542,73 +2346,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@oddjs/odd": { - "version": "0.37.2", - "resolved": "https://registry.npmjs.org/@oddjs/odd/-/odd-0.37.2.tgz", - "integrity": "sha512-ot5cpfHCfq8r9AXAxNACgmSSjLjEm1PJj2AOGrmOFiG0jYgD530h9pZc7G0keNIQJNk6YbZxCOddk0XfiwU01A==", - "license": "Apache-2.0", - "dependencies": { - "@ipld/dag-cbor": "^8.0.0", - "@ipld/dag-pb": "^3.0.1", - "@libp2p/interface-keys": "^1.0.4", - "@libp2p/peer-id": "^1.1.17", - "@multiformats/multiaddr": "^11.1.0", - "blockstore-core": "^2.0.2", - "blockstore-datastore-adapter": "^4.0.0", - "datastore-core": "^8.0.2", - "datastore-level": "^9.0.4", - "events": "^3.3.0", - "fission-bloom-filters": "1.7.1", - "ipfs-core-types": "0.13.0", - "ipfs-repo": "^16.0.0", - "keystore-idb": "^0.15.5", - "localforage": "^1.10.0", - "multiformats": "^10.0.2", - "one-webcrypto": "^1.0.3", - "throttle-debounce": "^3.0.1", - "tweetnacl": "^1.0.3", - "uint8arrays": "^3.0.0", - "wnfs": "0.1.7" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/@opentelemetry/api": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", @@ -4305,28 +4042,6 @@ } } }, - "node_modules/@rollup/pluginutils": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", - "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.50.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.0.tgz", @@ -4747,12 +4462,6 @@ "node": ">=8" } }, - "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "license": "MIT" - }, "node_modules/@sindresorhus/is": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.0.2.tgz", @@ -5593,54 +5302,6 @@ "node": ">= 10" } }, - "node_modules/@ts-morph/common": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.11.1.tgz", - "integrity": "sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==", - "license": "MIT", - "dependencies": { - "fast-glob": "^3.2.7", - "minimatch": "^3.0.4", - "mkdirp": "^1.0.4", - "path-browserify": "^1.0.1" - } - }, - "node_modules/@ts-morph/common/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "license": "MIT" - }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -5764,12 +5425,6 @@ "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", "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==", - "license": "MIT" - }, "node_modules/@types/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", @@ -6048,539 +5703,6 @@ "react": ">= 16.8.0" } }, - "node_modules/@vercel/analytics": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.5.0.tgz", - "integrity": "sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g==", - "license": "MPL-2.0", - "peerDependencies": { - "@remix-run/react": "^2", - "@sveltejs/kit": "^1 || ^2", - "next": ">= 13", - "react": "^18 || ^19 || ^19.0.0-rc", - "svelte": ">= 4", - "vue": "^3", - "vue-router": "^4" - }, - "peerDependenciesMeta": { - "@remix-run/react": { - "optional": true - }, - "@sveltejs/kit": { - "optional": true - }, - "next": { - "optional": true - }, - "react": { - "optional": true - }, - "svelte": { - "optional": true - }, - "vue": { - "optional": true - }, - "vue-router": { - "optional": true - } - } - }, - "node_modules/@vercel/build-utils": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@vercel/build-utils/-/build-utils-9.1.0.tgz", - "integrity": "sha512-ccknvdKH6LDB9ZzZaX8a8cOvFbI441APLHvKrunJE/wezY0skmfuEUK1qnfPApXMs4FMWzZQj2LO9qpzfgBPsQ==", - "license": "Apache-2.0" - }, - "node_modules/@vercel/error-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-2.0.3.tgz", - "integrity": "sha512-CqC01WZxbLUxoiVdh9B/poPbNpY9U+tO1N9oWHwTl5YAZxcqXmmWJ8KNMFItJCUUWdY3J3xv8LvAuQv2KZ5YdQ==", - "license": "Apache-2.0" - }, - "node_modules/@vercel/fun": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vercel/fun/-/fun-1.1.2.tgz", - "integrity": "sha512-n13RO1BUy8u6+kzDQ2++BRj4Y5EAiQPt+aV+Tb2HNTmToNr4Mu3dE1kFlaTVTxQzAT3hvIRlVEU/OMvF8LCFJw==", - "license": "Apache-2.0", - "dependencies": { - "@tootallnate/once": "2.0.0", - "async-listen": "1.2.0", - "debug": "4.3.4", - "execa": "3.2.0", - "fs-extra": "8.1.0", - "generic-pool": "3.4.2", - "micro": "9.3.5-canary.3", - "ms": "2.1.1", - "node-fetch": "2.6.7", - "path-match": "1.2.4", - "promisepipe": "3.0.0", - "semver": "7.5.4", - "stat-mode": "0.3.0", - "stream-to-promise": "2.2.0", - "tar": "4.4.18", - "tree-kill": "1.2.2", - "uid-promise": "1.0.0", - "uuid": "3.3.2", - "xdg-app-paths": "5.1.0", - "yauzl-promise": "2.1.3" - }, - "engines": { - "node": ">= 16" - } - }, - "node_modules/@vercel/fun/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@vercel/fun/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "license": "MIT" - }, - "node_modules/@vercel/fun/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@vercel/fun/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "license": "MIT" - }, - "node_modules/@vercel/fun/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/@vercel/fun/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@vercel/fun/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/@vercel/fun/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/@vercel/fun/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/@vercel/fun/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/@vercel/fun/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/@vercel/gatsby-plugin-vercel-analytics": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-analytics/-/gatsby-plugin-vercel-analytics-1.0.11.tgz", - "integrity": "sha512-iTEA0vY6RBPuEzkwUTVzSHDATo1aF6bdLLspI68mQ/BTbi5UQEGjpjyzdKOVcSYApDtFU6M6vypZ1t4vIEnHvw==", - "license": "Apache-2.0", - "dependencies": { - "web-vitals": "0.2.4" - } - }, - "node_modules/@vercel/gatsby-plugin-vercel-builder": { - "version": "2.0.65", - "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-builder/-/gatsby-plugin-vercel-builder-2.0.65.tgz", - "integrity": "sha512-MQX56fuL4WHDhT/fvKy9FMJigOymTAcCqw8rteF1wpRBAGhapSJkhT34I4mkfRRMFk1kIV7ijwuX+w1mpRrLjA==", - "dependencies": { - "@sinclair/typebox": "0.25.24", - "@vercel/build-utils": "9.1.0", - "@vercel/routing-utils": "5.0.1", - "esbuild": "0.14.47", - "etag": "1.8.1", - "fs-extra": "11.1.0" - } - }, - "node_modules/@vercel/gatsby-plugin-vercel-builder/node_modules/fs-extra": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", - "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@vercel/gatsby-plugin-vercel-builder/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@vercel/gatsby-plugin-vercel-builder/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@vercel/go": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@vercel/go/-/go-3.2.1.tgz", - "integrity": "sha512-ezjmuUvLigH9V4egEaX0SZ+phILx8lb+Zkp1iTqKI+yl/ibPAtVo5o+dLSRAXU9U01LBmaLu3O8Oxd/JpWYCOw==", - "license": "Apache-2.0" - }, - "node_modules/@vercel/hydrogen": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@vercel/hydrogen/-/hydrogen-1.0.11.tgz", - "integrity": "sha512-nkSQ0LC7rFRdfkTUGm9pIbAfRb2Aat05u8ouN0FoUl7/I/YVgd0G6iRBN9bOMFUIiBiaKB4KqaZEFzVfUHpwYw==", - "license": "Apache-2.0", - "dependencies": { - "@vercel/static-config": "3.0.0", - "ts-morph": "12.0.0" - } - }, - "node_modules/@vercel/next": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@vercel/next/-/next-4.4.4.tgz", - "integrity": "sha512-/xMzlOMY8UHzCehRZzx8TIdzVRCu3O2O+Gb7R8uRX0/ci9cLIjJvi0WfLyR06Ny4fMqMzzUuRADp5ezfJjaO1Q==", - "license": "Apache-2.0", - "dependencies": { - "@vercel/nft": "0.27.10" - } - }, - "node_modules/@vercel/nft": { - "version": "0.27.10", - "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.27.10.tgz", - "integrity": "sha512-zbaF9Wp/NsZtKLE4uVmL3FyfFwlpDyuymQM1kPbeT0mVOHKDQQNjnnfslB3REg3oZprmNFJuh3pkHBk2qAaizg==", - "license": "MIT", - "dependencies": { - "@mapbox/node-pre-gyp": "^2.0.0-rc.0", - "@rollup/pluginutils": "^5.1.3", - "acorn": "^8.6.0", - "acorn-import-attributes": "^1.9.5", - "async-sema": "^3.1.1", - "bindings": "^1.4.0", - "estree-walker": "2.0.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "node-gyp-build": "^4.2.2", - "picomatch": "^4.0.2", - "resolve-from": "^5.0.0" - }, - "bin": { - "nft": "out/cli.js" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@vercel/node": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@vercel/node/-/node-5.0.4.tgz", - "integrity": "sha512-AXpTFDzomabvi/FmxDDTwmnuqRBDfy2i0nzjKwVPM3ch94EucPbiAk3+18iZOX/A+o2mBO4jKc1DmB0ifQF2Rw==", - "license": "Apache-2.0", - "dependencies": { - "@edge-runtime/node-utils": "2.3.0", - "@edge-runtime/primitives": "4.1.0", - "@edge-runtime/vm": "3.2.0", - "@types/node": "16.18.11", - "@vercel/build-utils": "9.1.0", - "@vercel/error-utils": "2.0.3", - "@vercel/nft": "0.27.10", - "@vercel/static-config": "3.0.0", - "async-listen": "3.0.0", - "cjs-module-lexer": "1.2.3", - "edge-runtime": "2.5.9", - "es-module-lexer": "1.4.1", - "esbuild": "0.14.47", - "etag": "1.8.1", - "node-fetch": "2.6.9", - "path-to-regexp": "6.2.1", - "path-to-regexp-updated": "npm:path-to-regexp@6.3.0", - "ts-morph": "12.0.0", - "ts-node": "10.9.1", - "typescript": "4.9.5", - "undici": "5.28.4" - } - }, - "node_modules/@vercel/node/node_modules/@types/node": { - "version": "16.18.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.11.tgz", - "integrity": "sha512-3oJbGBUWuS6ahSnEq1eN2XrCyf4YsWI8OyCvo7c64zQJNplk3mO84t53o8lfTk+2ji59g5ycfc6qQ3fdHliHuA==", - "license": "MIT" - }, - "node_modules/@vercel/node/node_modules/async-listen": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.0.tgz", - "integrity": "sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/@vercel/node/node_modules/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/@vercel/node/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/@vercel/node/node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/@vercel/node/node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", - "license": "MIT", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/@vercel/node/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/@vercel/node/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/@vercel/python": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/@vercel/python/-/python-4.7.1.tgz", - "integrity": "sha512-H4g/5e8unII4oQ+KN5IUvTZSzHmj+lLYDkAK15QGYgAxBtE/mHUvEZpPPo7DPUDIyfq8ybWB1bmk7H5kEahubQ==", - "license": "Apache-2.0" - }, - "node_modules/@vercel/redwood": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@vercel/redwood/-/redwood-2.1.13.tgz", - "integrity": "sha512-e+4odfP2akWQq3WQ8mBkjqqwUcOvjhYmAhfg66IqTdIG15tIY6EOTMx/DhqXlvSDCyBbZPcqHb4/Xe662yPiEw==", - "license": "Apache-2.0", - "dependencies": { - "@vercel/nft": "0.27.10", - "@vercel/routing-utils": "5.0.1", - "@vercel/static-config": "3.0.0", - "semver": "6.3.1", - "ts-morph": "12.0.0" - } - }, - "node_modules/@vercel/remix-builder": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@vercel/remix-builder/-/remix-builder-5.1.1.tgz", - "integrity": "sha512-OP1f6GI8MdylL4aUrX6n7OkN93jqmkWyLzQMeQMapVOXKvRFj05STZ4SQ/kNJkXdh3rEzjJWuCsJ6bklTHkJ7Q==", - "license": "Apache-2.0", - "dependencies": { - "@vercel/error-utils": "2.0.3", - "@vercel/nft": "0.27.10", - "@vercel/static-config": "3.0.0", - "ts-morph": "12.0.0" - } - }, - "node_modules/@vercel/routing-utils": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@vercel/routing-utils/-/routing-utils-5.0.1.tgz", - "integrity": "sha512-CH8sulzI8VNySWyJP+536fEX+oBnRuIVpw79jrn/0JwgCl7xb6E2JkKrMBT/mUCkZXh4vZZIOt23/QiIRK9Dyw==", - "license": "Apache-2.0", - "dependencies": { - "path-to-regexp": "6.1.0", - "path-to-regexp-updated": "npm:path-to-regexp@6.3.0" - }, - "optionalDependencies": { - "ajv": "^6.12.3" - } - }, - "node_modules/@vercel/routing-utils/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "optional": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@vercel/routing-utils/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==", - "license": "MIT", - "optional": true - }, - "node_modules/@vercel/routing-utils/node_modules/path-to-regexp": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.1.0.tgz", - "integrity": "sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==", - "license": "MIT" - }, - "node_modules/@vercel/ruby": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@vercel/ruby/-/ruby-2.2.0.tgz", - "integrity": "sha512-FJF9gKVNHAljGOgV6zS5ou2N7ZgjOqMMtcPA5lsJEUI5/AZzVDWCmtcowTP80wEtHuupkd7d7M399FA082kXYQ==", - "license": "Apache-2.0" - }, - "node_modules/@vercel/static-build": { - "version": "2.5.43", - "resolved": "https://registry.npmjs.org/@vercel/static-build/-/static-build-2.5.43.tgz", - "integrity": "sha512-r6Pi/yC1nUCuq6V7xDxfMKDkwla4qnqpJVohd7cTsWRDKlRzHJJX/YaDp/6yKrDaNH9UY6cBhj9ryL8QJWY63w==", - "license": "Apache-2.0", - "dependencies": { - "@vercel/gatsby-plugin-vercel-analytics": "1.0.11", - "@vercel/gatsby-plugin-vercel-builder": "2.0.65", - "@vercel/static-config": "3.0.0", - "ts-morph": "12.0.0" - } - }, - "node_modules/@vercel/static-config": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@vercel/static-config/-/static-config-3.0.0.tgz", - "integrity": "sha512-2qtvcBJ1bGY0dYGYh3iM7yGKkk971FujLEDXzuW5wcZsPr1GSEjO/w2iSr3qve6nDDtBImsGoDEnus5FI4+fIw==", - "license": "Apache-2.0", - "dependencies": { - "ajv": "8.6.3", - "json-schema-to-ts": "1.6.4", - "ts-morph": "12.0.0" - } - }, - "node_modules/@vercel/static-config/node_modules/ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/@vitejs/plugin-react": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", @@ -6658,15 +5780,6 @@ "deprecated": "Use your platform's native atob() and btoa() methods instead", "license": "BSD-3-Clause" }, - "node_modules/abbrev": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", - "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -6737,15 +5850,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-walk": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", @@ -6846,18 +5950,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "license": "MIT" - }, - "node_modules/arg": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", - "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", - "license": "MIT" - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -6894,18 +5986,6 @@ "node": ">=12.0.0" } }, - "node_modules/async-listen": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-1.2.0.tgz", - "integrity": "sha512-CcEtRh/oc9Jc4uWeUwdpG/+Mb2YUHKmdaTf0gUr7Wa+bfp4xx70HOb3RuSTJMvqKNB1TkdTfjLdrcz2X4rkkZA==", - "license": "MIT" - }, - "node_modules/async-sema": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", - "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", - "license": "MIT" - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -6959,12 +6039,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, "node_modules/bare-events": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.7.0.tgz", @@ -7093,15 +6167,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -7205,28 +6270,6 @@ "integrity": "sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==", "license": "MIT" }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/browser-level": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", @@ -7333,15 +6376,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -7568,33 +6602,12 @@ "mermaid": "9.4.3" } }, - "node_modules/chokidar": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.0.tgz", - "integrity": "sha512-mxIojEAQcuEvT/lyXq+jf/3cO/KoA6z4CeNDGGevTybECPOMFCnQy3OPahluUkbqgPNGw5Bi78UC7Po6Lhy+NA==", - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "license": "ISC" }, - "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "license": "MIT" - }, "node_modules/classic-level": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.4.1.tgz", @@ -7657,12 +6670,6 @@ "integrity": "sha512-34yY66OBWtX4nSq8cYvOG4pZ4ufaPEnBfm00Z6sfLcXT0JdUFcCROt9LRD2cWRd1euQ3cdhFXw782WEui9rHxw==", "license": "MIT" }, - "node_modules/code-block-writer": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz", - "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==", - "license": "MIT" - }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -7736,12 +6743,6 @@ "node": ">= 10" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, "node_modules/concurrently": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", @@ -7767,33 +6768,6 @@ "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-hrtime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-3.0.0.tgz", - "integrity": "sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -7831,32 +6805,12 @@ "layout-base": "^1.0.0" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "license": "MIT" - }, "node_modules/crelt": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", "license": "MIT" }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/crypto-js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", @@ -8691,15 +7645,6 @@ "node": ">=0.4.0" } }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -8737,15 +7682,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/diff-match-patch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", @@ -8897,56 +7833,6 @@ "node": ">= 0.4" } }, - "node_modules/edge-runtime": { - "version": "2.5.9", - "resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.9.tgz", - "integrity": "sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg==", - "license": "MPL-2.0", - "dependencies": { - "@edge-runtime/format": "2.2.1", - "@edge-runtime/ponyfill": "2.4.2", - "@edge-runtime/vm": "3.2.0", - "async-listen": "3.0.1", - "mri": "1.2.0", - "picocolors": "1.0.0", - "pretty-ms": "7.0.1", - "signal-exit": "4.0.2", - "time-span": "4.0.0" - }, - "bin": { - "edge-runtime": "dist/cli/index.js" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/edge-runtime/node_modules/async-listen": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.1.tgz", - "integrity": "sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/edge-runtime/node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "license": "ISC" - }, - "node_modules/edge-runtime/node_modules/signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/electron-to-chromium": { "version": "1.5.213", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.213.tgz", @@ -9020,12 +7906,6 @@ "node": ">= 0.4" } }, - "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", - "license": "MIT" - }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -9053,361 +7933,6 @@ "node": ">= 0.4" } }, - "node_modules/esbuild": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.47.tgz", - "integrity": "sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "esbuild-android-64": "0.14.47", - "esbuild-android-arm64": "0.14.47", - "esbuild-darwin-64": "0.14.47", - "esbuild-darwin-arm64": "0.14.47", - "esbuild-freebsd-64": "0.14.47", - "esbuild-freebsd-arm64": "0.14.47", - "esbuild-linux-32": "0.14.47", - "esbuild-linux-64": "0.14.47", - "esbuild-linux-arm": "0.14.47", - "esbuild-linux-arm64": "0.14.47", - "esbuild-linux-mips64le": "0.14.47", - "esbuild-linux-ppc64le": "0.14.47", - "esbuild-linux-riscv64": "0.14.47", - "esbuild-linux-s390x": "0.14.47", - "esbuild-netbsd-64": "0.14.47", - "esbuild-openbsd-64": "0.14.47", - "esbuild-sunos-64": "0.14.47", - "esbuild-windows-32": "0.14.47", - "esbuild-windows-64": "0.14.47", - "esbuild-windows-arm64": "0.14.47" - } - }, - "node_modules/esbuild-android-64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.47.tgz", - "integrity": "sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-android-arm64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.47.tgz", - "integrity": "sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-darwin-64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.47.tgz", - "integrity": "sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-darwin-arm64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.47.tgz", - "integrity": "sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-freebsd-64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.47.tgz", - "integrity": "sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-freebsd-arm64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.47.tgz", - "integrity": "sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-32": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.47.tgz", - "integrity": "sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.47.tgz", - "integrity": "sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-arm": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.47.tgz", - "integrity": "sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-arm64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.47.tgz", - "integrity": "sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-mips64le": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.47.tgz", - "integrity": "sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-ppc64le": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.47.tgz", - "integrity": "sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-riscv64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.47.tgz", - "integrity": "sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-s390x": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.47.tgz", - "integrity": "sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-netbsd-64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.47.tgz", - "integrity": "sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-openbsd-64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.47.tgz", - "integrity": "sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-sunos-64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.47.tgz", - "integrity": "sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-32": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.47.tgz", - "integrity": "sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.47.tgz", - "integrity": "sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-arm64": { - "version": "0.14.47", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.47.tgz", - "integrity": "sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -9483,12 +8008,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "license": "MIT" - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -9498,15 +8017,6 @@ "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/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -9531,12 +8041,6 @@ "node": ">=0.8.x" } }, - "node_modules/events-intercept": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/events-intercept/-/events-intercept-2.0.0.tgz", - "integrity": "sha512-blk1va0zol9QOrdZt0rFXo5KMkNPVSp92Eju/Qz8THwKWKRKeE0T8Br/1aW6+Edkyq9xHYgYxn2QtOnUKPUp+Q==", - "license": "MIT" - }, "node_modules/events-universal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", @@ -9546,27 +8050,6 @@ "bare-events": "^2.7.0" } }, - "node_modules/execa": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-3.2.0.tgz", - "integrity": "sha512-kJJfVbI/lZE1PZYDI5VPxp8zXPO9rtxOkhpZ0jMKha56AI9y2gGVC6bkukStQf0ka5Rh15BA5m7cCCH4jmHqkw==", - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": "^8.12.0 || >=9.7.0" - } - }, "node_modules/exit-hook": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", @@ -9626,29 +8109,6 @@ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "license": "MIT" }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "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==", - "license": "MIT", - "optional": true - }, "node_modules/fast-sha256": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz", @@ -9671,15 +8131,6 @@ ], "license": "BSD-3-Clause" }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fathom-typescript": { "version": "0.0.36", "resolved": "https://registry.npmjs.org/fathom-typescript/-/fathom-typescript-0.0.36.tgz", @@ -9689,15 +8140,6 @@ "zod": "^3.20.0" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -9722,24 +8164,6 @@ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", "license": "MIT" }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fission-bloom-filters": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/fission-bloom-filters/-/fission-bloom-filters-1.7.1.tgz", @@ -9842,44 +8266,6 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT" }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-extra/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "license": "ISC", - "dependencies": { - "minipass": "^2.6.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -9904,15 +8290,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/generic-pool": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.4.2.tgz", - "integrity": "sha512-H7cUpwCQSiJmAHM4c/aFu6fUfrhWXW1ncyh8ftxEPMu6AiYkHw9K8br720TGPZJbk5eOH2bynjZD1yPvdDAmag==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -9979,21 +8356,6 @@ "node": ">= 0.4" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -10006,39 +8368,6 @@ "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", "license": "ISC" }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", @@ -10679,25 +9008,6 @@ "entities": "^2.0.0" } }, - "node_modules/http-errors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.4.0.tgz", - "integrity": "sha512-oLjPqve1tuOl5aRhv8GK5eHpqP1C9fb+Ol+XTLjKfLltE44zdDbEdjPSbU7Ch5rSNsVFqZn97SrMmZLdu1/YMw==", - "license": "MIT", - "dependencies": { - "inherits": "2.0.1", - "statuses": ">= 1.2.1 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", - "license": "ISC" - }, "node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -10725,15 +9035,6 @@ "node": ">= 6" } }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "license": "Apache-2.0", - "engines": { - "node": ">=8.12.0" - } - }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -10787,17 +9088,6 @@ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", "license": "MIT" }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -11143,15 +9433,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -11162,18 +9443,6 @@ "node": ">=8" } }, - "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==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-hexadecimal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", @@ -11184,15 +9453,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -11217,36 +9477,12 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "license": "MIT" }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-url": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", "license": "MIT" }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, "node_modules/it-all": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz", @@ -11526,16 +9762,6 @@ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "license": "(AFL-2.1 OR BSD-3-Clause)" }, - "node_modules/json-schema-to-ts": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-1.6.4.tgz", - "integrity": "sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.6", - "ts-toolbelt": "^6.15.5" - } - }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -11584,15 +9810,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jspdf": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.5.2.tgz", @@ -11862,12 +10079,6 @@ "integrity": "sha512-NWtdGrAca/69fm6DIVd8T9rtfDII4Q8NQbIbsKQq2VzS9eqOGYs8uaNQjcuaCq/d9H/o625aOTJX2Qoxzqw0Pw==", "license": "Apache-2.0 OR MIT" }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "license": "ISC" - }, "node_modules/markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -12222,21 +10433,6 @@ "node": ">=10" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/mermaid": { "version": "9.4.3", "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.4.3.tgz", @@ -12269,23 +10465,6 @@ "license": "(MPL-2.0 OR Apache-2.0)", "optional": true }, - "node_modules/micro": { - "version": "9.3.5-canary.3", - "resolved": "https://registry.npmjs.org/micro/-/micro-9.3.5-canary.3.tgz", - "integrity": "sha512-viYIo9PefV+w9dvoIBh1gI44Mvx1BOk67B4BpC2QK77qdY0xZF0Q+vWLt/BII6cLkIc8rLmSIcJaB/OrXXKe1g==", - "license": "MIT", - "dependencies": { - "arg": "4.1.0", - "content-type": "1.0.4", - "raw-body": "2.4.1" - }, - "bin": { - "micro": "bin/micro.js" - }, - "engines": { - "node": ">= 8.0.0" - } - }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -12849,31 +11028,6 @@ ], "license": "MIT" }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", @@ -12908,15 +11062,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -13011,18 +11156,6 @@ } } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -13032,37 +11165,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "license": "ISC", - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "license": "MIT", - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -13089,15 +11191,6 @@ "main-event": "^1.0.0" } }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -13295,33 +11388,6 @@ "license": "MIT", "optional": true }, - "node_modules/nopt": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", - "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", - "license": "ISC", - "dependencies": { - "abbrev": "^3.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -13362,21 +11428,6 @@ "integrity": "sha512-fu9ywBVBPx0gS9K0etIROTiCkvI5S1TDjFsYFb3rC1ewFxeOqsbzq7aIMBHsYfrTHBcGXJaONXXjTl8B01cW1Q==", "license": "MIT" }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/onnx-proto": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz", @@ -13495,15 +11546,6 @@ "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", "license": "MIT" }, - "node_modules/os-paths": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/os-paths/-/os-paths-4.4.0.tgz", - "integrity": "sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==", - "license": "MIT", - "engines": { - "node": ">= 6.0" - } - }, "node_modules/p-defer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.1.tgz", @@ -13516,15 +11558,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/p-queue": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.4.1.tgz", @@ -13588,15 +11621,6 @@ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "license": "MIT" }, - "node_modules/parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/parse-numeric-range": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", @@ -13619,63 +11643,6 @@ "tslib": "^2.0.3" } }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "license": "MIT" - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-match": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/path-match/-/path-match-1.2.4.tgz", - "integrity": "sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==", - "deprecated": "This package is archived and no longer maintained. For support, visit https://github.com/expressjs/express/discussions", - "license": "MIT", - "dependencies": { - "http-errors": "~1.4.0", - "path-to-regexp": "^1.0.0" - } - }, - "node_modules/path-match/node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", - "license": "MIT" - }, - "node_modules/path-to-regexp-updated": { - "name": "path-to-regexp", - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "license": "MIT" - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -13683,12 +11650,6 @@ "dev": true, "license": "MIT" }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "license": "MIT" - }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -13707,6 +11668,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -13814,33 +11776,12 @@ "renderkid": "^3.0.0" } }, - "node_modules/pretty-ms": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", - "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", - "license": "MIT", - "dependencies": { - "parse-ms": "^2.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/progress-events": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.1.tgz", "integrity": "sha512-MOzLIwhpt64KIVN64h1MwdKWiyKFNc/S6BoYKPIVUHFg0/eIEyBulhWCgn678v/4c0ri3FdGuzXymNCv02MUIw==", "license": "Apache-2.0 OR MIT" }, - "node_modules/promisepipe": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/promisepipe/-/promisepipe-3.0.0.tgz", - "integrity": "sha512-V6TbZDJ/ZswevgkDNpGt/YqNCiZP9ASfgU+p83uJE6NrGtvSGoOcHLiDCqkMs2+yg7F5qHdLV8d0aS8O26G/KA==", - "license": "MIT" - }, "node_modules/proper-lockfile": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", @@ -14305,58 +12246,6 @@ "performance-now": "^2.1.0" } }, - "node_modules/raw-body": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.3", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "license": "MIT", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/rbush": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/rbush/-/rbush-4.0.1.tgz", @@ -14588,19 +12477,6 @@ "node": ">= 6" } }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/receptacle": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/receptacle/-/receptacle-1.3.2.tgz", @@ -15007,15 +12883,6 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "license": "MIT" }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -15032,16 +12899,6 @@ "node": ">= 4" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rgbcolor": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", @@ -15106,29 +12963,6 @@ "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", "license": "MIT" }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "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", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/run-parallel-limit": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", @@ -15245,6 +13079,7 @@ "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" @@ -15256,12 +13091,6 @@ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", "license": "MIT" }, - "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "license": "ISC" - }, "node_modules/sharp": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", @@ -15315,27 +13144,6 @@ "node": ">=10" } }, - "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==", - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/shell-quote": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", @@ -15491,21 +13299,6 @@ "node": ">=0.1.14" } }, - "node_modules/stat-mode": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.3.0.tgz", - "integrity": "sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng==", - "license": "MIT" - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/stoppable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", @@ -15517,44 +13310,6 @@ "npm": ">=6" } }, - "node_modules/stream-to-array": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", - "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", - "license": "MIT", - "dependencies": { - "any-promise": "^1.1.0" - } - }, - "node_modules/stream-to-promise": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/stream-to-promise/-/stream-to-promise-2.2.0.tgz", - "integrity": "sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==", - "license": "MIT", - "dependencies": { - "any-promise": "~1.3.0", - "end-of-stream": "~1.1.0", - "stream-to-array": "~2.3.0" - } - }, - "node_modules/stream-to-promise/node_modules/end-of-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", - "integrity": "sha512-EoulkdKF/1xa92q25PbjuDcgJ9RDHYU2Rs3SCIvs2/dSQ3BpmxneNHmA/M7fe60M3PrV7nNGTTNbkK62l6vXiQ==", - "license": "MIT", - "dependencies": { - "once": "~1.3.0" - } - }, - "node_modules/stream-to-promise/node_modules/once": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", - "integrity": "sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/streamx": { "version": "2.23.0", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", @@ -15625,15 +13380,6 @@ "node": ">=0.10.0" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -15750,24 +13496,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/tar": { - "version": "4.4.18", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.18.tgz", - "integrity": "sha512-ZuOtqqmkV9RE1+4odd+MhBpibmCxNP6PJhH/h2OqNuotTX7/XHPZQJv2pKvWMplFH9SIZZhitehh6vBH6LO8Pg==", - "license": "ISC", - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, "node_modules/tar-fs": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", @@ -15856,21 +13584,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/time-span": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/time-span/-/time-span-4.0.0.tgz", - "integrity": "sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==", - "license": "MIT", - "dependencies": { - "convert-hrtime": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tinyglobby": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", @@ -15923,27 +13636,6 @@ "react-dom": "^18.2.0 || ^19.0.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "node_modules/tough-cookie": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", @@ -15975,6 +13667,7 @@ "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" @@ -16010,77 +13703,6 @@ "node": ">=6.10" } }, - "node_modules/ts-morph": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-12.0.0.tgz", - "integrity": "sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==", - "license": "MIT", - "dependencies": { - "@ts-morph/common": "~0.11.0", - "code-block-writer": "^10.1.1" - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ts-toolbelt": { - "version": "6.15.5", - "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", - "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==", - "license": "Apache-2.0" - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -16132,12 +13754,6 @@ "dev": true, "license": "MIT" }, - "node_modules/uid-promise": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/uid-promise/-/uid-promise-1.0.0.tgz", - "integrity": "sha512-R8375j0qwXyIu/7R0tjdF06/sElHqbmdmWC9M2qQHpEVbvE4I5+38KJI7LUUmQMp7NVq4tKHiBMkT0NFM453Ig==", - "license": "MIT" - }, "node_modules/uint8-varint": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/uint8-varint/-/uint8-varint-2.0.4.tgz", @@ -16353,15 +13969,6 @@ "node": ">= 4.0.0" } }, - "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.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", @@ -16393,15 +14000,6 @@ "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==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -16529,45 +14127,12 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "license": "MIT" - }, "node_modules/varint": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", "license": "MIT" }, - "node_modules/vercel": { - "version": "39.4.2", - "resolved": "https://registry.npmjs.org/vercel/-/vercel-39.4.2.tgz", - "integrity": "sha512-A3ilkwJ83xLwAYAI733hHthJ4DO0zXjQOvCWS9QYklWQTBEj0RllyRkrfGd2jypgNDZuAbDS/iFMsV+GuuaTHw==", - "license": "Apache-2.0", - "dependencies": { - "@vercel/build-utils": "9.1.0", - "@vercel/fun": "1.1.2", - "@vercel/go": "3.2.1", - "@vercel/hydrogen": "1.0.11", - "@vercel/next": "4.4.4", - "@vercel/node": "5.0.4", - "@vercel/python": "4.7.1", - "@vercel/redwood": "2.1.13", - "@vercel/remix-builder": "5.1.1", - "@vercel/ruby": "2.2.0", - "@vercel/static-build": "2.5.43", - "chokidar": "4.0.0" - }, - "bin": { - "vc": "dist/vc.js", - "vercel": "dist/vc.js" - }, - "engines": { - "node": ">= 16" - } - }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", @@ -16814,12 +14379,6 @@ "node": ">= 14" } }, - "node_modules/web-vitals": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-0.2.4.tgz", - "integrity": "sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==", - "license": "Apache-2.0" - }, "node_modules/web-worker": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz", @@ -16972,21 +14531,6 @@ "node": ">=12" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/wildemitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/wildemitter/-/wildemitter-1.2.1.tgz", @@ -17572,30 +15116,6 @@ } } }, - "node_modules/xdg-app-paths": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-app-paths/-/xdg-app-paths-5.1.0.tgz", - "integrity": "sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA==", - "license": "MIT", - "dependencies": { - "xdg-portable": "^7.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/xdg-portable": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/xdg-portable/-/xdg-portable-7.3.0.tgz", - "integrity": "sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==", - "license": "MIT", - "dependencies": { - "os-paths": "^4.0.1" - }, - "engines": { - "node": ">= 6.0" - } - }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -17644,6 +15164,7 @@ "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": { @@ -17675,50 +15196,6 @@ "node": ">=12" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yauzl-clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/yauzl-clone/-/yauzl-clone-1.0.4.tgz", - "integrity": "sha512-igM2RRCf3k8TvZoxR2oguuw4z1xasOnA31joCqHIyLkeWrvAc2Jgay5ISQ2ZplinkoGaJ6orCz56Ey456c5ESA==", - "license": "MIT", - "dependencies": { - "events-intercept": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yauzl-promise": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/yauzl-promise/-/yauzl-promise-2.1.3.tgz", - "integrity": "sha512-A1pf6fzh6eYkK0L4Qp7g9jzJSDrM6nN0bOn5T0IbY4Yo3w+YkWlHFkJP7mzknMXjqusHFHlKsK2N+4OLsK2MRA==", - "license": "MIT", - "dependencies": { - "yauzl": "^2.9.1", - "yauzl-clone": "^1.0.4" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/youch": { "version": "4.1.0-beta.10", "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", diff --git a/package.json b/package.json index bf03188..7957dcd 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "@chengsokdara/use-whisper": "^0.2.0", "@daily-co/daily-js": "^0.60.0", "@daily-co/daily-react": "^0.20.0", - "@oddjs/odd": "^0.37.2", "@tldraw/assets": "^3.15.4", "@tldraw/tldraw": "^3.15.4", "@tldraw/tlschema": "^3.15.4", diff --git a/src/App.tsx b/src/App.tsx index eeec138..1e49ef9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -16,11 +16,7 @@ import "@/css/auth.css"; // Import auth styles import "@/css/crypto-auth.css"; // Import crypto auth styles import "@/css/starred-boards.css"; // Import starred boards styles import "@/css/user-profile.css"; // Import user profile styles -import "@/css/location.css"; // Import location sharing styles import { Dashboard } from "./routes/Dashboard"; -import { LocationShareCreate } from "./routes/LocationShareCreate"; -import { LocationShareView } from "./routes/LocationShareView"; -import { LocationDashboardRoute } from "./routes/LocationDashboardRoute"; import { useState, useEffect } from 'react'; // Import React Context providers @@ -149,22 +145,6 @@ const AppWithProviders = () => { } /> - {/* Location sharing routes */} - - - - } /> - - - - } /> - - - - } /> diff --git a/src/automerge/AutomergeToTLStore.ts b/src/automerge/AutomergeToTLStore.ts index 3e14891..dee47a5 100644 --- a/src/automerge/AutomergeToTLStore.ts +++ b/src/automerge/AutomergeToTLStore.ts @@ -593,7 +593,7 @@ export function sanitizeRecord(record: any): TLRecord { 'holon': 'Holon', 'obsidianBrowser': 'ObsidianBrowser', 'fathomMeetingsBrowser': 'FathomMeetingsBrowser', - 'locationShare': 'LocationShare', + // locationShare removed 'imageGen': 'ImageGen', } diff --git a/src/automerge/README.md b/src/automerge/README.md index bc5c9b7..3cc5940 100644 --- a/src/automerge/README.md +++ b/src/automerge/README.md @@ -47,6 +47,6 @@ To switch from TLdraw sync to Automerge sync: 1. Update the Board component to use `useAutomergeSync` 2. Deploy the new worker with Automerge Durable Object -3. Update the URI to use `/automerge/connect/` instead of `/connect/` +3. The CloudflareAdapter will automatically connect to `/connect/{roomId}` via WebSocket -The migration is backward compatible - existing TLdraw sync will continue to work while you test the new system. +The migration is backward compatible - the system will handle both legacy and new document formats. diff --git a/src/automerge/useAutomergeStoreV2.ts b/src/automerge/useAutomergeStoreV2.ts index 8f0e171..679e104 100644 --- a/src/automerge/useAutomergeStoreV2.ts +++ b/src/automerge/useAutomergeStoreV2.ts @@ -123,7 +123,7 @@ import { FathomNoteShape } from "@/shapes/FathomNoteShapeUtil" import { HolonShape } from "@/shapes/HolonShapeUtil" import { ObsidianBrowserShape } from "@/shapes/ObsidianBrowserShapeUtil" import { FathomMeetingsBrowserShape } from "@/shapes/FathomMeetingsBrowserShapeUtil" -import { LocationShareShape } from "@/shapes/LocationShareShapeUtil" +// Location shape removed - no longer needed export function useAutomergeStoreV2({ handle, @@ -173,7 +173,6 @@ export function useAutomergeStoreV2({ HolonShape, ObsidianBrowserShape, FathomMeetingsBrowserShape, - LocationShareShape, ], }) return store diff --git a/src/automerge/useAutomergeSyncRepo.ts b/src/automerge/useAutomergeSyncRepo.ts index 4a8c3db..f9303db 100644 --- a/src/automerge/useAutomergeSyncRepo.ts +++ b/src/automerge/useAutomergeSyncRepo.ts @@ -146,15 +146,10 @@ export function useAutomergeSync(config: AutomergeSyncConfig): TLStoreWithStatus let handle: DocHandle if (documentId) { - // Try to find the existing document - const foundHandle = await repo.find(documentId as any) - if (!foundHandle) { - console.log(`📝 Document ${documentId} not in local repo, creating handle`) - handle = repo.create() - } else { - console.log(`✅ Found existing document in local repo: ${documentId}`) - handle = foundHandle - } + // Find the existing document (will sync from network if not available locally) + console.log(`🔍 Finding document ${documentId} (will sync from network if needed)`) + handle = await repo.find(documentId as any) + console.log(`✅ Got handle for document: ${documentId}`) } else { // Create a new document and register its ID with the server handle = repo.create() diff --git a/src/components/auth/LinkDevice.tsx b/src/components/auth/LinkDevice.tsx deleted file mode 100644 index 695d804..0000000 --- a/src/components/auth/LinkDevice.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import React, { useState, useEffect } from 'react' -import { useNavigate } from 'react-router-dom' -import { createAccountLinkingConsumer } from '../../lib/auth/linking' -import { useAuth } from '../../context/AuthContext' -import { useNotifications } from '../../context/NotificationContext' - -const LinkDevice: React.FC = () => { - const [username, setUsername] = useState('') - const [displayPin, setDisplayPin] = useState('') - const [view, setView] = useState<'enter-username' | 'show-pin' | 'load-filesystem'>('enter-username') - const [accountLinkingConsumer, setAccountLinkingConsumer] = useState(null) - const navigate = useNavigate() - const { login } = useAuth() - const { addNotification } = useNotifications() - - const initAccountLinkingConsumer = async () => { - try { - const consumer = await createAccountLinkingConsumer(username) - setAccountLinkingConsumer(consumer) - - consumer.on('challenge', ({ pin }: { pin: number[] }) => { - setDisplayPin(pin.join('')) - setView('show-pin') - }) - - consumer.on('link', async ({ approved, username }: { approved: boolean, username: string }) => { - if (approved) { - setView('load-filesystem') - - const success = await login(username) - - if (success) { - addNotification("You're now connected!", "success") - navigate('/') - } else { - addNotification("Connection successful but login failed", "error") - navigate('/login') - } - } else { - addNotification('The connection attempt was cancelled', "warning") - navigate('/') - } - }) - } catch (error) { - console.error('Error initializing account linking consumer:', error) - addNotification('Failed to initialize device linking', "error") - } - } - - const handleSubmitUsername = (e: React.FormEvent) => { - e.preventDefault() - initAccountLinkingConsumer() - } - - // Clean up consumer on unmount - useEffect(() => { - return () => { - if (accountLinkingConsumer) { - accountLinkingConsumer.destroy() - } - } - }, [accountLinkingConsumer]) - - return ( -
- {view === 'enter-username' && ( - <> -

Link a New Device

-
-
- - setUsername(e.target.value)} - required - /> -
- -
- - )} - - {view === 'show-pin' && ( -
-

Enter this PIN on your other device

-
{displayPin}
-
- )} - - {view === 'load-filesystem' && ( -
-

Loading your filesystem...

-

Please wait while we connect to your account.

-
- )} -
- ) -} - -export default LinkDevice \ No newline at end of file diff --git a/src/components/auth/Register.tsx b/src/components/auth/Register.tsx deleted file mode 100644 index 9ae42b0..0000000 --- a/src/components/auth/Register.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React, { useState } from 'react' -import { register } from '../../lib/auth/account' - -const Register: React.FC = () => { - const [username, setUsername] = useState('') - const [checkingUsername, setCheckingUsername] = useState(false) - const [initializingFilesystem, setInitializingFilesystem] = useState(false) - const [error, setError] = useState(null) - - const handleRegister = async (e: React.FormEvent) => { - e.preventDefault() - - if (checkingUsername) { - return - } - - setInitializingFilesystem(true) - setError(null) - - try { - const success = await register(username) - - if (!success) { - setError('Registration failed. Username may be taken.') - setInitializingFilesystem(false) - } - } catch (err) { - setError('An error occurred during registration') - setInitializingFilesystem(false) - console.error(err) - } - } - - return ( -
-

Create an Account

- -
-
- - setUsername(e.target.value)} - disabled={initializingFilesystem} - required - /> -
- - {error &&
{error}
} - - -
-
- ) -} - -export default Register \ No newline at end of file diff --git a/src/components/location/LocationCapture.tsx b/src/components/location/LocationCapture.tsx deleted file mode 100644 index 0319f78..0000000 --- a/src/components/location/LocationCapture.tsx +++ /dev/null @@ -1,187 +0,0 @@ -"use client" - -import type React from "react" -import { useState, useEffect } from "react" -import { useAuth } from "@/context/AuthContext" -import { LocationStorageService, type LocationData } from "@/lib/location/locationStorage" -import type { GeolocationPosition } from "@/lib/location/types" - -interface LocationCaptureProps { - onLocationCaptured?: (location: LocationData) => void - onError?: (error: string) => void -} - -export const LocationCapture: React.FC = ({ onLocationCaptured, onError }) => { - const { session, fileSystem } = useAuth() - const [isCapturing, setIsCapturing] = useState(false) - const [permissionState, setPermissionState] = useState<"prompt" | "granted" | "denied">("prompt") - const [currentLocation, setCurrentLocation] = useState(null) - const [error, setError] = useState(null) - - // Show loading state while auth is initializing - if (session.loading) { - return ( -
-
-
-

Loading authentication...

-
-
- ) - } - - // Check permission status on mount - useEffect(() => { - if ("permissions" in navigator) { - navigator.permissions.query({ name: "geolocation" }).then((result) => { - setPermissionState(result.state as "prompt" | "granted" | "denied") - - result.addEventListener("change", () => { - setPermissionState(result.state as "prompt" | "granted" | "denied") - }) - }) - } - }, []) - - const captureLocation = async () => { - // Don't proceed if still loading - if (session.loading) { - return - } - - if (!session.authed) { - const errorMsg = "You must be logged in to share your location. Please log in and try again." - setError(errorMsg) - onError?.(errorMsg) - return - } - - if (!fileSystem) { - const errorMsg = "File system not available. Please refresh the page and try again." - setError(errorMsg) - onError?.(errorMsg) - return - } - - setIsCapturing(true) - setError(null) - - try { - // Request geolocation - const position = await new Promise((resolve, reject) => { - navigator.geolocation.getCurrentPosition( - (pos) => resolve(pos as GeolocationPosition), - (err) => reject(err), - { - enableHighAccuracy: true, - timeout: 10000, - maximumAge: 0, - }, - ) - }) - - setCurrentLocation(position) - - // Create location data - const locationData: LocationData = { - id: crypto.randomUUID(), - userId: session.username, - latitude: position.coords.latitude, - longitude: position.coords.longitude, - accuracy: position.coords.accuracy, - timestamp: position.timestamp, - expiresAt: null, // Will be set when creating a share - precision: "exact", - } - - // Save to filesystem - const storageService = new LocationStorageService(fileSystem) - await storageService.initialize() - await storageService.saveLocation(locationData) - - onLocationCaptured?.(locationData) - } catch (err: any) { - let errorMsg = "Failed to capture location" - - if (err.code === 1) { - errorMsg = "Location permission denied. Please enable location access in your browser settings." - setPermissionState("denied") - } else if (err.code === 2) { - errorMsg = "Location unavailable. Please check your device settings." - } else if (err.code === 3) { - errorMsg = "Location request timed out. Please try again." - } - - setError(errorMsg) - onError?.(errorMsg) - } finally { - setIsCapturing(false) - } - } - - return ( -
-
-

Share Your Location

-

Securely share your current location with others

-
- - {/* Permission status */} - {permissionState === "denied" && ( -
-

- Location access is blocked. Please enable it in your browser settings to continue. -

-
- )} - - {/* Current location display */} - {currentLocation && ( -
-

Current Location

-
-

- Latitude: {currentLocation.coords.latitude.toFixed(6)} -

-

- Longitude: {currentLocation.coords.longitude.toFixed(6)} -

-

- Accuracy: ±{Math.round(currentLocation.coords.accuracy)}m -

-

Captured {new Date(currentLocation.timestamp).toLocaleString()}

-
-
- )} - - {/* Error display */} - {error && ( -
-

{error}

-
- )} - - {/* Capture button */} - - - {!session.authed && ( -

Please log in to share your location

- )} -
- ) -} - - diff --git a/src/components/location/LocationDashboard.tsx b/src/components/location/LocationDashboard.tsx deleted file mode 100644 index b051b88..0000000 --- a/src/components/location/LocationDashboard.tsx +++ /dev/null @@ -1,270 +0,0 @@ -"use client" - -import type React from "react" -import { useState, useEffect } from "react" -import { useAuth } from "@/context/AuthContext" -import { LocationStorageService, type LocationData, type LocationShare } from "@/lib/location/locationStorage" -import { LocationMap } from "./LocationMap" - -interface ShareWithLocation { - share: LocationShare - location: LocationData -} - -export const LocationDashboard: React.FC = () => { - const { session, fileSystem } = useAuth() - const [shares, setShares] = useState([]) - const [loading, setLoading] = useState(true) - const [selectedShare, setSelectedShare] = useState(null) - const [error, setError] = useState(null) - - const loadShares = async () => { - if (!fileSystem) { - setError("File system not available") - setLoading(false) - return - } - - try { - const storageService = new LocationStorageService(fileSystem) - await storageService.initialize() - - // Get all shares - const allShares = await storageService.getAllShares() - - // Get locations for each share - const sharesWithLocations: ShareWithLocation[] = [] - - for (const share of allShares) { - const location = await storageService.getLocation(share.locationId) - if (location) { - sharesWithLocations.push({ share, location }) - } - } - - // Sort by creation date (newest first) - sharesWithLocations.sort((a, b) => b.share.createdAt - a.share.createdAt) - - setShares(sharesWithLocations) - setLoading(false) - } catch (err) { - console.error("Error loading shares:", err) - setError("Failed to load location shares") - setLoading(false) - } - } - - useEffect(() => { - if (session.authed && fileSystem) { - loadShares() - } - }, [session.authed, fileSystem]) - - const handleCopyLink = async (shareToken: string) => { - const baseUrl = window.location.origin - const link = `${baseUrl}/location/${shareToken}` - - try { - await navigator.clipboard.writeText(link) - alert("Link copied to clipboard!") - } catch (err) { - console.error("Failed to copy link:", err) - alert("Failed to copy link") - } - } - - const isExpired = (share: LocationShare): boolean => { - return share.expiresAt ? share.expiresAt < Date.now() : false - } - - const isMaxViewsReached = (share: LocationShare): boolean => { - return share.maxViews ? share.viewCount >= share.maxViews : false - } - - const getShareStatus = (share: LocationShare): { label: string; color: string } => { - if (isExpired(share)) { - return { label: "Expired", color: "text-destructive" } - } - if (isMaxViewsReached(share)) { - return { label: "Max Views Reached", color: "text-destructive" } - } - return { label: "Active", color: "text-green-600" } - } - - if (!session.authed) { - return ( -
-
-
🔒
-

Authentication Required

-

Please log in to view your location shares

-
-
- ) - } - - if (loading) { - return ( -
-
-
-

Loading your shares...

-
-
- ) - } - - if (error) { - return ( -
-
-
⚠️
-

Error Loading Dashboard

-

{error}

- -
-
- ) - } - - return ( -
-
-

Location Shares

-

Manage your shared locations and privacy settings

-
- - {shares.length === 0 ? ( -
-
📍
-

No Location Shares Yet

-

- You haven't shared any locations yet. Create your first share to get started. -

- - Share Your Location - -
- ) : ( -
- {/* Stats Overview */} -
-
-
Total Shares
-
{shares.length}
-
-
-
Active Shares
-
- {shares.filter((s) => !isExpired(s.share) && !isMaxViewsReached(s.share)).length} -
-
-
-
Total Views
-
- {shares.reduce((sum, s) => sum + s.share.viewCount, 0)} -
-
-
- - {/* Shares List */} -
- {shares.map(({ share, location }) => { - const status = getShareStatus(share) - const isSelected = selectedShare?.share.id === share.id - - return ( -
-
-
-
-

Location Share

- {status.label} -
-
-

Created: {new Date(share.createdAt).toLocaleString()}

- {share.expiresAt &&

Expires: {new Date(share.expiresAt).toLocaleString()}

} -

- Views: {share.viewCount} - {share.maxViews && ` / ${share.maxViews}`} -

-

- Precision: {share.precision} -

-
-
-
- - -
-
- - {isSelected && ( -
- -
- )} -
- ) - })} -
-
- )} -
- ) -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/components/location/LocationMap.tsx b/src/components/location/LocationMap.tsx deleted file mode 100644 index 998fa7b..0000000 --- a/src/components/location/LocationMap.tsx +++ /dev/null @@ -1,241 +0,0 @@ -"use client" - -import type React from "react" -import { useEffect, useRef, useState } from "react" -import type { LocationData } from "@/lib/location/locationStorage" -import { obfuscateLocation } from "@/lib/location/locationStorage" -import type { PrecisionLevel } from "@/lib/location/types" - -// Leaflet types -interface LeafletMap { - setView: (coords: [number, number], zoom: number) => void - remove: () => void -} - -interface LeafletMarker { - addTo: (map: LeafletMap) => LeafletMarker - bindPopup: (content: string) => LeafletMarker -} - -interface LeafletCircle { - addTo: (map: LeafletMap) => LeafletCircle -} - -interface LeafletTileLayer { - addTo: (map: LeafletMap) => LeafletTileLayer -} - -interface Leaflet { - map: (element: HTMLElement, options?: any) => LeafletMap - marker: (coords: [number, number], options?: any) => LeafletMarker - circle: (coords: [number, number], options?: any) => LeafletCircle - tileLayer: (url: string, options?: any) => LeafletTileLayer - icon: (options: any) => any -} - -declare global { - interface Window { - L?: Leaflet - } -} - -interface LocationMapProps { - location: LocationData - precision?: PrecisionLevel - showAccuracy?: boolean - height?: string -} - -export const LocationMap: React.FC = ({ - location, - precision = "exact", - showAccuracy = true, - height = "400px", -}) => { - const mapContainer = useRef(null) - const mapInstance = useRef(null) - const [isLoading, setIsLoading] = useState(true) - const [error, setError] = useState(null) - - useEffect(() => { - // Load Leaflet CSS and JS - const loadLeaflet = async () => { - try { - // Load CSS - if (!document.querySelector('link[href*="leaflet.css"]')) { - const link = document.createElement("link") - link.rel = "stylesheet" - link.href = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" - link.integrity = "sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" - link.crossOrigin = "" - document.head.appendChild(link) - } - - // Load JS - if (!window.L) { - await new Promise((resolve, reject) => { - const script = document.createElement("script") - script.src = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" - script.integrity = "sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" - script.crossOrigin = "" - script.onload = () => resolve() - script.onerror = () => reject(new Error("Failed to load Leaflet")) - document.head.appendChild(script) - }) - } - - setIsLoading(false) - } catch (err) { - setError("Failed to load map library") - setIsLoading(false) - } - } - - loadLeaflet() - }, []) - - useEffect(() => { - if (!mapContainer.current || !window.L || isLoading) return - - // Clean up existing map - if (mapInstance.current) { - mapInstance.current.remove() - } - - const L = window.L! - - // Get obfuscated location based on precision - const { lat, lng, radius } = obfuscateLocation(location.latitude, location.longitude, precision) - - // Create map - const map = L.map(mapContainer.current, { - center: [lat, lng], - zoom: precision === "exact" ? 15 : precision === "street" ? 14 : precision === "neighborhood" ? 12 : 10, - zoomControl: true, - attributionControl: true, - }) - - // Add OpenStreetMap tiles - L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { - attribution: '© OpenStreetMap contributors', - maxZoom: 19, - }).addTo(map) - - // Add marker - const marker = L.marker([lat, lng], { - icon: L.icon({ - iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png", - iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png", - shadowUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png", - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], - shadowSize: [41, 41], - }), - }).addTo(map) - - // Add popup with location info - const popupContent = ` -
- Shared Location
- - Precision: ${precision}
- ${new Date(location.timestamp).toLocaleString()} -
-
- ` - marker.bindPopup(popupContent) - - // Add accuracy circle if showing accuracy - if (showAccuracy && radius > 0) { - L.circle([lat, lng], { - radius: radius, - color: "#3b82f6", - fillColor: "#3b82f6", - fillOpacity: 0.1, - weight: 2, - }).addTo(map) - } - - mapInstance.current = map - - // Cleanup - return () => { - if (mapInstance.current) { - mapInstance.current.remove() - mapInstance.current = null - } - } - }, [location, precision, showAccuracy, isLoading]) - - if (error) { - return ( -
-

{error}

-
- ) - } - - if (isLoading) { - return ( -
-
-
-

Loading map...

-
-
- ) - } - - return ( -
-
-
-

- Showing {precision} location • Last updated {new Date(location.timestamp).toLocaleTimeString()} -

-
-
- ) -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/components/location/LocationShareDialog.tsx b/src/components/location/LocationShareDialog.tsx deleted file mode 100644 index 76f809a..0000000 --- a/src/components/location/LocationShareDialog.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { - TLUiDialogProps, - TldrawUiDialogBody, - TldrawUiDialogCloseButton, - TldrawUiDialogHeader, - TldrawUiDialogTitle, -} from "tldraw" -import React from "react" -import { ShareLocation } from "./ShareLocation" - -export function LocationShareDialog({ onClose: _onClose }: TLUiDialogProps) { - return ( - <> - - Share Location - - - - - - - ) -} - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/components/location/LocationViewer.tsx b/src/components/location/LocationViewer.tsx deleted file mode 100644 index 7ecf0ba..0000000 --- a/src/components/location/LocationViewer.tsx +++ /dev/null @@ -1,183 +0,0 @@ -"use client" - -import type React from "react" -import { useState, useEffect } from "react" -import { LocationMap } from "./LocationMap" -import type { LocationData, LocationShare } from "@/lib/location/locationStorage" -import { LocationStorageService } from "@/lib/location/locationStorage" -import { useAuth } from "@/context/AuthContext" - -interface LocationViewerProps { - shareToken: string -} - -export const LocationViewer: React.FC = ({ shareToken }) => { - const { fileSystem } = useAuth() - const [location, setLocation] = useState(null) - const [share, setShare] = useState(null) - const [loading, setLoading] = useState(true) - const [error, setError] = useState(null) - - useEffect(() => { - const loadSharedLocation = async () => { - if (!fileSystem) { - setError("File system not available") - setLoading(false) - return - } - - try { - const storageService = new LocationStorageService(fileSystem) - await storageService.initialize() - - // Get share by token - const shareData = await storageService.getShareByToken(shareToken) - if (!shareData) { - setError("Share not found or expired") - setLoading(false) - return - } - - // Check if share is expired - if (shareData.expiresAt && shareData.expiresAt < Date.now()) { - setError("This share has expired") - setLoading(false) - return - } - - // Check if max views reached - if (shareData.maxViews && shareData.viewCount >= shareData.maxViews) { - setError("This share has reached its maximum view limit") - setLoading(false) - return - } - - // Get location data - const locationData = await storageService.getLocation(shareData.locationId) - if (!locationData) { - setError("Location data not found") - setLoading(false) - return - } - - setShare(shareData) - setLocation(locationData) - - // Increment view count - await storageService.incrementShareViews(shareData.id) - - setLoading(false) - } catch (err) { - console.error("Error loading shared location:", err) - setError("Failed to load shared location") - setLoading(false) - } - } - - loadSharedLocation() - }, [shareToken, fileSystem]) - - if (loading) { - return ( -
-
-
-

Loading shared location...

-
-
- ) - } - - if (error) { - return ( -
-
-
📍
-

Unable to Load Location

-

{error}

-
-
- ) - } - - if (!location || !share) { - return null - } - - return ( -
-
-

Shared Location

-

Someone has shared their location with you

-
- -
- {/* Map Display */} - - - {/* Share Info */} -
-
- Precision Level: - {share.precision} -
-
- Views: - - {share.viewCount} {share.maxViews ? `/ ${share.maxViews}` : ""} - -
- {share.expiresAt && ( -
- Expires: - {new Date(share.expiresAt).toLocaleString()} -
- )} -
- Shared: - {new Date(share.createdAt).toLocaleString()} -
-
- - {/* Privacy Notice */} -
-

- This location is shared securely and will expire based on the sender's privacy settings. The location data - is stored in a decentralized filesystem and is only accessible via this unique link. -

-
-
-
- ) -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/components/location/ShareLocation.tsx b/src/components/location/ShareLocation.tsx deleted file mode 100644 index dcf24c1..0000000 --- a/src/components/location/ShareLocation.tsx +++ /dev/null @@ -1,279 +0,0 @@ -"use client" - -import React, { useState } from "react" -import { LocationCapture } from "./LocationCapture" -import { ShareSettingsComponent } from "./ShareSettings" -import { LocationMap } from "./LocationMap" -import type { LocationData, LocationShare } from "@/lib/location/locationStorage" -import { LocationStorageService, generateShareToken } from "@/lib/location/locationStorage" -import type { ShareSettings } from "@/lib/location/types" -import { useAuth } from "@/context/AuthContext" - -export const ShareLocation: React.FC = () => { - const { session, fileSystem } = useAuth() - const [step, setStep] = useState<"capture" | "settings" | "share">("capture") - const [capturedLocation, setCapturedLocation] = useState(null) - const [shareSettings, setShareSettings] = useState({ - duration: 24 * 3600000, // 24 hours - maxViews: null, - precision: "street", - }) - const [shareLink, setShareLink] = useState(null) - const [isCreatingShare, setIsCreatingShare] = useState(false) - const [error, setError] = useState(null) - - // Show loading state while auth is initializing - if (session.loading) { - return ( -
-
-
-

Loading...

-

Initializing authentication

-
-
- ) - } - - const handleLocationCaptured = (location: LocationData) => { - setCapturedLocation(location) - setStep("settings") - } - - const handleCreateShare = async () => { - if (!capturedLocation || !fileSystem) { - setError("Location or filesystem not available") - return - } - - setIsCreatingShare(true) - setError(null) - - try { - const storageService = new LocationStorageService(fileSystem) - await storageService.initialize() - - // Generate share token - const shareToken = generateShareToken() - - // Calculate expiration - const expiresAt = shareSettings.duration ? Date.now() + shareSettings.duration : null - - // Update location with expiration - const updatedLocation: LocationData = { - ...capturedLocation, - expiresAt, - precision: shareSettings.precision, - } - - await storageService.saveLocation(updatedLocation) - - // Create share - const share: LocationShare = { - id: crypto.randomUUID(), - locationId: capturedLocation.id, - shareToken, - createdAt: Date.now(), - expiresAt, - maxViews: shareSettings.maxViews, - viewCount: 0, - precision: shareSettings.precision, - } - - await storageService.createShare(share) - - // Generate share link - const baseUrl = window.location.origin - const link = `${baseUrl}/location/${shareToken}` - - setShareLink(link) - setStep("share") - } catch (err) { - console.error("Error creating share:", err) - setError("Failed to create share link") - } finally { - setIsCreatingShare(false) - } - } - - const handleCopyLink = async () => { - if (!shareLink) return - - try { - await navigator.clipboard.writeText(shareLink) - // Could add a toast notification here - alert("Link copied to clipboard!") - } catch (err) { - console.error("Failed to copy link:", err) - alert("Failed to copy link. Please copy manually.") - } - } - - const handleReset = () => { - setStep("capture") - setCapturedLocation(null) - setShareLink(null) - setError(null) - } - - if (!session.authed) { - return ( -
-
-
🔒
-

Authentication Required

-

Please log in to share your location securely

-
-
- ) - } - - return ( -
- {/* Progress Steps */} -
- {["capture", "settings", "share"].map((s, index) => ( - -
-
- {index + 1} -
- - {s} - -
- {index < 2 && ( -
- )} - - ))} -
- - {/* Error Display */} - {error && ( -
-

{error}

-
- )} - - {/* Step Content */} -
- {step === "capture" && } - - {step === "settings" && capturedLocation && ( -
-
-

Preview Your Location

- -
- - - -
- - -
-
- )} - - {step === "share" && shareLink && capturedLocation && ( -
-
-
-

Share Link Created!

-

Your location is ready to share securely

-
- -
- -
- e.currentTarget.select()} - /> - -
-
- -
-

Location Preview

- -
- -
-

Share Settings

-
- Precision: - {shareSettings.precision} -
-
- Duration: - - {shareSettings.duration ? `${shareSettings.duration / 3600000} hours` : "No expiration"} - -
-
- Max Views: - {shareSettings.maxViews || "Unlimited"} -
-
- - -
- )} -
-
- ) -} - - diff --git a/src/components/location/ShareSettings.tsx b/src/components/location/ShareSettings.tsx deleted file mode 100644 index 9e2d0e9..0000000 --- a/src/components/location/ShareSettings.tsx +++ /dev/null @@ -1,150 +0,0 @@ -"use client" - -import React, { useState } from "react" -import type { ShareSettings, PrecisionLevel } from "@/lib/location/types" - -interface ShareSettingsProps { - onSettingsChange: (settings: ShareSettings) => void - initialSettings?: Partial -} - -export const ShareSettingsComponent: React.FC = ({ onSettingsChange, initialSettings = {} }) => { - const [duration, setDuration] = useState( - initialSettings.duration ? String(initialSettings.duration / 3600000) : "24", - ) - const [maxViews, setMaxViews] = useState( - initialSettings.maxViews ? String(initialSettings.maxViews) : "unlimited", - ) - const [precision, setPrecision] = useState(initialSettings.precision || "street") - - const handleChange = () => { - const settings: ShareSettings = { - duration: duration === "unlimited" ? null : Number(duration) * 3600000, - maxViews: maxViews === "unlimited" ? null : Number(maxViews), - precision, - } - onSettingsChange(settings) - } - - React.useEffect(() => { - handleChange() - }, [duration, maxViews, precision]) - - return ( -
-
-

Privacy Settings

-

Control how your location is shared

-
- - {/* Precision Level */} -
- -
- {[ - { value: "exact", label: "Exact Location", desc: "Share precise coordinates" }, - { value: "street", label: "Street Level", desc: "~100m radius" }, - { value: "neighborhood", label: "Neighborhood", desc: "~1km radius" }, - { value: "city", label: "City Level", desc: "~10km radius" }, - ].map((option) => ( - - ))} -
-
- - {/* Duration */} -
- - -
- - {/* Max Views */} -
- - -
- - {/* Privacy Notice */} -
-

- Your location data is stored securely in your private filesystem. Only people with the share link can view - your location, and shares automatically expire based on your settings. -

-
-
- ) -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/context/AuthContext.tsx b/src/context/AuthContext.tsx index 9c08fb1..52c1485 100644 --- a/src/context/AuthContext.tsx +++ b/src/context/AuthContext.tsx @@ -1,5 +1,4 @@ import React, { createContext, useContext, useState, useEffect, useCallback, useMemo, ReactNode } from 'react'; -import type FileSystem from '@oddjs/odd/fs/index'; import { Session, SessionError } from '../lib/auth/types'; import { AuthService } from '../lib/auth/authService'; import { saveSession, clearStoredSession } from '../lib/auth/sessionPersistence'; @@ -9,8 +8,6 @@ interface AuthContextType { setSession: (updatedSession: Partial) => void; updateSession: (updatedSession: Partial) => void; clearSession: () => void; - fileSystem: FileSystem | null; - setFileSystem: (fs: FileSystem | null) => void; initialize: () => Promise; login: (username: string) => Promise; register: (username: string) => Promise; @@ -30,47 +27,40 @@ export const AuthContext = createContext(undefined) export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => { const [session, setSessionState] = useState(initialSession); - const [fileSystem, setFileSystemState] = useState(null); // Update session with partial data const setSession = useCallback((updatedSession: Partial) => { setSessionState(prev => { const newSession = { ...prev, ...updatedSession }; - + // Save session to localStorage if authenticated if (newSession.authed && newSession.username) { saveSession(newSession); } - + return newSession; }); }, []); - // Set file system - const setFileSystem = useCallback((fs: FileSystem | null) => { - setFileSystemState(fs); - }, []); - /** * Initialize the authentication state */ const initialize = useCallback(async (): Promise => { setSessionState(prev => ({ ...prev, loading: true })); - + try { - const { session: newSession, fileSystem: newFs } = await AuthService.initialize(); + const { session: newSession } = await AuthService.initialize(); setSessionState(newSession); - setFileSystemState(newFs); - + // Save session to localStorage if authenticated if (newSession.authed && newSession.username) { saveSession(newSession); } } catch (error) { console.error('Auth initialization error:', error); - setSessionState(prev => ({ + setSessionState(prev => ({ ...prev, - loading: false, + loading: false, authed: false, error: error as SessionError })); @@ -82,21 +72,20 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => */ const login = useCallback(async (username: string): Promise => { setSessionState(prev => ({ ...prev, loading: true })); - + try { const result = await AuthService.login(username); - - if (result.success && result.session && result.fileSystem) { + + if (result.success && result.session) { setSessionState(result.session); - setFileSystemState(result.fileSystem); - + // Save session to localStorage if authenticated if (result.session.authed && result.session.username) { saveSession(result.session); } return true; } else { - setSessionState(prev => ({ + setSessionState(prev => ({ ...prev, loading: false, error: result.error as SessionError @@ -105,7 +94,7 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => } } catch (error) { console.error('Login error:', error); - setSessionState(prev => ({ + setSessionState(prev => ({ ...prev, loading: false, error: error as SessionError @@ -119,21 +108,20 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => */ const register = useCallback(async (username: string): Promise => { setSessionState(prev => ({ ...prev, loading: true })); - + try { const result = await AuthService.register(username); - - if (result.success && result.session && result.fileSystem) { + + if (result.success && result.session) { setSessionState(result.session); - setFileSystemState(result.fileSystem); - + // Save session to localStorage if authenticated if (result.session.authed && result.session.username) { saveSession(result.session); } return true; } else { - setSessionState(prev => ({ + setSessionState(prev => ({ ...prev, loading: false, error: result.error as SessionError @@ -142,7 +130,7 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => } } catch (error) { console.error('Register error:', error); - setSessionState(prev => ({ + setSessionState(prev => ({ ...prev, loading: false, error: error as SessionError @@ -164,7 +152,6 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => obsidianVaultPath: undefined, obsidianVaultName: undefined }); - setFileSystemState(null); }, []); /** @@ -200,13 +187,11 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => setSession, updateSession: setSession, clearSession, - fileSystem, - setFileSystem, initialize, login, register, logout - }), [session, setSession, clearSession, fileSystem, setFileSystem, initialize, login, register, logout]); + }), [session, setSession, clearSession, initialize, login, register, logout]); return ( @@ -221,4 +206,4 @@ export const useAuth = (): AuthContextType => { throw new Error('useAuth must be used within an AuthProvider'); } return context; -}; \ No newline at end of file +}; diff --git a/src/lib/auth/account.ts b/src/lib/auth/account.ts deleted file mode 100644 index 3e9d0c5..0000000 --- a/src/lib/auth/account.ts +++ /dev/null @@ -1,259 +0,0 @@ -import * as odd from '@oddjs/odd'; -import type FileSystem from '@oddjs/odd/fs/index'; -import { asyncDebounce } from '../utils/asyncDebounce'; -import * as browser from '../utils/browser'; -import { DIRECTORIES } from '../../context/FileSystemContext'; - -/** - * Constants for filesystem paths - */ -export const ACCOUNT_SETTINGS_DIR = ['private', 'settings']; -export const GALLERY_DIRS = { - PUBLIC: ['public', 'gallery'], - PRIVATE: ['private', 'gallery'] -}; -export const AREAS = { - PUBLIC: 'public', - PRIVATE: 'private' -}; - -/** - * Checks if a username is valid according to ODD's rules - * @param username The username to check - * @returns A boolean indicating if the username is valid - */ -export const isUsernameValid = async (username: string): Promise => { - console.log('Checking if username is valid:', username); - try { - // Fallback if ODD account functions are not available - if (odd.account && odd.account.isUsernameValid) { - const isValid = await odd.account.isUsernameValid(username); - console.log('Username validity check result:', isValid); - return Boolean(isValid); - } - // Default validation if ODD is not available - const usernameRegex = /^[a-zA-Z0-9_-]{3,20}$/; - const isValid = usernameRegex.test(username); - console.log('Username validity check result (fallback):', isValid); - return isValid; - } catch (error) { - console.error('Error checking username validity:', error); - return false; - } -}; - -/** - * Debounced function to check if a username is available - */ -const debouncedIsUsernameAvailable = asyncDebounce( - (username: string) => { - // Fallback if ODD account functions are not available - if (odd.account && odd.account.isUsernameAvailable) { - return odd.account.isUsernameAvailable(username); - } - // Default to true if ODD is not available - return Promise.resolve(true); - }, - 300 -); - -/** - * Checks if a username is available - * @param username The username to check - * @returns A boolean indicating if the username is available - */ -export const isUsernameAvailable = async ( - username: string -): Promise => { - console.log('Checking if username is available:', username); - try { - // In a local development environment, simulate the availability check - // by checking if the username exists in localStorage - if (browser.isBrowser()) { - const isAvailable = await browser.isUsernameAvailable(username); - console.log('Username availability check result:', isAvailable); - return isAvailable; - } else { - // If not in a browser (SSR), use the ODD API - const isAvailable = await debouncedIsUsernameAvailable(username); - console.log('Username availability check result:', isAvailable); - return Boolean(isAvailable); - } - } catch (error) { - console.error('Error checking username availability:', error); - return false; - } -}; - -/** - * Create additional directories and files needed by the app - * @param fs FileSystem - */ -export const initializeFilesystem = async (fs: FileSystem): Promise => { - try { - // Create required directories - console.log('Creating required directories...'); - - // Fallback if ODD path is not available - if (!odd.path || !odd.path.directory) { - console.log('ODD path not available, skipping filesystem initialization'); - return; - } - - // Public directories - await fs.mkdir(odd.path.directory(...DIRECTORIES.PUBLIC.ROOT)); - await fs.mkdir(odd.path.directory(...DIRECTORIES.PUBLIC.GALLERY)); - await fs.mkdir(odd.path.directory(...DIRECTORIES.PUBLIC.DOCUMENTS)); - - // Private directories - await fs.mkdir(odd.path.directory(...DIRECTORIES.PRIVATE.ROOT)); - await fs.mkdir(odd.path.directory(...DIRECTORIES.PRIVATE.GALLERY)); - await fs.mkdir(odd.path.directory(...DIRECTORIES.PRIVATE.SETTINGS)); - await fs.mkdir(odd.path.directory(...DIRECTORIES.PRIVATE.DOCUMENTS)); - - console.log('Filesystem initialized successfully'); - } catch (error) { - console.error('Error during filesystem initialization:', error); - throw error; - } -}; - -/** - * Checks data root for a username with retries - * @param username The username to check - */ -export const checkDataRoot = async (username: string): Promise => { - console.log('Looking up data root for username:', username); - - // Fallback if ODD dataRoot is not available - if (!odd.dataRoot || !odd.dataRoot.lookup) { - console.log('ODD dataRoot not available, skipping data root lookup'); - return; - } - - let dataRoot = await odd.dataRoot.lookup(username); - console.log('Initial data root lookup result:', dataRoot ? 'found' : 'not found'); - - if (dataRoot) return; - - console.log('Data root not found, starting retry process...'); - return new Promise((resolve, reject) => { - const maxRetries = 20; - let attempt = 0; - - const dataRootInterval = setInterval(async () => { - console.warn(`Could not fetch filesystem data root. Retrying (${attempt + 1}/${maxRetries})`); - - dataRoot = await odd.dataRoot.lookup(username); - console.log(`Retry ${attempt + 1} result:`, dataRoot ? 'found' : 'not found'); - - if (!dataRoot && attempt < maxRetries) { - attempt++; - return; - } - - console.log(`Retry process completed. Data root ${dataRoot ? 'found' : 'not found'} after ${attempt + 1} attempts`); - clearInterval(dataRootInterval); - - if (dataRoot) { - resolve(); - } else { - reject(new Error(`Data root not found after ${maxRetries} attempts`)); - } - }, 500); - }); -}; - -/** - * Generate a cryptographic key pair and store in localStorage during registration - * @param username The username being registered - */ -export const generateUserCredentials = async (username: string): Promise => { - if (!browser.isBrowser()) return false; - - try { - console.log('Generating cryptographic keys for user...'); - // Generate a key pair using Web Crypto API - const keyPair = await browser.generateKeyPair(); - - if (!keyPair) { - console.error('Failed to generate key pair'); - return false; - } - - // Export the public key - const publicKeyBase64 = await browser.exportPublicKey(keyPair.publicKey); - - if (!publicKeyBase64) { - console.error('Failed to export public key'); - return false; - } - - console.log('Keys generated successfully'); - - // Store the username and public key - browser.addRegisteredUser(username); - browser.storePublicKey(username, publicKeyBase64); - - return true; - } catch (error) { - console.error('Error generating user credentials:', error); - return false; - } -}; - -/** - * Validate a user's stored credentials (for development mode) - * @param username The username to validate - */ -export const validateStoredCredentials = (username: string): boolean => { - if (!browser.isBrowser()) return false; - - try { - const users = browser.getRegisteredUsers(); - const publicKey = browser.getPublicKey(username); - - return users.includes(username) && Boolean(publicKey); - } catch (error) { - console.error('Error validating stored credentials:', error); - return false; - } -}; - -/** - * Register a new user with the specified username - * @param username The username to register - * @returns A boolean indicating if registration was successful - */ -export const register = async (username: string): Promise => { - try { - console.log('Registering user:', username); - - // Check if username is valid - const isValid = await isUsernameValid(username); - if (!isValid) { - console.error('Invalid username format'); - return false; - } - - // Check if username is available - const isAvailable = await isUsernameAvailable(username); - if (!isAvailable) { - console.error('Username is not available'); - return false; - } - - // Generate user credentials - const credentialsGenerated = await generateUserCredentials(username); - if (!credentialsGenerated) { - console.error('Failed to generate user credentials'); - return false; - } - - console.log('User registration successful'); - return true; - } catch (error) { - console.error('Error during user registration:', error); - return false; - } -}; \ No newline at end of file diff --git a/src/lib/auth/authService.ts b/src/lib/auth/authService.ts index 3ed120e..11d0d2c 100644 --- a/src/lib/auth/authService.ts +++ b/src/lib/auth/authService.ts @@ -1,10 +1,6 @@ -import * as odd from '@oddjs/odd'; -import type FileSystem from '@oddjs/odd/fs/index'; -import { checkDataRoot, initializeFilesystem, isUsernameValid, isUsernameAvailable } from './account'; -import { getBackupStatus } from './backup'; import { Session } from './types'; import { CryptoAuthService } from './cryptoAuthService'; -import { loadSession, saveSession, clearStoredSession, getStoredUsername } from './sessionPersistence'; +import { loadSession, saveSession, clearStoredSession } from './sessionPersistence'; export class AuthService { /** @@ -12,91 +8,32 @@ export class AuthService { */ static async initialize(): Promise<{ session: Session; - fileSystem: FileSystem | null; }> { - // First try to load stored session + // Try to load stored session const storedSession = loadSession(); let session: Session; - let fileSystem: FileSystem | null = null; if (storedSession && storedSession.authed && storedSession.username) { - // Try to restore ODD session with stored username - try { - const program = await odd.program({ - namespace: { creator: 'mycrozine', name: 'app' }, - username: storedSession.username - }); - - if (program.session) { - // ODD session restored successfully - fileSystem = program.session.fs; - const backupStatus = await getBackupStatus(fileSystem); - session = { - username: storedSession.username, - authed: true, - loading: false, - backupCreated: backupStatus.created, - obsidianVaultPath: storedSession.obsidianVaultPath, - obsidianVaultName: storedSession.obsidianVaultName - }; - } else { - // ODD session not available, but we have crypto auth - session = { - username: storedSession.username, - authed: true, - loading: false, - backupCreated: storedSession.backupCreated, - obsidianVaultPath: storedSession.obsidianVaultPath, - obsidianVaultName: storedSession.obsidianVaultName - }; - } - } catch (oddError) { - // ODD session restoration failed, using stored session - session = { - username: storedSession.username, - authed: true, - loading: false, - backupCreated: storedSession.backupCreated, - obsidianVaultPath: storedSession.obsidianVaultPath, - obsidianVaultName: storedSession.obsidianVaultName - }; - } + // Restore existing session + session = { + username: storedSession.username, + authed: true, + loading: false, + backupCreated: storedSession.backupCreated, + obsidianVaultPath: storedSession.obsidianVaultPath, + obsidianVaultName: storedSession.obsidianVaultName + }; } else { - // No stored session, try ODD initialization - try { - const program = await odd.program({ - namespace: { creator: 'mycrozine', name: 'app' } - }); - - if (program.session) { - fileSystem = program.session.fs; - const backupStatus = await getBackupStatus(fileSystem); - session = { - username: program.session.username, - authed: true, - loading: false, - backupCreated: backupStatus.created - }; - } else { - session = { - username: '', - authed: false, - loading: false, - backupCreated: null - }; - } - } catch (error) { - session = { - username: '', - authed: false, - loading: false, - backupCreated: null, - error: String(error) - }; - } + // No stored session + session = { + username: '', + authed: false, + loading: false, + backupCreated: null + }; } - return { session, fileSystem }; + return { session }; } /** @@ -105,81 +42,25 @@ export class AuthService { static async login(username: string): Promise<{ success: boolean; session?: Session; - fileSystem?: FileSystem; error?: string; }> { try { - // First try cryptographic authentication + // Use cryptographic authentication const cryptoResult = await CryptoAuthService.login(username); - + if (cryptoResult.success && cryptoResult.session) { - // If crypto auth succeeds, also try to load ODD session - try { - const program = await odd.program({ - namespace: { creator: 'mycrozine', name: 'app' }, - username - }); - - if (program.session) { - const fs = program.session.fs; - const backupStatus = await getBackupStatus(fs); - - return { - success: true, - session: { - username, - authed: true, - loading: false, - backupCreated: backupStatus.created - }, - fileSystem: fs - }; - } - } catch (oddError) { - // ODD session not available, using crypto auth only - } - - // Return crypto auth result if ODD is not available const session = cryptoResult.session; - if (session) { - saveSession(session); - } + saveSession(session); return { success: true, - session: cryptoResult.session, - fileSystem: undefined - }; - } - - // Fallback to ODD authentication - const program = await odd.program({ - namespace: { creator: 'mycrozine', name: 'app' }, - username - }); - - if (program.session) { - const fs = program.session.fs; - const backupStatus = await getBackupStatus(fs); - - const session = { - username, - authed: true, - loading: false, - backupCreated: backupStatus.created - }; - saveSession(session); - - return { - success: true, - session, - fileSystem: fs - }; - } else { - return { - success: false, - error: cryptoResult.error || 'Failed to authenticate' + session: cryptoResult.session }; } + + return { + success: false, + error: cryptoResult.error || 'Failed to authenticate' + }; } catch (error) { return { success: false, @@ -194,99 +75,33 @@ export class AuthService { static async register(username: string): Promise<{ success: boolean; session?: Session; - fileSystem?: FileSystem; error?: string; }> { try { - // Validate username - const valid = await isUsernameValid(username); - if (!valid) { + // Validate username format (basic check) + if (!username || username.length < 3) { return { success: false, - error: 'Invalid username format' + error: 'Username must be at least 3 characters' }; } - - // First try cryptographic registration + + // Use cryptographic registration const cryptoResult = await CryptoAuthService.register(username); - + if (cryptoResult.success && cryptoResult.session) { - // If crypto registration succeeds, also try to create ODD session - try { - const program = await odd.program({ - namespace: { creator: 'mycrozine', name: 'app' }, - username - }); - - if (program.session) { - const fs = program.session.fs; - - // Initialize filesystem with required directories - await initializeFilesystem(fs); - - // Check backup status - const backupStatus = await getBackupStatus(fs); - - return { - success: true, - session: { - username, - authed: true, - loading: false, - backupCreated: backupStatus.created - }, - fileSystem: fs - }; - } - } catch (oddError) { - // ODD session creation failed, using crypto auth only - } - - // Return crypto registration result if ODD is not available const session = cryptoResult.session; - if (session) { - saveSession(session); - } - return { - success: true, - session: cryptoResult.session, - fileSystem: undefined - }; - } - - // Fallback to ODD-only registration - const program = await odd.program({ - namespace: { creator: 'mycrozine', name: 'app' }, - username - }); - - if (program.session) { - const fs = program.session.fs; - - // Initialize filesystem with required directories - await initializeFilesystem(fs); - - // Check backup status - const backupStatus = await getBackupStatus(fs); - - const session = { - username, - authed: true, - loading: false, - backupCreated: backupStatus.created - }; saveSession(session); return { success: true, - session, - fileSystem: fs - }; - } else { - return { - success: false, - error: cryptoResult.error || 'Failed to create account' + session: cryptoResult.session }; } + + return { + success: false, + error: cryptoResult.error || 'Failed to create account' + }; } catch (error) { return { success: false, @@ -302,17 +117,9 @@ export class AuthService { try { // Clear stored session clearStoredSession(); - - // Try to destroy ODD session - try { - await odd.session.destroy(); - } catch (oddError) { - // ODD session destroy failed - } - return true; } catch (error) { return false; } } -} \ No newline at end of file +} diff --git a/src/lib/auth/backup.ts b/src/lib/auth/backup.ts deleted file mode 100644 index 47266fd..0000000 --- a/src/lib/auth/backup.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as odd from '@oddjs/odd' - -export type BackupStatus = { - created: boolean | null -} - -export const getBackupStatus = async (fs: odd.FileSystem): Promise => { - try { - // Check if the required methods exist - if ((fs as any).exists && odd.path && (odd.path as any).backups) { - const backupStatus = await (fs as any).exists((odd.path as any).backups()); - return { created: backupStatus }; - } - - // Fallback if methods don't exist - console.warn('Backup methods not available in current ODD version'); - return { created: null }; - } catch (error) { - console.error('Error checking backup status:', error); - return { created: null }; - } -} \ No newline at end of file diff --git a/src/lib/auth/linking.ts b/src/lib/auth/linking.ts deleted file mode 100644 index 12d9f26..0000000 --- a/src/lib/auth/linking.ts +++ /dev/null @@ -1,58 +0,0 @@ -import * as odd from '@oddjs/odd'; - -/** - * Creates an account linking consumer for the specified username - * @param username The username to create a consumer for - * @returns A Promise resolving to an AccountLinkingConsumer-like object - */ -export const createAccountLinkingConsumer = async ( - username: string -): Promise => { - // Check if the method exists in the current ODD version - if (odd.account && typeof (odd.account as any).createConsumer === 'function') { - return await (odd.account as any).createConsumer({ username }); - } - - // Fallback: create a mock consumer for development - console.warn('Account linking consumer not available in current ODD version, using mock implementation'); - return { - on: (event: string, callback: Function) => { - // Mock event handling - if (event === 'challenge') { - // Simulate PIN challenge - setTimeout(() => callback({ pin: [1, 2, 3, 4] }), 1000); - } else if (event === 'link') { - // Simulate successful link - setTimeout(() => callback({ approved: true, username }), 2000); - } - }, - destroy: () => { - // Cleanup mock consumer - } - }; -}; - -/** - * Creates an account linking producer for the specified username - * @param username The username to create a producer for - * @returns A Promise resolving to an AccountLinkingProducer-like object - */ -export const createAccountLinkingProducer = async ( - username: string -): Promise => { - // Check if the method exists in the current ODD version - if (odd.account && typeof (odd.account as any).createProducer === 'function') { - return await (odd.account as any).createProducer({ username }); - } - - // Fallback: create a mock producer for development - console.warn('Account linking producer not available in current ODD version, using mock implementation'); - return { - on: (_event: string, _callback: Function) => { - // Mock event handling - parameters unused in mock implementation - }, - destroy: () => { - // Cleanup mock producer - } - }; -}; \ No newline at end of file diff --git a/src/lib/location/locationStorage.ts b/src/lib/location/locationStorage.ts deleted file mode 100644 index 02bbc10..0000000 --- a/src/lib/location/locationStorage.ts +++ /dev/null @@ -1,302 +0,0 @@ -import type FileSystem from '@oddjs/odd/fs/index'; -import * as odd from '@oddjs/odd'; -import type { PrecisionLevel } from './types'; - -/** - * Location data stored in the filesystem - */ -export interface LocationData { - id: string; - userId: string; - latitude: number; - longitude: number; - accuracy: number; - timestamp: number; - expiresAt: number | null; - precision: PrecisionLevel; -} - -/** - * Location share metadata - */ -export interface LocationShare { - id: string; - locationId: string; - shareToken: string; - createdAt: number; - expiresAt: number | null; - maxViews: number | null; - viewCount: number; - precision: PrecisionLevel; -} - -/** - * Location storage service - * Handles storing and retrieving locations from the ODD.js filesystem - */ -export class LocationStorageService { - private fs: FileSystem; - private locationsPath: string[]; - private sharesPath: string[]; - private publicSharesPath: string[]; - - constructor(fs: FileSystem) { - this.fs = fs; - // Private storage paths - this.locationsPath = ['private', 'locations']; - this.sharesPath = ['private', 'location-shares']; - // Public reference path for share validation - this.publicSharesPath = ['public', 'location-shares']; - } - - /** - * Initialize directories - */ - async initialize(): Promise { - // Ensure private directories exist - await this.ensureDirectory(this.locationsPath); - await this.ensureDirectory(this.sharesPath); - // Ensure public directory for share references - await this.ensureDirectory(this.publicSharesPath); - } - - /** - * Ensure a directory exists - */ - private async ensureDirectory(path: string[]): Promise { - try { - const dirPath = odd.path.directory(...path); - const fs = this.fs as any; - const exists = await fs.exists(dirPath); - if (!exists) { - await fs.mkdir(dirPath); - } - } catch (error) { - console.error('Error ensuring directory:', error); - throw error; - } - } - - /** - * Save a location to the filesystem - */ - async saveLocation(location: LocationData): Promise { - try { - const filePath = (odd.path as any).file(...this.locationsPath, `${location.id}.json`); - const content = new TextEncoder().encode(JSON.stringify(location, null, 2)); - const fs = this.fs as any; - await fs.write(filePath, content); - await fs.publish(); - } catch (error) { - console.error('Error saving location:', error); - throw error; - } - } - - /** - * Get a location by ID - */ - async getLocation(locationId: string): Promise { - try { - const filePath = (odd.path as any).file(...this.locationsPath, `${locationId}.json`); - const fs = this.fs as any; - const exists = await fs.exists(filePath); - if (!exists) { - return null; - } - const content = await fs.read(filePath); - const text = new TextDecoder().decode(content as Uint8Array); - return JSON.parse(text) as LocationData; - } catch (error) { - console.error('Error reading location:', error); - return null; - } - } - - /** - * Create a location share - */ - async createShare(share: LocationShare): Promise { - try { - // Save share metadata in private directory - const sharePath = (odd.path as any).file(...this.sharesPath, `${share.id}.json`); - const shareContent = new TextEncoder().encode(JSON.stringify(share, null, 2)); - const fs = this.fs as any; - await fs.write(sharePath, shareContent); - - // Create public reference file for share validation (only token, not full data) - const publicSharePath = (odd.path as any).file(...this.publicSharesPath, `${share.shareToken}.json`); - const publicShareRef = { - shareToken: share.shareToken, - shareId: share.id, - createdAt: share.createdAt, - expiresAt: share.expiresAt, - }; - const publicContent = new TextEncoder().encode(JSON.stringify(publicShareRef, null, 2)); - await fs.write(publicSharePath, publicContent); - - await fs.publish(); - } catch (error) { - console.error('Error creating share:', error); - throw error; - } - } - - /** - * Get a share by token - */ - async getShareByToken(shareToken: string): Promise { - try { - // First check public reference - const publicSharePath = (odd.path as any).file(...this.publicSharesPath, `${shareToken}.json`); - const fs = this.fs as any; - const publicExists = await fs.exists(publicSharePath); - if (!publicExists) { - return null; - } - - const publicContent = await fs.read(publicSharePath); - const publicText = new TextDecoder().decode(publicContent as Uint8Array); - const publicRef = JSON.parse(publicText); - - // Now get full share from private directory - const sharePath = (odd.path as any).file(...this.sharesPath, `${publicRef.shareId}.json`); - const shareExists = await fs.exists(sharePath); - if (!shareExists) { - return null; - } - - const shareContent = await fs.read(sharePath); - const shareText = new TextDecoder().decode(shareContent as Uint8Array); - return JSON.parse(shareText) as LocationShare; - } catch (error) { - console.error('Error reading share:', error); - return null; - } - } - - /** - * Get all shares for the current user - */ - async getAllShares(): Promise { - try { - const dirPath = odd.path.directory(...this.sharesPath); - const fs = this.fs as any; - const exists = await fs.exists(dirPath); - if (!exists) { - return []; - } - - const files = await fs.ls(dirPath); - const shares: LocationShare[] = []; - - for (const fileName of Object.keys(files)) { - if (fileName.endsWith('.json')) { - const shareId = fileName.replace('.json', ''); - const share = await this.getShareById(shareId); - if (share) { - shares.push(share); - } - } - } - - return shares; - } catch (error) { - console.error('Error listing shares:', error); - return []; - } - } - - /** - * Get a share by ID - */ - private async getShareById(shareId: string): Promise { - try { - const sharePath = (odd.path as any).file(...this.sharesPath, `${shareId}.json`); - const fs = this.fs as any; - const exists = await fs.exists(sharePath); - if (!exists) { - return null; - } - const content = await fs.read(sharePath); - const text = new TextDecoder().decode(content as Uint8Array); - return JSON.parse(text) as LocationShare; - } catch (error) { - console.error('Error reading share:', error); - return null; - } - } - - /** - * Increment view count for a share - */ - async incrementShareViews(shareId: string): Promise { - try { - const share = await this.getShareById(shareId); - if (!share) { - throw new Error('Share not found'); - } - - share.viewCount += 1; - await this.createShare(share); // Re-save the share - } catch (error) { - console.error('Error incrementing share views:', error); - throw error; - } - } -} - -/** - * Obfuscate location based on precision level - */ -export function obfuscateLocation( - lat: number, - lng: number, - precision: PrecisionLevel -): { lat: number; lng: number; radius: number } { - let radius = 0; - - switch (precision) { - case 'exact': - radius = 0; - break; - case 'street': - radius = 100; // ~100m radius - break; - case 'neighborhood': - radius = 1000; // ~1km radius - break; - case 'city': - radius = 10000; // ~10km radius - break; - } - - if (radius === 0) { - return { lat, lng, radius: 0 }; - } - - // Add random offset within the radius - const angle = Math.random() * 2 * Math.PI; - const distance = Math.random() * radius; - - // Convert distance to degrees (rough approximation: 1 degree ≈ 111km) - const latOffset = (distance / 111000) * Math.cos(angle); - const lngOffset = (distance / (111000 * Math.cos(lat * Math.PI / 180))) * Math.sin(angle); - - return { - lat: lat + latOffset, - lng: lng + lngOffset, - radius, - }; -} - -/** - * Generate a secure share token - */ -export function generateShareToken(): string { - // Generate a cryptographically secure random token - const array = new Uint8Array(32); - crypto.getRandomValues(array); - return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join(''); -} - diff --git a/src/lib/location/types.ts b/src/lib/location/types.ts deleted file mode 100644 index 52f8393..0000000 --- a/src/lib/location/types.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Location sharing types - */ - -export type PrecisionLevel = "exact" | "street" | "neighborhood" | "city"; - -export interface ShareSettings { - duration: number | null; // Duration in milliseconds - maxViews: number | null; // Maximum number of views allowed - precision: PrecisionLevel; // Precision level for location obfuscation -} - -export interface GeolocationPosition { - coords: { - latitude: number; - longitude: number; - accuracy: number; - altitude?: number | null; - altitudeAccuracy?: number | null; - heading?: number | null; - speed?: number | null; - }; - timestamp: number; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/routes/Board.tsx b/src/routes/Board.tsx index f0fea4b..3a297cf 100644 --- a/src/routes/Board.tsx +++ b/src/routes/Board.tsx @@ -41,7 +41,7 @@ import { FathomMeetingsTool } from "@/tools/FathomMeetingsTool" import { HolonBrowserShape } from "@/shapes/HolonBrowserShapeUtil" import { ObsidianBrowserShape } from "@/shapes/ObsidianBrowserShapeUtil" import { FathomMeetingsBrowserShape } from "@/shapes/FathomMeetingsBrowserShapeUtil" -import { LocationShareShape } from "@/shapes/LocationShareShapeUtil" +// Location shape removed - no longer needed import { lockElement, unlockElement, @@ -81,7 +81,6 @@ const customShapeUtils = [ HolonBrowserShape, ObsidianBrowserShape, FathomMeetingsBrowserShape, - LocationShareShape, ] const customTools = [ ChatBoxTool, diff --git a/src/routes/LocationDashboardRoute.tsx b/src/routes/LocationDashboardRoute.tsx deleted file mode 100644 index fb9c023..0000000 --- a/src/routes/LocationDashboardRoute.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import { LocationDashboard } from '@/components/location/LocationDashboard'; - -export const LocationDashboardRoute: React.FC = () => { - return ; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/routes/LocationShareCreate.tsx b/src/routes/LocationShareCreate.tsx deleted file mode 100644 index 5e3b197..0000000 --- a/src/routes/LocationShareCreate.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import { ShareLocation } from '@/components/location/ShareLocation'; - -export const LocationShareCreate: React.FC = () => { - return ; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/routes/LocationShareView.tsx b/src/routes/LocationShareView.tsx deleted file mode 100644 index 75d8d3e..0000000 --- a/src/routes/LocationShareView.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import { useParams } from 'react-router-dom'; -import { LocationViewer } from '@/components/location/LocationViewer'; - -export const LocationShareView: React.FC = () => { - const { token } = useParams<{ token: string }>(); - - if (!token) { - return ( -
-
-

Invalid Share Link

-

No share token provided in the URL

-
-
- ); - } - - return ; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/shapes/LocationShareShapeUtil.tsx b/src/shapes/LocationShareShapeUtil.tsx deleted file mode 100644 index 505d543..0000000 --- a/src/shapes/LocationShareShapeUtil.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { - BaseBoxShapeUtil, - HTMLContainer, - TLBaseShape, - RecordProps, - T -} from "tldraw" -import { ShareLocation } from "@/components/location/ShareLocation" - -export type ILocationShare = TLBaseShape< - "LocationShare", - { - w: number - h: number - } -> - -export class LocationShareShape extends BaseBoxShapeUtil { - static override type = "LocationShare" as const - - static override props: RecordProps = { - w: T.number, - h: T.number - } - - getDefaultProps(): ILocationShare["props"] { - return { - w: 800, - h: 600 - } - } - - component(shape: ILocationShare) { - return ( - -
- -
-
- ) - } - - indicator(shape: ILocationShare) { - return - } -} diff --git a/src/types/odd.d.ts b/src/types/odd.d.ts deleted file mode 100644 index 949ce1a..0000000 --- a/src/types/odd.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -declare module '@oddjs/odd' { - export interface Program { - session?: Session; - } - - export interface Session { - username: string; - fs: FileSystem; - } - - export interface FileSystem { - mkdir(path: string): Promise; - } - - export const program: (options: { namespace: { creator: string; name: string }; username?: string }) => Promise; - export const session: { - destroy(): Promise; - }; - export const account: { - isUsernameValid(username: string): Promise; - isUsernameAvailable(username: string): Promise; - }; - export const dataRoot: { - lookup(username: string): Promise; - }; - export const path: { - directory(...parts: string[]): string; - }; -} - -declare module '@oddjs/odd/fs/index' { - export interface FileSystem { - mkdir(path: string): Promise; - } - export default FileSystem; -} \ No newline at end of file diff --git a/src/ui/CustomMainMenu.tsx b/src/ui/CustomMainMenu.tsx index 899254b..c450c4f 100644 --- a/src/ui/CustomMainMenu.tsx +++ b/src/ui/CustomMainMenu.tsx @@ -29,7 +29,7 @@ export function CustomMainMenu() { const validateAndNormalizeShapeType = (shape: any): string => { if (!shape || !shape.type) return 'text' - const validCustomShapes = ['ObsNote', 'VideoChat', 'Transcription', 'Prompt', 'ChatBox', 'Embed', 'Markdown', 'MycrozineTemplate', 'Slide', 'Holon', 'ObsidianBrowser', 'HolonBrowser', 'FathomMeetingsBrowser', 'LocationShare'] + const validCustomShapes = ['ObsNote', 'VideoChat', 'Transcription', 'Prompt', 'ChatBox', 'Embed', 'Markdown', 'MycrozineTemplate', 'Slide', 'Holon', 'ObsidianBrowser', 'HolonBrowser', 'FathomMeetingsBrowser'] const validDefaultShapes = ['arrow', 'bookmark', 'draw', 'embed', 'frame', 'geo', 'group', 'highlight', 'image', 'line', 'note', 'text', 'video'] const allValidShapes = [...validCustomShapes, ...validDefaultShapes] diff --git a/src/ui/CustomToolbar.tsx b/src/ui/CustomToolbar.tsx index 6331222..46faee9 100644 --- a/src/ui/CustomToolbar.tsx +++ b/src/ui/CustomToolbar.tsx @@ -15,7 +15,6 @@ import { createShapeId } from "tldraw" import type { ObsidianObsNote } from "../lib/obsidianImporter" import { HolonData } from "../lib/HoloSphereService" import { FathomMeetingsPanel } from "../components/FathomMeetingsPanel" -import { LocationShareDialog } from "../components/location/LocationShareDialog" import { getFathomApiKey, saveFathomApiKey, removeFathomApiKey, isFathomApiKeyConfigured } from "../lib/fathomApiKey" export function CustomToolbar() { diff --git a/src/utils/shapeCollisionUtils.ts b/src/utils/shapeCollisionUtils.ts index 3f5fe7e..bc99669 100644 --- a/src/utils/shapeCollisionUtils.ts +++ b/src/utils/shapeCollisionUtils.ts @@ -32,7 +32,7 @@ export function resolveOverlaps(editor: Editor, shapeId: string): void { const allShapes = editor.getCurrentPageShapes() const customShapeTypes = [ 'ObsNote', 'ObsidianBrowser', 'HolonBrowser', 'VideoChat', - 'Transcription', 'Holon', 'LocationShare', 'FathomMeetingsBrowser', 'Prompt', + 'Transcription', 'Holon', 'FathomMeetingsBrowser', 'Prompt', 'Embed', 'Slide', 'Markdown', 'MycrozineTemplate', 'ChatBox' ] @@ -119,7 +119,7 @@ export function findNonOverlappingPosition( const allShapes = editor.getCurrentPageShapes() const customShapeTypes = [ 'ObsNote', 'ObsidianBrowser', 'HolonBrowser', 'VideoChat', - 'Transcription', 'Holon', 'LocationShare', 'FathomMeetingsBrowser', 'Prompt', + 'Transcription', 'Holon', 'FathomMeetingsBrowser', 'Prompt', 'Embed', 'Slide', 'Markdown', 'MycrozineTemplate', 'ChatBox' ]