From 89ec949a5c40d8b3f5c3ce525318275c878fae77 Mon Sep 17 00:00:00 2001 From: Shreyan Bag Date: Thu, 12 Nov 2026 07:47:59 +0530 Subject: [PATCH 1/8] Add monorepo foundation, graph schema, language adapters and indexing pipeline - npm workspaces, TypeScript strict config, ESLint/Prettier - graph schema with validation and normalisation - TypeScript (compiler API + checker), Python (ast) and Tree-sitter adapters - repository scanner, manifest readers, relationship resolver - subsystem/concept organisation, execution flows - graph engine: algorithms, SQLite store, exports, question explorer - labelled sample repository for tests and onboarding Co-Authored-By: Claude Fable 5.2 --- .env.example | 20 + .gitignore | 15 + .npmrc | 1 + .prettierignore | 10 + .prettierrc.json | 7 + apps/local-engine/package.json | 30 + apps/web/package.json | 62 + eslint.config.js | 32 + package-lock.json | 11314 ++++++++++++++++ package.json | 50 + packages/graph-engine/package.json | 9 + packages/graph-engine/src/algorithms.ts | 267 + packages/graph-engine/src/analysis.ts | 163 + packages/graph-engine/src/explore.ts | 343 + packages/graph-engine/src/exports.ts | 250 + packages/graph-engine/src/index.ts | 5 + packages/graph-engine/src/store.ts | 329 + packages/graph-layout/package.json | 9 + packages/graph-schema/package.json | 9 + packages/graph-schema/src/index.ts | 408 + .../grammars/tree-sitter-c.wasm | Bin 0 -> 625918 bytes .../grammars/tree-sitter-c_sharp.wasm | Bin 0 -> 5350581 bytes .../grammars/tree-sitter-cpp.wasm | Bin 0 -> 3434931 bytes .../grammars/tree-sitter-go.wasm | Bin 0 -> 217182 bytes .../grammars/tree-sitter-java.wasm | Bin 0 -> 414641 bytes .../grammars/tree-sitter-rust.wasm | Bin 0 -> 1102547 bytes packages/language-adapters/package.json | 9 + packages/language-adapters/python/extract.py | 390 + packages/language-adapters/src/assets.ts | 20 + packages/language-adapters/src/index.ts | 19 + packages/language-adapters/src/languages.ts | 150 + .../language-adapters/src/python-adapter.ts | 122 + .../src/treesitter-adapter.ts | 865 ++ packages/language-adapters/src/types.ts | 143 + .../src/typescript-adapter.ts | 865 ++ packages/repository-indexer/package.json | 9 + .../repository-indexer/src/analyze-worker.ts | 22 + packages/repository-indexer/src/index.ts | 6 + packages/repository-indexer/src/manifests.ts | 295 + packages/repository-indexer/src/organize.ts | 445 + packages/repository-indexer/src/pipeline.ts | 217 + packages/repository-indexer/src/resolve.ts | 705 + packages/repository-indexer/src/scan.ts | 173 + packages/repository-indexer/src/workers.ts | 184 + packages/search/package.json | 9 + packages/search/src/index.ts | 158 + packages/shared/package.json | 9 + packages/shared/src/index.ts | 316 + samples/sample-repo/.gitignore | 2 + samples/sample-repo/README.md | 9 + samples/sample-repo/analytics/app/__init__.py | 0 samples/sample-repo/analytics/app/main.py | 25 + samples/sample-repo/analytics/app/models.py | 15 + .../analytics/app/services/__init__.py | 0 .../analytics/app/services/report.py | 27 + .../sample-repo/analytics/requirements.txt | 2 + samples/sample-repo/package.json | 9 + samples/sample-repo/tools/c/main.c | 7 + samples/sample-repo/tools/c/util.c | 6 + samples/sample-repo/tools/c/util.h | 8 + samples/sample-repo/tools/csharp/Program.cs | 14 + .../tools/csharp/Services/Greeter.cs | 20 + samples/sample-repo/tools/go/go.mod | 3 + samples/sample-repo/tools/go/main.go | 18 + samples/sample-repo/tools/go/store/store.go | 27 + .../java/src/com/sample/tools/Exporter.java | 20 + .../java/src/com/sample/tools/Formatter.java | 6 + .../src/com/sample/tools/JsonFormatter.java | 12 + samples/sample-repo/tools/rust/Cargo.toml | 6 + samples/sample-repo/tools/rust/src/main.rs | 8 + samples/sample-repo/tools/rust/src/parser.rs | 19 + .../sample-repo/web/src/auth/middleware.ts | 16 + samples/sample-repo/web/src/auth/session.ts | 23 + samples/sample-repo/web/src/config.ts | 11 + samples/sample-repo/web/src/cycle/a.ts | 5 + samples/sample-repo/web/src/cycle/b.ts | 5 + samples/sample-repo/web/src/db/client.ts | 3 + .../sample-repo/web/src/db/noteRepository.ts | 21 + samples/sample-repo/web/src/db/schema.ts | 13 + samples/sample-repo/web/src/routes/login.ts | 8 + samples/sample-repo/web/src/routes/notes.ts | 17 + samples/sample-repo/web/src/server.ts | 14 + .../web/src/services/noteService.ts | 17 + samples/sample-repo/web/src/ui/App.tsx | 10 + samples/sample-repo/web/src/ui/NoteList.tsx | 11 + scripts/index-cli.ts | 39 + tsconfig.json | 27 + 87 files changed, 18967 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 .prettierignore create mode 100644 .prettierrc.json create mode 100644 apps/local-engine/package.json create mode 100644 apps/web/package.json create mode 100644 eslint.config.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 packages/graph-engine/package.json create mode 100644 packages/graph-engine/src/algorithms.ts create mode 100644 packages/graph-engine/src/analysis.ts create mode 100644 packages/graph-engine/src/explore.ts create mode 100644 packages/graph-engine/src/exports.ts create mode 100644 packages/graph-engine/src/index.ts create mode 100644 packages/graph-engine/src/store.ts create mode 100644 packages/graph-layout/package.json create mode 100644 packages/graph-schema/package.json create mode 100644 packages/graph-schema/src/index.ts create mode 100644 packages/language-adapters/grammars/tree-sitter-c.wasm create mode 100644 packages/language-adapters/grammars/tree-sitter-c_sharp.wasm create mode 100644 packages/language-adapters/grammars/tree-sitter-cpp.wasm create mode 100644 packages/language-adapters/grammars/tree-sitter-go.wasm create mode 100644 packages/language-adapters/grammars/tree-sitter-java.wasm create mode 100644 packages/language-adapters/grammars/tree-sitter-rust.wasm create mode 100644 packages/language-adapters/package.json create mode 100644 packages/language-adapters/python/extract.py create mode 100644 packages/language-adapters/src/assets.ts create mode 100644 packages/language-adapters/src/index.ts create mode 100644 packages/language-adapters/src/languages.ts create mode 100644 packages/language-adapters/src/python-adapter.ts create mode 100644 packages/language-adapters/src/treesitter-adapter.ts create mode 100644 packages/language-adapters/src/types.ts create mode 100644 packages/language-adapters/src/typescript-adapter.ts create mode 100644 packages/repository-indexer/package.json create mode 100644 packages/repository-indexer/src/analyze-worker.ts create mode 100644 packages/repository-indexer/src/index.ts create mode 100644 packages/repository-indexer/src/manifests.ts create mode 100644 packages/repository-indexer/src/organize.ts create mode 100644 packages/repository-indexer/src/pipeline.ts create mode 100644 packages/repository-indexer/src/resolve.ts create mode 100644 packages/repository-indexer/src/scan.ts create mode 100644 packages/repository-indexer/src/workers.ts create mode 100644 packages/search/package.json create mode 100644 packages/search/src/index.ts create mode 100644 packages/shared/package.json create mode 100644 packages/shared/src/index.ts create mode 100644 samples/sample-repo/.gitignore create mode 100644 samples/sample-repo/README.md create mode 100644 samples/sample-repo/analytics/app/__init__.py create mode 100644 samples/sample-repo/analytics/app/main.py create mode 100644 samples/sample-repo/analytics/app/models.py create mode 100644 samples/sample-repo/analytics/app/services/__init__.py create mode 100644 samples/sample-repo/analytics/app/services/report.py create mode 100644 samples/sample-repo/analytics/requirements.txt create mode 100644 samples/sample-repo/package.json create mode 100644 samples/sample-repo/tools/c/main.c create mode 100644 samples/sample-repo/tools/c/util.c create mode 100644 samples/sample-repo/tools/c/util.h create mode 100644 samples/sample-repo/tools/csharp/Program.cs create mode 100644 samples/sample-repo/tools/csharp/Services/Greeter.cs create mode 100644 samples/sample-repo/tools/go/go.mod create mode 100644 samples/sample-repo/tools/go/main.go create mode 100644 samples/sample-repo/tools/go/store/store.go create mode 100644 samples/sample-repo/tools/java/src/com/sample/tools/Exporter.java create mode 100644 samples/sample-repo/tools/java/src/com/sample/tools/Formatter.java create mode 100644 samples/sample-repo/tools/java/src/com/sample/tools/JsonFormatter.java create mode 100644 samples/sample-repo/tools/rust/Cargo.toml create mode 100644 samples/sample-repo/tools/rust/src/main.rs create mode 100644 samples/sample-repo/tools/rust/src/parser.rs create mode 100644 samples/sample-repo/web/src/auth/middleware.ts create mode 100644 samples/sample-repo/web/src/auth/session.ts create mode 100644 samples/sample-repo/web/src/config.ts create mode 100644 samples/sample-repo/web/src/cycle/a.ts create mode 100644 samples/sample-repo/web/src/cycle/b.ts create mode 100644 samples/sample-repo/web/src/db/client.ts create mode 100644 samples/sample-repo/web/src/db/noteRepository.ts create mode 100644 samples/sample-repo/web/src/db/schema.ts create mode 100644 samples/sample-repo/web/src/routes/login.ts create mode 100644 samples/sample-repo/web/src/routes/notes.ts create mode 100644 samples/sample-repo/web/src/server.ts create mode 100644 samples/sample-repo/web/src/services/noteService.ts create mode 100644 samples/sample-repo/web/src/ui/App.tsx create mode 100644 samples/sample-repo/web/src/ui/NoteList.tsx create mode 100644 scripts/index-cli.ts create mode 100644 tsconfig.json diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..1defa66 --- /dev/null +++ b/.env.example @@ -0,0 +1,20 @@ +# VECTORA local engine configuration. Copy to .env or set in your shell. +# All values are optional; defaults are shown. + +# Loopback address and port of the local engine. +VECTORA_HOST=127.0.0.1 +VECTORA_PORT=4317 + +# Where VECTORA keeps its database, imported sources and caches. +# Default: .vectora-data inside the VECTORA folder (uploads and temp files live here too). +# VECTORA_DATA_DIR= + +# Extra allowed browser origins (comma separated). The engine only accepts +# same-origin requests plus the Vite dev server by default. +# VECTORA_ALLOWED_ORIGINS=http://localhost:5173 + +# Log level: fatal | error | warn | info | debug +VECTORA_LOG_LEVEL=info + +# Python interpreter used for Python source analysis. +# VECTORA_PYTHON=python diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07ce1bf --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +node_modules/ +dist/ +coverage/ +.vectora-data/ +test-results/ +playwright-report/ +*.log +.env +.env.* +!.env.example +.DS_Store +Thumbs.db +*.tsbuildinfo +.bench-tmp/ +.npm-cache/ diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..1553fcb --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +cache=.npm-cache diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..191d2a8 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,10 @@ +node_modules +dist +coverage +samples +package-lock.json +*.wasm +.vectora-data +test-results +playwright-report +docs/LICENSES.md diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..e876358 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "all", + "printWidth": 110, + "tabWidth": 2 +} diff --git a/apps/local-engine/package.json b/apps/local-engine/package.json new file mode 100644 index 0000000..ac31e56 --- /dev/null +++ b/apps/local-engine/package.json @@ -0,0 +1,30 @@ +{ + "name": "@vectora/local-engine", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MIT", + "scripts": { + "dev": "tsx watch src/main.ts", + "start": "tsx src/main.ts" + }, + "dependencies": { + "@fastify/cors": "^11.4.1", + "@fastify/multipart": "^10.1.8", + "@fastify/static": "^9.0.0", + "@vectora/graph-engine": "*", + "@vectora/graph-schema": "*", + "@vectora/repository-indexer": "*", + "@vectora/search": "*", + "@vectora/shared": "*", + "fastify": "^5.12.8", + "octokit": "^5.0.5", + "simple-git": "^4.0.2", + "yauzl": "^3.4.0", + "zod": "^4.6.7" + }, + "devDependencies": { + "@types/yauzl": "^2.10.3", + "fflate": "^0.8.3" + } +} diff --git a/apps/web/package.json b/apps/web/package.json new file mode 100644 index 0000000..04ee320 --- /dev/null +++ b/apps/web/package.json @@ -0,0 +1,62 @@ +{ + "name": "@vectora/web", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MIT", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@codemirror/lang-cpp": "^6.0.0", + "@codemirror/lang-go": "^6.0.0", + "@codemirror/lang-java": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/lang-json": "^6.0.0", + "@codemirror/lang-markdown": "^6.0.0", + "@codemirror/lang-python": "^6.0.0", + "@codemirror/lang-rust": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@dagrejs/dagre": "^3.1.3", + "@fontsource/ibm-plex-mono": "^5.0.0", + "@fontsource/shippori-mincho": "^5.0.0", + "@fontsource/zen-kaku-gothic-new": "^5.0.0", + "@lezer/highlight": "^1.0.0", + "@react-three/drei": "^10.7.9", + "@react-three/fiber": "^9.8.2", + "@tanstack/react-query": "^5.107.1", + "@vectora/graph-layout": "*", + "@vectora/graph-schema": "*", + "@vectora/search": "*", + "@vectora/shared": "*", + "@xyflow/react": "^12.12.1", + "cmdk": "^1.1.1", + "codemirror": "^6.0.2", + "graphology": "^0.26.0", + "graphology-layout-forceatlas2": "^0.10.1", + "graphology-layout-noverlap": "^0.4.2", + "html-to-image": "^1.11.13", + "lucide-react": "^1.72.0", + "radix-ui": "^1.4.0", + "react": "^19.3.1", + "react-dom": "^19.3.1", + "react-markdown": "^10.0.0", + "react-router": "^8.5.1", + "sigma": "^4.0.6", + "three": "^0.187.0", + "zustand": "^5.1.0" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.3.5", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@types/three": "^0.187.0", + "@vitejs/plugin-react": "^6.3.0", + "tailwindcss": "^4.3.5", + "vite": "^8.3.8" + } +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..e16fcb5 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,32 @@ +import js from '@eslint/js'; +import globals from 'globals'; +import reactHooks from 'eslint-plugin-react-hooks'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + { ignores: ['**/dist/**', 'node_modules/**', 'coverage/**', 'samples/**', '.vectora-data/**', 'test-results/**', 'playwright-report/**', '.bench-tmp/**'] }, + js.configs.recommended, + ...tseslint.configs.recommended, + { + languageOptions: { + globals: { ...globals.browser, ...globals.node }, + }, + rules: { + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], + '@typescript-eslint/no-explicit-any': 'warn', + 'no-console': ['warn', { allow: ['warn', 'error', 'info'] }], + }, + }, + { + files: ['apps/web/**/*.{ts,tsx}'], + plugins: { 'react-hooks': reactHooks }, + rules: { + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + }, + }, + { + files: ['scripts/**', 'tests/**', '**/*.test.ts', '**/*.test.tsx'], + rules: { 'no-console': 'off' }, + }, +); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..f5a52a1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11314 @@ +{ + "name": "vectora", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "vectora", + "version": "0.1.0", + "license": "MIT", + "workspaces": [ + "packages/*", + "apps/*" + ], + "devDependencies": { + "@eslint/js": "^10.0.0", + "@playwright/test": "^1.65.0", + "@testing-library/jest-dom": "^6.6.0", + "@testing-library/react": "^16.3.3", + "@types/node": "^24.0.0", + "@vitest/coverage-v8": "^5.1.0", + "esbuild": "^0.28.0", + "eslint": "^10.14.0", + "eslint-plugin-react-hooks": "^7.0.0", + "globals": "^16.0.0", + "jsdom": "^31.0.0", + "prettier": "^3.10.0", + "tsx": "^4.23.15", + "typescript": "~5.9.3", + "typescript-eslint": "^8.72.2", + "vitest": "^5.1.0" + }, + "engines": { + "node": ">=22.13.0" + } + }, + "apps/local-engine": { + "name": "@vectora/local-engine", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@fastify/cors": "^11.4.1", + "@fastify/multipart": "^10.1.8", + "@fastify/static": "^9.0.0", + "@vectora/graph-engine": "*", + "@vectora/graph-schema": "*", + "@vectora/repository-indexer": "*", + "@vectora/search": "*", + "@vectora/shared": "*", + "fastify": "^5.12.8", + "octokit": "^5.0.5", + "simple-git": "^4.0.2", + "yauzl": "^3.4.0", + "zod": "^4.6.7" + }, + "devDependencies": { + "@types/yauzl": "^2.10.3", + "fflate": "^0.8.3" + } + }, + "apps/web": { + "name": "@vectora/web", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@codemirror/lang-cpp": "^6.0.0", + "@codemirror/lang-go": "^6.0.0", + "@codemirror/lang-java": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/lang-json": "^6.0.0", + "@codemirror/lang-markdown": "^6.0.0", + "@codemirror/lang-python": "^6.0.0", + "@codemirror/lang-rust": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@dagrejs/dagre": "^3.1.3", + "@fontsource/ibm-plex-mono": "^5.0.0", + "@fontsource/shippori-mincho": "^5.0.0", + "@fontsource/zen-kaku-gothic-new": "^5.0.0", + "@lezer/highlight": "^1.0.0", + "@react-three/drei": "^10.7.9", + "@react-three/fiber": "^9.8.2", + "@tanstack/react-query": "^5.107.1", + "@vectora/graph-layout": "*", + "@vectora/graph-schema": "*", + "@vectora/search": "*", + "@vectora/shared": "*", + "@xyflow/react": "^12.12.1", + "cmdk": "^1.1.1", + "codemirror": "^6.0.2", + "graphology": "^0.26.0", + "graphology-layout-forceatlas2": "^0.10.1", + "graphology-layout-noverlap": "^0.4.2", + "html-to-image": "^1.11.13", + "lucide-react": "^1.72.0", + "radix-ui": "^1.4.0", + "react": "^19.3.1", + "react-dom": "^19.3.1", + "react-markdown": "^10.0.0", + "react-router": "^8.5.1", + "sigma": "^4.0.6", + "three": "^0.187.0", + "zustand": "^5.1.0" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.3.5", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@types/three": "^0.187.0", + "@vitejs/plugin-react": "^6.3.0", + "tailwindcss": "^4.3.5", + "vite": "^8.3.8" + } + }, + "apps/web/node_modules/@vitejs/plugin-react": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.3.0.tgz", + "integrity": "sha512-H9E955aVvD2F4zNHCw4eIZbIfF6xKldlh7MNu+hSU7xwQzh65lI/N+CJWqmfhi0PEjDXIt/H7T7J/4wU63KJiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0 || ^0.3.0", + "babel-plugin-react-compiler": "^1.0.0", + "oxc-transform-react": ">=0.152.0 <0.157.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "oxc-transform-react": { + "optional": true + } + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.13.tgz", + "integrity": "sha512-j1nvOQCZYSgp7HLmisnCXFTpVvFODiijQ9QHkORfGKWH6YDtskTEeCJS7eV545GZ9UBzrq0e2xsOd5QQ5PjIqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.13", + "@babel/helper-compilation-targets": "^7.29.13", + "@babel/helper-module-transforms": "^7.29.13", + "@babel/helpers": "^7.29.13", + "@babel/parser": "^7.29.13", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.13", + "@babel/types": "^7.29.11", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.14", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.14.tgz", + "integrity": "sha512-qSY56jgW5JnSXzuekLVil6zaOQxOCtOHidr65KkaMBw772IuAY28Qx4ZykAcDn8+FRF15qk80XzKwgSc/RYW6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.14", + "@babel/types": "^7.29.14", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.13.tgz", + "integrity": "sha512-8WxJ4/Vmes3ghacj8VOJy3NW8eyHiFY/4thU/LSBuBE470+igjR/j1ZTNn8fV5VdNrLx6iXUwig526UdOvfP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.14.tgz", + "integrity": "sha512-2XDvQVd9JESaOgGc4jT2/jquTAO7ppA5noTZQqH+MmZ89yjCzScLwtCPbWtkPZylL+TLWR49IwWmk+QkRR4GsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.14" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.14", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.14.tgz", + "integrity": "sha512-CXvKMFvM80ihI7Vox9jb+kQjnyjESQNPM+vB7U0Zz6TWuZA+Z/FL0QPMH300h33qJtIx+REeBhXqWOPW48TcAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.14", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.14.tgz", + "integrity": "sha512-6E3Mi1r0B0umq6vmZa4/78q+64fqO2YY0THUdjDPKUCKhNb0yQy5NQIaPHCSD3ryTgiTss//P4JsWS80AsZ6LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.14" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.14", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.14.tgz", + "integrity": "sha512-VL220vXuyO2z3rNIQwY7ftj9UwpqOt+33sH+sBWkOekbsSR2g7EEMnOx24ZlCH0xOA3DM/33SifVFGbnJD8r/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.14" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.14", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.14.tgz", + "integrity": "sha512-Y5tqevQaUAZhhj82BpYMNC1ssvLQTVAfwKdm8iy8qwmhvC2/CpcAu8OC+QEtjM7pMk7knx83u1Qj8gzkicyelw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.14", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.14.tgz", + "integrity": "sha512-RAdQJrBgmIH1FWvN0X+1hoDxzMzlP4cv/1Zi4dn4tG1H0cTb+rw7CzUxQJhp1f4ANd8j5vH3fy8BAWFGkBDEsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.14", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.14", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.14", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.14", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.14.tgz", + "integrity": "sha512-UjI/dKmwJwT9pOszJitq2G6EObZPnsZUfdCr92z2TlF3EZK9J3EdfOKUrCzHl6wFthbzwhzl1Soc/UIwxRiq6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.14", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@cacheable/memory": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz", + "integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.5.0", + "@keyv/bigmap": "^1.3.1", + "hookified": "^1.15.1", + "keyv": "^5.6.0" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz", + "integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.5.1", + "keyv": "^5.6.0" + } + }, + "node_modules/@codemirror/autocomplete": { + "version": "6.20.4", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.4.tgz", + "integrity": "sha512-yF8RhOf2SXlg00+qtupzLhrglcas61boqaONiNcbPIebHCpJocpqTBA6dyrtUrQO47hqyTdeob/3XnYilT7TaQ==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.11.1.tgz", + "integrity": "sha512-O/4hG3SC1YwcmQ0d2UVNDs+AsaNWd1iHVxbTeEBuqH+6bExAiPK3iS/BvpY6rZGURALv4ZD3sIgcCmRvw3ehBg==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.7.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-cpp": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.3.tgz", + "integrity": "sha512-URM26M3vunFFn9/sm6rzqrBzDgfWuDixp85uTY49wKudToc2jTHUrKIGGKs+QWND+YLofNNZpxcNGRynFJfvgA==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/cpp": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-css": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz", + "integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.1.7" + } + }, + "node_modules/@codemirror/lang-go": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-go/-/lang-go-6.0.1.tgz", + "integrity": "sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/go": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.4.12", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.12.tgz", + "integrity": "sha512-pw2ReWKUqSkbvh76RAT4NYxiogRu+PWkR2ukAwO9uOgrm8uipkzjtKKtNpyeAQwHOqxEeSvAXZ6vr3AfyB9y/w==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.12" + } + }, + "node_modules/@codemirror/lang-java": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.2.tgz", + "integrity": "sha512-m5Nt1mQ/cznJY7tMfQTJchmrjdjQ71IDs+55d1GAa8DGaB8JXWsVCkVT284C3RTASaY43YknrK2X3hPO/J3MOQ==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/java": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.5.tgz", + "integrity": "sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-json": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.2.tgz", + "integrity": "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-markdown": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.5.2.tgz", + "integrity": "sha512-AwBOdkWYuA//WcM0xO5PfHPUcmz/O2i5o0Nsg1U69SII/loCJlFI1Romd9xp2HYb1kYJRGZotyqRghuHH5n8Kw==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.7.1", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.3.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/markdown": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-python": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.2.1.tgz", + "integrity": "sha512-IRjC8RUBhn9mGR9ywecNhB51yePWCGgvHfY1lWN/Mrp3cKuHr0isDKia+9HnvhiWNnMpbGhWrkhuWOc09exRyw==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.3.2", + "@codemirror/language": "^6.8.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/python": "^1.1.4" + } + }, + "node_modules/@codemirror/lang-rust": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.2.tgz", + "integrity": "sha512-EZaGjCUegtiU7kSMvOfEZpaCReowEf3yNidYu7+vfuGTm9ow4mthAparY5hisJqOHmJowVH3Upu+eJlUji6qqA==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/rust": "^1.0.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.13.1.tgz", + "integrity": "sha512-zfvU2r3TyylQLMj/te+5CnQ0rSqZi8B1oTCBbQkagcLW4Xc6imab6qN+pEJhsuNOLaJqiRyBXp9UhWA1DhVvDw==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/streamparser": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.5.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.7.tgz", + "integrity": "sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.42.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.7.2.tgz", + "integrity": "sha512-gUYkYhT2+n/+VGZ+8EzE5WFkYZUZYm1VOKDudIsNqh42uRVQJ0a6Yss9sdKT3MeOYfuL1N6AZA57oza0Oyr0LA==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.37.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.7.6", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.7.6.tgz", + "integrity": "sha512-kAz+AncRtKuIknedxT1bq4XwXv4UowhbkHU1myPrtVb/jZtImWuV5BXzv5vK6i3kYACsdiZiQKFQQ5Mq7elW8w==", + "license": "MIT", + "dependencies": { + "@marijn/find-cluster-break": "^1.0.0" + } + }, + "node_modules/@codemirror/streamparser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@codemirror/streamparser/-/streamparser-6.0.0.tgz", + "integrity": "sha512-JTFPF6xrfjt0mnfGPgzcLiMwYmvIyNaoizp8BYzv8FE8KrT6GBGDZ190rtt+O7Wke3gG/MFHyiY9YGNeimof4w==", + "license": "MIT" + }, + "node_modules/@codemirror/view": { + "version": "6.43.15", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.15.tgz", + "integrity": "sha512-HHsfpqFeHyXLs983pSRe38Xajs0vFWZQ2BuX0m7Ki8w3jZ5iD8cuR3lBz2/5/X53Dhf32SBHKh6rtSTB6tKeGw==", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.7.0", + "crelt": "^1.0.6", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@dagrejs/dagre": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@dagrejs/dagre/-/dagre-3.1.3.tgz", + "integrity": "sha512-X4aUTwOReZvthaZWOVHqlJ52/ZdhZFEM4+Lh/uR4XooUSLE6p71bcy7MPGzYnNUcNh+nj+i/qJQpCMIdQnSmrg==", + "license": "MIT", + "dependencies": { + "@dagrejs/graphlib": "4.0.6" + } + }, + "node_modules/@dagrejs/graphlib": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-4.0.6.tgz", + "integrity": "sha512-Hjv7hbfmSBMP4nVXMFt4gusqWWHghQF0qNT4V5KHo4Jatvd+2L5VHKFnnIjXVuDnaHIRz7ZuHSnlf0RuZkOwWA==", + "license": "MIT" + }, + "node_modules/@dimforge/rapier3d-compat": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz", + "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", + "license": "Apache-2.0" + }, + "node_modules/@emnapi/core": { + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-2.0.0-beta.2.tgz", + "integrity": "sha512-MzCVoWtcg4Pm2B3je5mMvYMvj3MmBKw+fU7vbsJc9/iT8ip6/eYIHo/Dsm/mr+wsHB6SEyJDuxB09Yy6r/8+4A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "2.2.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-2.0.0-beta.2.tgz", + "integrity": "sha512-JcrSPzPvZuNZvJqPTF9Fw25LbOJ8avzFVlaf2grmH4Cku0oGP47tRgqPZadcfj3YoZMHkFVnCYFbQM8I+i5QEw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-2.2.0.tgz", + "integrity": "sha512-JP7OYH38Q7+pyTAe14raZHLQIK7BDKbdwji+Xi3pcd/6QkJYQH3SX4wu6EplGrGJWRepoNzedfm0G3B9Z4e9Rw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.3.tgz", + "integrity": "sha512-R76UKbvsqI68DJJVTVyqFKqU98CN4+B+acxNfEA2IFarSzP0SjtKf/3+fFiXzTyv5Fj3PxLkGHe2wnVWWMxobQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", + "integrity": "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.3.tgz", + "integrity": "sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.16.0.tgz", + "integrity": "sha512-IcpW84uEn3N7ETtNZMlxKhfl6Pec8rUNGOTBtWbK1FKhJxIFAptZyVrvVRVBimAJxJCgc3PxepxkdWWG4DVzfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@fastify/accept-negotiator": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@fastify/accept-negotiator/-/accept-negotiator-2.1.2.tgz", + "integrity": "sha512-LV7MZqTwXTEt3GxBT6BU8ACztWnv++hSkMEsP3usIHiI0tA4F5EO4THhDCOr5J/ginM9DCnLCmZ6u3JLA9x8Iw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/ajv-compiler": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-4.0.7.tgz", + "integrity": "sha512-VP0yIfwlc1ohj733keYDqyHm1VWeP9VQxYomunhr90jkC4aNNibbkrRiaNgPgqj1ORxUenILR4qzA/ppYBNAtQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^4.0.0" + } + }, + "node_modules/@fastify/ajv-compiler/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@fastify/ajv-compiler/node_modules/ajv/node_modules/fast-uri": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz", + "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/@fastify/ajv-compiler/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/@fastify/busboy": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.5.tgz", + "integrity": "sha512-y8MTAeBlEQUNVnskmZQwpseZN3EgCksQNOULlfxWY6o6VEqh01+oExMgbM7gN6YLQ8pNDYeweNPKJRt8jQm2ZQ==", + "license": "MIT" + }, + "node_modules/@fastify/cors": { + "version": "11.4.1", + "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-11.4.1.tgz", + "integrity": "sha512-WuPATGGyc3YzpOfumovBJ4xC2RPBBFyDFElwldFRBCgM2G27xH9DnXTho9+nc2Ho6gLD1hKTetdOntR+G38+7A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fastify-plugin": "^6.0.0", + "toad-cache": "^3.7.0" + } + }, + "node_modules/@fastify/deepmerge": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-3.2.4.tgz", + "integrity": "sha512-kc8GQq5gX9RRhw0rov3DMrN8wS8yRlxJRdDzsYwwdBV/wazuVgc/1K7CKL90tlvu3RlHan6Y0R0aE3nJtBz2eQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/error": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-4.2.1.tgz", + "integrity": "sha512-MYBumuIwP+5MIpXSyKm6/o1Eigcoij186lWUssX3LH5U8KWqU0ktZhzC4CErIX9EJeQeRGI+zJZQWakBlFbUcg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/fast-json-stringify-compiler": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-5.1.1.tgz", + "integrity": "sha512-pyxRKk7UpUnnrztP9pF4+ZYxusEQ4LifTyzRdiXmyql1QezNHxO02D25MVU2o4kMeAMYWAjG6RKRlojgkbiDAw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fast-json-stringify": "^7.0.0" + } + }, + "node_modules/@fastify/forwarded": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@fastify/forwarded/-/forwarded-3.1.2.tgz", + "integrity": "sha512-89WiRG+hW3VQSfCwg4Hb8b43PeyEX15K5+lEfsZ4EUth/FyOjS/lv8HsVuswUNXWiSnxMGNouE/fq/0w3VumHQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/merge-json-schemas": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.2.2.tgz", + "integrity": "sha512-d/gx9sRbUCVgGRGzma46wLcwiY8noTqO2Nmjg/vbTARxHRE5bdh5PIL8s97Lt1X7ScRWRW52eVYxwIoPwIdVUA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@fastify/multipart": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/@fastify/multipart/-/multipart-10.1.8.tgz", + "integrity": "sha512-GNZ6bKyqiKpb1VRhOJtb38X92NSEQIM+piO3sid13oP5xmuVmdbFq32khGh4Ru/jMAJoAVxt4yzuUNPwc/CdSg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@fastify/deepmerge": "^3.0.0", + "@fastify/error": "^4.0.0", + "fastify-plugin": "^6.0.0", + "secure-json-parse": "^4.0.0" + } + }, + "node_modules/@fastify/proxy-addr": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.1.2.tgz", + "integrity": "sha512-uqB4QsgVoro0XDC+DIftIMGXHdBPn+lK6Ek3xXAIxPMCJfqxnbtyEoMCm2KPUVOuIosd7Cyw9HawEqMFM/UA+g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/forwarded": "^3.0.0", + "ipaddr.js": "^2.1.0" + } + }, + "node_modules/@fastify/send": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@fastify/send/-/send-4.2.1.tgz", + "integrity": "sha512-zOB8L9z444PnGbd1Nd7gNXPz/7bnDR8Z4KNTNSwLVQuE3cTGsU9qUj1N4SjXKK0Tq4cauZYTwB+tqvlqosuKsw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@lukeed/ms": "^2.0.2", + "escape-html": "~1.0.3", + "fast-decode-uri-component": "^1.0.1", + "http-errors": "^2.0.0", + "mime": "^3" + } + }, + "node_modules/@fastify/static": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@fastify/static/-/static-9.3.0.tgz", + "integrity": "sha512-9YMYRpCOtMBrqKYWcqiw7ykOrn4D0jogHpJrFS0KGeSuOwzKMM5/mjj7B0CFLVoQ6htqKYw//Zs7APn9DBq05w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/accept-negotiator": "^2.0.0", + "@fastify/send": "^4.0.0", + "content-disposition": "^1.0.1", + "fastify-plugin": "^6.0.0", + "fastq": "^1.17.1", + "glob": "^13.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.8.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", + "license": "MIT" + }, + "node_modules/@fontsource/ibm-plex-mono": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.3.0.tgz", + "integrity": "sha512-eTgnZjZEGk1QtD3ZstF+Vclo2HLAni8YMy34/DxllwZvyz1lR/1RF/xTiAquOBO7MvqBx8D2Ig2WCPMVfdZu7Q==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource/shippori-mincho": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/shippori-mincho/-/shippori-mincho-5.3.0.tgz", + "integrity": "sha512-S41kRxQuubAaYss+LeXu0IOc02RQwsPaJbR1cWZx4VV15hXaYZViH3WAve9HpDVFqKYd/BVk86Bg7lp9ytV3KQ==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource/zen-kaku-gothic-new": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@fontsource/zen-kaku-gothic-new/-/zen-kaku-gothic-new-5.3.1.tgz", + "integrity": "sha512-L69mE6bkzeVK3UdTenxOmCIWvTwMxohJRNm1dAj+W+UiCULQ91b7M77ENVw+pjGmFL6zKPFYFeH3g8x2ugAJNw==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@keyv/bigmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz", + "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.4.0", + "hookified": "^1.15.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.6.0" + } + }, + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "license": "MIT" + }, + "node_modules/@lezer/common": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.5.tgz", + "integrity": "sha512-Pw7PVCndruF1pb3ebCxpSVpkMHSDjwRCLcTRw+RizUKco5QbWylwq2g4lnG/RYN7yTTQDXE9F77MwtkAyphrjg==", + "license": "MIT" + }, + "node_modules/@lezer/cpp": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.6.tgz", + "integrity": "sha512-vh9gWWJOXFVY8HBHK3Twzq8MgwG2iN4GSyzBP9sCGTe37P15x2R14VaBQk0VA0ezTRN1KHYBBsHhvpGZ2Xy/pA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/css": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.3.9.tgz", + "integrity": "sha512-ZmzgvTOBdJWGIsY/ItAfN7UW8DV802oZG+jeG6E508SwEzz5YhuAajptpWPICvIyqYAD2+VjMdOS40GgGkyEOQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/go": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@lezer/go/-/go-1.0.1.tgz", + "integrity": "sha512-xToRsYxwsgJNHTgNdStpcvmbVuKxTapV0dM0wey1geMMRc9aggoVyKgzYp41D2/vVOx+Ii4hmE206kvxIXBVXQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/highlight": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.5.tgz", + "integrity": "sha512-O1GMVKgtf5YspFaRzpmqkVgMtIk2HG9uMAbH6wdAIdNh3TVzCsch/+cRi+6l2//UGDKe6NB9BW3cvuR5ezMQ0w==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.3.0" + } + }, + "node_modules/@lezer/html": { + "version": "1.3.13", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.13.tgz", + "integrity": "sha512-oI7n6NJml729m7pjm9lvLvmXbdoMoi2f+1pwSDJkl9d68zGr7a9Btz8NdHTGQZtW2DA25ybeuv/SyDb9D5tseg==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/java": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.1.5.tgz", + "integrity": "sha512-JppTd1iKHpeNlLYw/Zl8JX7zSY5HqAzK4zZ05lpn8l8Sk7Fo5KAKiDiMiezKoT5lfeC2xZf8HeKp1tSctj4G6Q==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.5.6.tgz", + "integrity": "sha512-sEvOqpl4vJQca0NugSQK02vQPbc5KrvoojnYGoqqFgFO0MtcYhwGiHKVEB+LuXYJnfyXo4QPA8ztbrEa4Fw5NA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/json": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz", + "integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.12.tgz", + "integrity": "sha512-On9HU4oMMiHPMkQDgoTnGahjgG5n/MkN38CgG77sMraKLL+3JBbeQNi1FcCXV9QRqwF9/BUXP3caHyJC1fBOTQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/markdown": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.8.1.tgz", + "integrity": "sha512-M5YmEcKWO4mJ45Y1hECwqyu8cLv25EiXOK554PVOvDOWOP0olwelHHQUWr9sjF+d1bENVhy0nfJ8E57XZUTiXg==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.5.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@lezer/python": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.19.tgz", + "integrity": "sha512-MhQIURHRytsNzP/YXnqpYKW6la6voAH3kyplTOOiCdjyFY6cWWGFVmYVdHIPrElqSDf4iCDktQCockB9FxuhzQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/rust": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.3.tgz", + "integrity": "sha512-XxErOjZzQ7yJt1agUT4fu9qQvESZ3acgoxpPaPTPOiUx+duCjaVAtZGFIgphkHxlN05djdVAIOy/wItShMEjqQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lukeed/ms": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@lukeed/ms/-/ms-2.0.2.tgz", + "integrity": "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@marijn/find-cluster-break": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.4.tgz", + "integrity": "sha512-Wy0V7+SGUjnF9/TkiM1hKVDPj7jKXduPNboMVtHTA8dySMURWqfg/JZ9E2Sq8JgSJmkl7k7Qe9FLeMSrSraWmQ==", + "license": "MIT" + }, + "node_modules/@mediapipe/tasks-vision": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz", + "integrity": "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==", + "license": "Apache-2.0" + }, + "node_modules/@monogrid/gainmap-js": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.7.3.tgz", + "integrity": "sha512-YjgdH65wZ9lQnzkVWerrR9FJR0JYhn3ahV7DJqDZVtIvR/kWv7XzFbMSIOFS/47+nWbZ5zFTRxsFhq0OX//SuA==", + "license": "MIT", + "dependencies": { + "promise-worker-transferable": "^1.0.4" + }, + "peerDependencies": { + "three": ">= 0.159.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.6.tgz", + "integrity": "sha512-mRyDmEw9/fCDXCGfL1sbgIw/GUK0PVxRW4YwgPN61F3LQ+fSyoBFarJVzgGyhF6kRzEQZ0FejDqm4WLXSeqQmw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || 2.0.0-beta.2", + "@emnapi/runtime": "^1.7.1 || 2.0.0-beta.2" + } + }, + "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/@octokit/app": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/@octokit/app/-/app-16.1.4.tgz", + "integrity": "sha512-g70WONQyGoBgqIJtv4O0MUEfOF1iJpTfFt3qAW7HaiwiJ6k607xg/gBezCa4tuq6BpO6qXn7qvq8v9tjWtgGQg==", + "license": "MIT", + "dependencies": { + "@octokit/auth-app": "^8.3.0", + "@octokit/auth-unauthenticated": "^7.0.4", + "@octokit/core": "^7.0.7", + "@octokit/oauth-app": "^8.0.4", + "@octokit/plugin-paginate-rest": "^15.0.0", + "@octokit/types": "^17.0.0", + "@octokit/webhooks": "^14.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/app/node_modules/@octokit/openapi-types": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-28.0.0.tgz", + "integrity": "sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==", + "license": "MIT" + }, + "node_modules/@octokit/app/node_modules/@octokit/plugin-paginate-rest": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-15.0.0.tgz", + "integrity": "sha512-lw9A9YL5s4VPj+VEx8uMxaxQm2YTgrPDkrLEuZuu18R8TK3oPcXF4K6t52nx6xn1RcogZC9i188sAr/4XYJaQQ==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^17.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/app/node_modules/@octokit/types": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-17.0.0.tgz", + "integrity": "sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^28.0.0" + } + }, + "node_modules/@octokit/auth-app": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-8.3.1.tgz", + "integrity": "sha512-XHWxZsF4mvGTQCv7AOxgby9t9OjVO19FBuKq+QmyBxFrf+B2hR/P5j/MTF8g95bITf8cRtR17KIXThpFNqiKbg==", + "license": "MIT", + "dependencies": { + "@octokit/auth-oauth-app": "^9.0.5", + "@octokit/auth-oauth-user": "^6.0.4", + "@octokit/request": "^10.0.16", + "@octokit/request-error": "^7.1.2", + "@octokit/types": "^18.0.0", + "toad-cache": "^3.7.0", + "universal-github-app-jwt": "^2.2.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/auth-app/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/auth-app/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/auth-oauth-app": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-9.0.5.tgz", + "integrity": "sha512-Hn2yAlIDjFLGjAz7t+CRu7e9VYoFW1W3LLyOLyahFoJGlCf4PtDkHKtRET8w/2CJpsrC0FxIF5g5Xtx9E4O78w==", + "license": "MIT", + "dependencies": { + "@octokit/auth-oauth-device": "^8.0.5", + "@octokit/auth-oauth-user": "^6.0.4", + "@octokit/request": "^10.0.16", + "@octokit/types": "^18.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/auth-oauth-device": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-8.0.5.tgz", + "integrity": "sha512-kdJtjRhykMLJrMdcoC56XUBDfoUAuWEFKpkDxwYim+bNwYw1MreLolk+PLnwEYT8djm589YepeMuJ8+ECAIzVQ==", + "license": "MIT", + "dependencies": { + "@octokit/oauth-methods": "^6.0.5", + "@octokit/request": "^10.0.16", + "@octokit/types": "^18.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/auth-oauth-user": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-6.0.4.tgz", + "integrity": "sha512-eya2pMJ9pCBq1jrm1Rf6J3NI+NemEpzDMLo9J/GpRoK0KgdxIVXWX4LESIfwJ+GYeoq6QFIlUJNi1lVp5FBgmw==", + "license": "MIT", + "dependencies": { + "@octokit/auth-oauth-device": "^8.0.5", + "@octokit/oauth-methods": "^6.0.5", + "@octokit/request": "^10.0.16", + "@octokit/types": "^18.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/auth-unauthenticated": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-7.0.5.tgz", + "integrity": "sha512-KBzGMM8hRgtGKDe8JqvDdhHj+7PWHRo1qxz9pQ5WT1162DLdC6O5jL+kRFk3VfpCnEfc3bUYZ2vOwI9vx8yUXA==", + "license": "MIT", + "dependencies": { + "@octokit/request-error": "^7.1.2", + "@octokit/types": "^18.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/auth-unauthenticated/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/auth-unauthenticated/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/core": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.8.tgz", + "integrity": "sha512-L7y8eYc+AwxGr2PWI4WFt1VG4TiJ66c26BD16mXpYIlXxG0SMigM1+m4aTSlYyBr5BlQsGAlz8uDCoZN4SEMcg==", + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.5", + "@octokit/request": "^10.0.16", + "@octokit/request-error": "^7.1.2", + "@octokit/types": "^18.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/core/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/endpoint": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.5.tgz", + "integrity": "sha512-iXa654H3yFafF/ieHkukfbgWo2rmXD2ceD0ZOtrPhw1bc3FDch1d9N/TNs0FQ1/cIbwb7kspUX8jzIs8nzb9DQ==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^18.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/endpoint/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/graphql": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.5.tgz", + "integrity": "sha512-bt/hm03LeU6Vy7FwTrkkC9p3XGT/lBwClglMqxBSe5/q0E5CdJTXeAqEI0vlw89/LF/G6tryTIH8HirZ3prMVg==", + "license": "MIT", + "dependencies": { + "@octokit/request": "^10.0.16", + "@octokit/types": "^18.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/graphql/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/oauth-app": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-8.0.4.tgz", + "integrity": "sha512-Ji5JpRwAJcbOJkO4ij0tW6+GrQ8efpICnAca3o5xI8/HUNjqJu3hhG4cCZdXAHMKaOaQTFX0Yl+cpu61Rsx94A==", + "license": "MIT", + "dependencies": { + "@octokit/auth-oauth-app": "^9.0.4", + "@octokit/auth-oauth-user": "^6.0.3", + "@octokit/auth-unauthenticated": "^7.0.4", + "@octokit/core": "^7.0.7", + "@octokit/oauth-authorization-url": "^8.0.0", + "@octokit/oauth-methods": "^6.0.3", + "@types/aws-lambda": "^8.10.83", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/oauth-authorization-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-8.0.0.tgz", + "integrity": "sha512-7QoLPRh/ssEA/HuHBHdVdSgF8xNLz/Bc5m9fZkArJE5bb6NmVkDm3anKxXPmN1zh6b5WKZPRr3697xKT/yM3qQ==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/oauth-methods": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-6.0.5.tgz", + "integrity": "sha512-/mAz7taDZD7DcV4zcG6TDw3Kr6TOldmYBRpvA62C3WIxRMmcgX8XxsTvVQomqKE7VEk/BgYhUao1aR2tYGyIKg==", + "license": "MIT", + "dependencies": { + "@octokit/oauth-authorization-url": "^8.0.0", + "@octokit/request": "^10.0.16", + "@octokit/request-error": "^7.1.2", + "@octokit/types": "^18.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "license": "MIT" + }, + "node_modules/@octokit/openapi-webhooks-types": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-webhooks-types/-/openapi-webhooks-types-12.1.0.tgz", + "integrity": "sha512-WiuzhOsiOvb7W3Pvmhf8d2C6qaLHXrWiLBP4nJ/4kydu+wpagV5Fkz9RfQwV2afYzv3PB+3xYgp4mAdNGjDprA==", + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-graphql": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-6.0.0.tgz", + "integrity": "sha512-crfpnIoFiBtRkvPqOyLOsw12XsveYuY2ieP6uYDosoUegBJpSVxGwut9sxUgFFcll3VTOTqpUf8yGd8x1OmAkQ==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", + "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", + "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-retry": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-8.1.1.tgz", + "integrity": "sha512-VCVvZ/R1+u3WuiBWpNavZ0mY4aaJNAsENrpBP9aLSR2QyOpQgd7DhM5j4AW7z4MQpnJYgwBPf0XqPQoNBRdQwg==", + "license": "MIT", + "dependencies": { + "@octokit/request-error": "^7.1.1", + "@octokit/types": "^17.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=7" + } + }, + "node_modules/@octokit/plugin-retry/node_modules/@octokit/openapi-types": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-28.0.0.tgz", + "integrity": "sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==", + "license": "MIT" + }, + "node_modules/@octokit/plugin-retry/node_modules/@octokit/types": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-17.0.0.tgz", + "integrity": "sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^28.0.0" + } + }, + "node_modules/@octokit/plugin-throttling": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-11.0.5.tgz", + "integrity": "sha512-LIdrkrUv+DWbKeg/49rGuFJ3SU0d3hUS+B4MhNZLepBoNUFXms8Ic9edJjrlx+zycqJHjrMRudVpVb/bAXM2Lw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^17.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": "^7.0.0" + } + }, + "node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-28.0.0.tgz", + "integrity": "sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==", + "license": "MIT" + }, + "node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-17.0.0.tgz", + "integrity": "sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^28.0.0" + } + }, + "node_modules/@octokit/request": { + "version": "10.0.16", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.16.tgz", + "integrity": "sha512-A0zWGjHzISIb+9ccG8s0dq7LKO5zVpJLRICjgUb+sJxEWqn8RUHB1rD3AE51+PECvXHIxqZ1VVvs4fHTSD9nUQ==", + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^11.0.5", + "@octokit/request-error": "^7.1.2", + "@octokit/types": "^18.0.0", + "content-type": "^3.0.0", + "json-with-bigint": "^3.5.12", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/request-error": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.2.tgz", + "integrity": "sha512-XZRuT3xZ84D3gYErI1DZvhJ33dCWVV6uzBtWkaBB4TvA/L6eOeTZodxLFVB44bBEEo3vEx7y00UfX1tBLrtLRg==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^18.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/request-error/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/request/node_modules/@octokit/openapi-types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", + "license": "MIT" + }, + "node_modules/@octokit/request/node_modules/@octokit/types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^29.0.1" + } + }, + "node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/@octokit/webhooks": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-14.2.0.tgz", + "integrity": "sha512-da6KbdNCV5sr1/txD896V+6W0iamFWrvVl8cHkBSPT+YlvmT3DwXa4jxZnQc+gnuTEqSWbBeoSZYTayXH9wXcw==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-webhooks-types": "12.1.0", + "@octokit/request-error": "^7.0.0", + "@octokit/webhooks-methods": "^6.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/webhooks-methods": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-6.0.0.tgz", + "integrity": "sha512-MFlzzoDJVw/GcbfzVC1RLR36QqkTLUf79vLVO3D+xn7r0QgxnFoLZgtrzxiQErAjFUOdH6fas2KeQJ1yr/qaXQ==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.156.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.156.0.tgz", + "integrity": "sha512-1Duyg48TdJNdyhEB8Xn1L36bT9Pv6GUtlKjHxOys8xkaF/rQq3XJE+bAurSK/AgIz5mGFsb77cn9Pb20+WCScw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "license": "MIT" + }, + "node_modules/@playwright/test": { + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.65.0.tgz", + "integrity": "sha512-iGURLGuKDLakSEl7Pgfv8h7f+XLT+V861Wfhz0zlEl5nyFuKUopdkFBPKqTllTUp06aOwPuH8iuUEb3yp3MpbQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.65.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.3.tgz", + "integrity": "sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.2.0.tgz", + "integrity": "sha512-KABY+VMIRPJL+Vyzv/335FEhXXD/xDv8BMb1kl48/aXJZMH0LtHCTx5ga5RnxaEP3nZHtmTLf1P9vanmFX46bw==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accessible-icon": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.2.0.tgz", + "integrity": "sha512-BB4+HHkFl3HipEAhm/mLhrpXV+2kRX7MvY4AaImUcQVeWQt5KhV1JEByNs8NGfJOcr95RcQGijt9+OrCo68xGA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-visually-hidden": "1.2.13" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.3.1.tgz", + "integrity": "sha512-lCZ6sbGS/7WO0j84yx4srIgOf0MRJ/sZ13RonADXxvKBym8xrxNCq5f6DibGcr38sIlwPk8/52uYdXeOPsbEDw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collapsible": "1.2.1", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.2.1.tgz", + "integrity": "sha512-MWC4N7RY+qsbNrFNo7yQ9ZbdoZEW+B5DtpWxJfUnVCqcQxxqqg3qis3RMPTDbCNaTIdHJSn5XDkl9ZdVWXknLg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dialog": "1.3.1", + "@radix-ui/react-primitive": "2.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.17.tgz", + "integrity": "sha512-67jjcVvxjXCCStnTW3Z+M7jmaFMuMR7M2JgpDzH4w7JSRrikmzhjfYgP/09ECb8n7whnsgh1ifJ+Ie96qEj+pQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.2.0.tgz", + "integrity": "sha512-gHEU+Lx8DlT/FYIjZQvvBJrFSwUngXTjh7FeL9QvJaNALDLez6pgDj2axCUihBjtPBy82LN0gNb25+sTcSXNmA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.3.1.tgz", + "integrity": "sha512-ssZOkfQNkFpYVmCPQlr978xSaU7moSrGXdwg4j2Xs2WlGl/1KsSZtfpK+WnLnx0Rwll1BAh6oUrAy/uR31SBvQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.4.1.tgz", + "integrity": "sha512-KWtwhh+98ML3seZ9vO9yRY2OwaQG90dCiDAxjpSNY2AaZ3Hik3B0dsk6m0ILywo/no3A9/SozadyPMNweVT8yw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-size": "1.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.2.1.tgz", + "integrity": "sha512-fSzLb/qy1wuZSxQBcxpW0hNXYHDMWiIXDGyJGdA4+FSLknOWZsNRrTCUavxb4PI8b8lvHo/CysO6NVi5zLpo5g==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.2.0.tgz", + "integrity": "sha512-+yiQzqcc7Sy7/5s0jrMCjpPRFB3538VNrXPWdTLZhE/SCfgEws4aI6lHWN/vvcnyhHndROWBzqmqB4QBrITZ9Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.5.tgz", + "integrity": "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.3.0.tgz", + "integrity": "sha512-v5AYEocMISkbJ+1fTXzZpiFv7NRr3D2WiYbLIKf+FkmJ8VkP6d503eV2n34MFussHXY1pcoq3yfJiQH77dc4Mg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context-menu": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.4.1.tgz", + "integrity": "sha512-Pddn3Z8lio3/ChxyXaEP3jHTTo1LTHCWwF8+mG1chQlWijP+ttVHBKwezrQTiV6Mj670ojvumqvuGh+mdv33iQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-menu": "2.2.1", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.3.1.tgz", + "integrity": "sha512-+0E4qvVTwjAWra9sEhJ+9BTsvHE00zkUuNw1VGh7S+Gc13dfYk+S1PVQdchWDj+XYHhAai7Z7IpzXVDCGsDplg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-guards": "1.2.0", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.2.0.tgz", + "integrity": "sha512-FtRA52a/r+LKStFT+neLUm+8vSe7wbzkbQGGeU8ixFiwC8NU14Evoq9ATECqL3eGbcUzJR4fyfA4KkK/q6dfqg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.2.1.tgz", + "integrity": "sha512-KIfDcAsx+oVylFZ4xryVKusJUrLLhTQmfnJW4kwk4Km5myvhHCrj04hnWWUC166+xD4DHdH8tQGylwYX1h6+Pg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-effect-event": "0.0.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.2.1.tgz", + "integrity": "sha512-XsHcmYG2AcqnvTqrOXXWcMrhquEIlqucizuDH1MV/qMRW+DndpBCMvNeTRXOxqmG1H5j89M/+I0/34Zdd+zDcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-menu": "2.2.1", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.2.0.tgz", + "integrity": "sha512-MPm5R0iRGUDrDnPNxmLBkv+X7pN4XKzt+MbWJEuJQsH3NFH4omrbpXpucyYCCKTSt+na/ZxGhEWQrWTZ0285cA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.3.1.tgz", + "integrity": "sha512-ugeMhbXt4y5S2T1GnIqbWDKEN962PDwnX1fN0eKOOgf5f63Dh2mn8F1FUySlgW0iF6GiVsRF32DzuDIWTUyQJg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-form": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-form/-/react-form-0.3.0.tgz", + "integrity": "sha512-KnmrCM27m7Jo1R8S6cFDPrEeq20Jfn5dqde0SZrJr2lVXlj6/QZSUCyFoYh1d8ti0uUrMNK5Lx6dUDuINT+f4Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-label": "2.1.17", + "@radix-ui/react-primitive": "2.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.2.1.tgz", + "integrity": "sha512-4QooHxgmpCKRjj1Pft+hETKidYcrbPKcVwMGtk2Oa5DcWY2IH1fHuQt9LG6q5hUQBBV2MhQxSvtx6B/C1xfiTw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.4.tgz", + "integrity": "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.17.tgz", + "integrity": "sha512-xmj7MN/drx1oUAXkfiFIvyDmGNUIN/omGobvA5oAoNqu9zO2MkISYGZOkBcqSzs/UZXXwV+/3ACRE7q7mGcmkA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.2.1.tgz", + "integrity": "sha512-G34BsU90SBj5foYpz8pQqq/Q0Dlfyyl6KitWEfRwXC0QvfwhWNAwS49DWP2+rRJ0iwv20Z2Qx7Sk+T03bGo5JA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-guards": "1.2.0", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menubar": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.2.1.tgz", + "integrity": "sha512-bRTYtS9JITV2dUYqYZb7+N5SooQBkZrNRejfmyrSKe3Y57aXhKgx//kBUP0kY7pEpsWR/U1AHsAJRzjwCrK3PA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-menu": "2.2.1", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-use-controllable-state": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.4.1.tgz", + "integrity": "sha512-XPPZjkeyCSMNNvt0FyDv/PUauG7Ow4GwHQ/XZSwW36F/TS7rR4HFTsXH8ewLnXTOLn3x96/pmTPNQIVoTX/86g==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-previous": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.13" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-one-time-password-field": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-one-time-password-field/-/react-one-time-password-field-0.2.1.tgz", + "integrity": "sha512-KtHdcgnaAK6rohQ/MMJoGYcbgSRJsIuGBdHrFeTB1/9SaKlDs14oSOniW6BL6M43HqvgCO3u4WuVdFLkuc6sqw==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-effect-event": "0.0.5", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-password-toggle-field": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-password-toggle-field/-/react-password-toggle-field-0.2.1.tgz", + "integrity": "sha512-vu4+ZoJAaFjdI7l1lDSZRs+4dEv83Jmu7lyzajPrAeQzX74y84n0rUNWbWSgN9XB5NE8IY86Z02kGH6oRrzR+w==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-effect-event": "0.0.5", + "@radix-ui/react-use-is-hydrated": "0.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.3.1.tgz", + "integrity": "sha512-ZNxvXRx5W2Wos4fXCXb5lpdqN0Z5chf+mStOUOTr4ik7d+62MRvoe9rzCA/eGNg36lxXqSrKEKmwuZEcUrIstw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-guards": "1.2.0", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.4.0.tgz", + "integrity": "sha512-yCWRvLeGv9Pz3+efwHqGPp70mZ56r3kfIgQVF56Oj2aAa4uP/Tb+IE59wNcc+758rctqbCKx4LbK8II/r7Bn0Q==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.17", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-rect": "1.1.4", + "@radix-ui/react-use-size": "1.1.5", + "@radix-ui/rect": "1.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.2.0.tgz", + "integrity": "sha512-StX7xXnaRU41VvFtMm9zlhVGz8XF6GmWWTXftkQaY+tqVkbs/R9UmAp5mLzHHapk5hM9RMZQvO/3usyIP/g42g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.11.tgz", + "integrity": "sha512-Z7/atlkab36Z8hm+V8zYc79r0W+tiOB1o0tun1By94JyadkekLQmtEAnBSP9XKXBNQsStoStS4+gX10JpS5akA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.2.0.tgz", + "integrity": "sha512-HCTSPMNqv55Qk0IX4geJbpyXazmqulcimwuyjxTkKi29v+QZbG2Zho9BnbBq4YS2PF+KlNb2CXoLz66uUmblkg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.5.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.2.1.tgz", + "integrity": "sha512-yQBiM6J3YM8Ums1orkEFpbznK47geKxa0igikzcaS1xHgdba3DdAQBsGbCTt5BVfR8zhEvgxQ0poGcINaD3lvw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.5.1.tgz", + "integrity": "sha512-QbyVT1ddnjqB9H+CUYKkNWdU9fIK3QHCYtjf7mS6ekSqiuXkWtWn5UZW9mhA8qtl3vrVyIsmR9gePstAtKrqkw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-size": "1.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.2.1.tgz", + "integrity": "sha512-UwraORzVUeEPMclhO1p0vz0qI+TbdDLO9i+FiOqhJyHKwdpCRCck9yVEscUnAMIzCiuNoQa8D4A9bIpOPXGt6Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.4.0.tgz", + "integrity": "sha512-CFrLqHNejWq5FhKAcj9V/WPGRsol76HBQto81NdOBVFEOqIEkJkKIJt0Z824A/9hHLCtoiR/Kw3euRgzXP2pxg==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.4.1.tgz", + "integrity": "sha512-888ZwW0Md6GyptuqYABRX9nLKgoYfcooCyBBvVaX5Jp3e+8Jp2i4Zo/Uy50Hm+Ysn2JfloQXstW4U36w8teVtg==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-guards": "1.2.0", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.13", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.2.0.tgz", + "integrity": "sha512-1jUAap0wZEqVP05Ou7kJgRxe/W+Qftng+rUNWGa0qkKbv9r5pWTG3E7a3ELKo2eJoHKMECnzuYrZpSyO1YgcYQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.6.1.tgz", + "integrity": "sha512-IRNRR90moPqxfwCJ0XbMJIxo70W0/1ZExT/sNCxEHMaPx0SF9HoQrcPEC75+H28cFKa0b+KH63anfLYJmwKacw==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-size": "1.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.5.0.tgz", + "integrity": "sha512-tyYd9ddPXAysAbdbD9eYxgwpCSv6f3PncqVSNKQFSR5lcJVLz3cb/pANDoYrLiHBpXv7skortyUgGUWsYuPPFQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.4.1.tgz", + "integrity": "sha512-NpBGwc40rY02ZmSvuyeKk0Bvc8ZsNeTMi4qHvJ+ZH4EiYCv0zIXEgdCW4bVdzgIUeP9xxbLJSxKOUfqITYNmkA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-size": "1.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.2.1.tgz", + "integrity": "sha512-hRoJlode+hg5ZNlR+3tkfkUliIybdTpD5lkAvHQ9yaXseGf7XVO9Ib2GPEIOuaJJbo7YWYbNpDDRfo8Dhf6/xA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-use-controllable-state": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toast": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.3.1.tgz", + "integrity": "sha512-iQvL0J7XK4HtJNGkkWMyYrboNseI7vtotFeUkIno8YNxVA9oM7B6//fh0Mc6TSKI96+zioLWi98lQLso88yJmQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.13" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.2.1.tgz", + "integrity": "sha512-+3MUq+WyiBplXYqQ0EIYlq8R4sLQ0T5NbOK7DMdDLCKO93pe2uE0DUJTWWfTBprpJJXxfoF3eMW0xpakVZrYsg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-use-controllable-state": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.2.1.tgz", + "integrity": "sha512-O8Ldx5ao4p4KoW+DO8/PmkOe5mdKNi3F2SseqjVj88wvDGDHe60cUmO0Zm/uHsKrvNgQGV8Efpuh95Tht/h4vw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-toggle": "1.2.1", + "@radix-ui/react-use-controllable-state": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toolbar": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.2.1.tgz", + "integrity": "sha512-Cm8m7JTEeUdbfA6T9xgyu8HfOpyvSx8pB/wj0DlEuWaJe9FilIs4Az9wci/lU9RbthV/UkltszMw5WnnD+m/Ug==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-separator": "1.2.0", + "@radix-ui/react-toggle-group": "1.2.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.4.1.tgz", + "integrity": "sha512-NxLFGSFtZ78zVfcoOhTwR1xwqo5qx1Jh8Pw6FMZ9McCaqfRzz7/gIRahs2Oy5XlPgQ+8QkUcKbN5B0U44J/kCg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.13" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.5.tgz", + "integrity": "sha512-Y5GBf4NKeADoXI1geiMlMuMoURT3k9MizzzKhGb/m55H94aGigZ01PIpkvsO6lML13BA6XYAXSJ6gza7vTn5nw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.3.0.tgz", + "integrity": "sha512-TAcBI7bw2ljYCbv4+zuTSd6zICu8pRt6SDN2vJ/Z06K2MXh6I9WYFe/A9ovlFDtR5HVHGm5iDxDoABm/++dbKg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-use-effect-event": "0.0.5", + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.5.tgz", + "integrity": "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.6.tgz", + "integrity": "sha512-9cRullnQRv+kqnRmFlmh0WC3kAPuGmHiQ9VwsXdrYk//sBhgCKEttcpPEPgIQbyx6TGUmooVEHYTyohwz/lSJg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.3.tgz", + "integrity": "sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.4.tgz", + "integrity": "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.4.tgz", + "integrity": "sha512-XoSLhbRbqxFtgJoi2fNHA3C6pDlY34x508vUpUGoFZfvePfHXHbE1lC4FYFMnJWgiCRroSTw6fOsXQoVS9RwZg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.4.tgz", + "integrity": "sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.5.tgz", + "integrity": "sha512-V1McDQkMGzgivwqdu7u96APs7oi0Jvj9LTzgq3WWrDZqxWdAqU9yZnZQqk5OizGFR8badUQwZsrlao7MOlWYOA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.13.tgz", + "integrity": "sha512-feijiN1oPk4rck4u9Dm9tsU4mT6Wp9oeEEhaz1WUEs1VuqLf8xzsFG+Qk+uWq6TnMH9O+WRECRg0NftyP9E4Fw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.3.tgz", + "integrity": "sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==", + "license": "MIT" + }, + "node_modules/@react-three/drei": { + "version": "10.7.9", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-10.7.9.tgz", + "integrity": "sha512-wP4Y6o58KFi+hT1zCfjJarRtPCT6WW/lo53WMiA/aCORuUvBzW916XsCtadnIB1KB+3IQNcDU5JeVh/gYb8MYw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mediapipe/tasks-vision": "0.10.17", + "@monogrid/gainmap-js": "^3.0.6", + "@use-gesture/react": "^10.3.1", + "camera-controls": "^3.1.0", + "cross-env": "^7.0.3", + "detect-gpu": "^5.0.56", + "glsl-noise": "^0.0.0", + "hls.js": "^1.5.17", + "maath": "^0.10.8", + "meshline": "^3.3.1", + "stats-gl": "^2.2.8", + "stats.js": "^0.17.0", + "suspend-react": "^0.1.3", + "three-mesh-bvh": "^0.8.3", + "three-stdlib": "^2.35.6", + "troika-three-text": "^0.52.4", + "tunnel-rat": "^0.1.2", + "use-sync-external-store": "^1.4.0", + "utility-types": "^3.11.0", + "zustand": "^5.0.1" + }, + "peerDependencies": { + "@react-three/fiber": "^9.0.0", + "react": "^19", + "react-dom": "^19", + "three": ">=0.159" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber": { + "version": "9.8.2", + "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.8.2.tgz", + "integrity": "sha512-6s0ejw0bT1myQ/aLLugcil8/zBmNnnHw/AISWF1yfDLOxfX3yYaTS+0IkpJITEnm/SSMLtxje6CJDt0i5Wu1Sw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.8", + "@types/webxr": "*", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "its-fine": "^2.1.1", + "react-use-measure": "^2.1.7", + "scheduler": "^0.28.0", + "suspend-react": "^0.1.3", + "use-sync-external-store": "^1.4.0", + "zustand": "^5.0.3" + }, + "peerDependencies": { + "expo": ">=43.0", + "expo-asset": ">=8.4", + "expo-file-system": ">=11.0", + "expo-gl": ">=11.0", + "react": ">=19 <19.4", + "react-dom": ">=19 <19.4", + "react-native": ">=0.78", + "three": ">=0.156" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + }, + "expo-asset": { + "optional": true + }, + "expo-file-system": { + "optional": true + }, + "expo-gl": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@remix-run/route-pattern": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/@remix-run/route-pattern/-/route-pattern-0.22.1.tgz", + "integrity": "sha512-czdGJWh09Lapvcqt7Vb09KlrU2PhRJ8xQaI+AItTuD9aDJ5MAgxnS38lnys6Ll+6RJEqPiaUqTwIQhVLwFvv+w==", + "license": "MIT" + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.19.tgz", + "integrity": "sha512-e+Ebe0WT+9tbXmNKPIiC8YrWAHYwug3m6i4p3rZGGulfZri1jtI4HslT+OZnFf/OIHowWF71DTlHwXBP2SiA7A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.19.tgz", + "integrity": "sha512-hOombrTJ+szt2ciEzS7oCA78lMPBgF5UMQWCJIyNfnrI7GLl8HYoFqCnpL2gcPOaXMqryGCU5ExdQKyDDcC+yA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.19.tgz", + "integrity": "sha512-XoMA2pwCKGTQzUjPgtRwkedH4WmXhdIPKT6l6oOxd1PUbNodGI6DcBekgN7EC//+x3pfBYX/qL1gNmZAqivw5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.19.tgz", + "integrity": "sha512-zo8EsSSwMZCY/e+fRnGaX02YGgvJD0yvhNi/9hpGPA2MJ9ZF8dPCw75UGfpI6OpQ/myR/dIYmogRvqiZD0TrXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.19.tgz", + "integrity": "sha512-O8ISAOfI1nj7AuBPd30FSF47z7f7lzlk5poQVGgiikvQuGEBFYvW8ki+UEnT+YJPnNGjQzn304klt4O9FUE7mA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.19.tgz", + "integrity": "sha512-/lYCba5NO0yq4S0jGMH8QTBtkvQxoXjoQWzF5BcWp9MjB9jxVRD1GQDNofkVjcOj30DWyhLIN/4Oe60JKzaONw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.19.tgz", + "integrity": "sha512-pm/apFMBnSbFb3O6nG5pHO1iqHhZrjGDFEjSm+ot9J17XXPvH9L90y5h+jgfHCE+Qdlsvy8qKEcU4VKxgjD+vA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.19.tgz", + "integrity": "sha512-K1SmQp3FFichn8oqrNIwvFoZ5wcvjC7goBzpaMNvLf9FZc+QB/QvLmnpJZgAAGHiD980tP8FZZnXk2K94rvlxg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.19.tgz", + "integrity": "sha512-I0xwD57jP/3A7+5UPZin2w8Y7XHEmEM5zqpYZOcQ45MlNW6tUJUziymV3yRr7rL4vwyfEcRsRksC4a7Kc08p5Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.19.tgz", + "integrity": "sha512-BrtEHT24SNXj9HiXqy+s/kXiSiQGt6EKCPUlRirAoIioVxKGnbXBUEkbZASAei7iZJB0/Ynm+0JP00Ipx7AnSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.19.tgz", + "integrity": "sha512-rm75/9DkHKeU2WnA8w4X94WGYgLlDCFCfkQC+4bguVJmC/jvDRv2B+2wLOYhyE0fVuv7//Ckk39OoOufyCu76Q==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.19.tgz", + "integrity": "sha512-irh/4+iYFM4GAzpluDErgjz89bj6NDtqqMAG/6O1LG38Ed3NpyebzCpcVNkFW8uhy+/3/BocUvnXDR33CXWe9A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.19.tgz", + "integrity": "sha512-+KWTWNoPt+CfSq94CiceWu3yPE+QzkaG+phPyz9G60tmZLwfQkcA4AeksafzvJAw4pvg1mcd5a1TkUqVv0s4JA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.2.19.tgz", + "integrity": "sha512-7EH+skOsl5qpWnK0vzamgJFhOv1cwxQpsxm8tI883K9fur5c27p8q87fzEO6BbBPabA2/+s/zR63/pLc137iOg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "2.0.0-beta.2", + "@emnapi/runtime": "2.0.0-beta.2", + "@napi-rs/wasm-runtime": "1.2.6" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.19.tgz", + "integrity": "sha512-3Q1Yg1Q7tEvBWoZf5rFvG/GKZQPgwfru+p4wBajDfJFBs0SHCpL++dfTjW9gyAKd1T7ZpIYvdaUax7Pa/IhFVQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.19.tgz", + "integrity": "sha512-y/sqRRc6d7hECzOFc5n3LSeqctmIp9mMjY1Kq4s14uLPd/LZ4z7i1zrW6fMtp2mPeuQIC4e6ULMcwQzMomqQag==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.1.0.tgz", + "integrity": "sha512-K+NU2HDCEem4sClgHH4ZZXwdJeNFkJo+hRk479DIwdIviAPN2hFJH1KHHwg8CxHQXvi0M5XY4deTXINfIiSG6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@simple-git/args-pathspec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@simple-git/args-pathspec/-/args-pathspec-1.0.4.tgz", + "integrity": "sha512-EtMX6XjRWSastG2SdkmSQByPtJ9dx/NIjnHbpQPCYt62j4RmSx5rgLTGpw0YCjF5h191gZOmBfheOT23cRSFdw==", + "license": "MIT" + }, + "node_modules/@simple-git/argv-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@simple-git/argv-parser/-/argv-parser-2.0.1.tgz", + "integrity": "sha512-M++IaVWrN+vYalilOHfwvT2IL3wYZtVEBQpmX6DLSOJLtxbZ+SUeIDE3IiPogzhPACLajwtxfa5rp+ZX1FczzQ==", + "license": "MIT", + "dependencies": { + "@simple-git/args-pathspec": "^1.0.4" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.5.tgz", + "integrity": "sha512-yT53FzV4ke0cr/BguDxhWMpm5MJu1O2muzk+tKw6lKHjODAsYArBbWwFbJiaksfzFv1tpkO9QHGzmfs1hJT66g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.24.5", + "jiti": "^2.7.0", + "lightningcss": "1.33.0", + "magic-string": "^1.1.0", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.5" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.5.tgz", + "integrity": "sha512-PynqGLZsZvwM9tqD/CUxkOIfyd6K5elZ2MooauzJryP/UqXYgi3yYbtt3N0Xe+MHV/eFKPFQCEfIKAqlAS1CBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.5", + "@tailwindcss/oxide-darwin-arm64": "4.3.5", + "@tailwindcss/oxide-darwin-x64": "4.3.5", + "@tailwindcss/oxide-freebsd-x64": "4.3.5", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.5", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.5", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.5", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.5", + "@tailwindcss/oxide-linux-x64-musl": "4.3.5", + "@tailwindcss/oxide-wasm32-wasi": "4.3.5", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.5", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.5" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.5.tgz", + "integrity": "sha512-Se0z5xMqcSQanJD1IYmO0cGpK3iv0fp3ZsIT7xRJZ1Da5PghvNoc46zz4jIQn+aan3dV9T8AermFNN9QPmsh0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.5.tgz", + "integrity": "sha512-UPrgTDuUbvmqGMZuCnmI3FKee/tYKzKdp00/kuB4oSGB213VYg8QTdF7lVhnPoBXq/mIfJ+ILoBFqNOboWcMwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.5.tgz", + "integrity": "sha512-E+p7HEtjI0b8D7kbbWxH067cGui6d4c79COGko9fAPVE3rwc1E7ld2HFCbaG86AOGWS5VKQYqZOaf38ya4uxTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.5.tgz", + "integrity": "sha512-yWEWcWyAG7rWOcTpJTjdhQ3pcaFY2h+0bqTRfgU3G2fz87ZU3AKdvdZKhslD+kyHnjBUWKvNdRYwIYC5dI1tIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.5.tgz", + "integrity": "sha512-WmeVjtJhZlr+smpqcdR2kQkkn6arHIJnUIBxTO2EJcTLGY1ecVXNo2hbSn8xc0IH2aEtys936iMWKGyj0GaKnA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.5.tgz", + "integrity": "sha512-DTCSyucc6ShMp1QMqV5R94Z7xlgNgUzkGmFF1rL5HH2Qjy4eSmEqy+YLGkqqYvWa4sILtgrBt1JjRKbneQtiFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.5.tgz", + "integrity": "sha512-H9lsvO4x9E4nE4Hi8h7NHHw0O/kcVSu+iOyFHNGdYzazGgDjFHZbE6S3hQ8kMcbNXSBlMdNi67LV5EVqtpaJtw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.5.tgz", + "integrity": "sha512-4uxQvtBvPuIdl13WfUBj9xMZHH14PtHZ8OZdtLmdyDtG66sCa1t599NZT+jagkUzRtWhuul1qRZQ1nAJscXN5g==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.5.tgz", + "integrity": "sha512-0JQAzs7jwbA7O6+z/adU+Jk3AXwsu3npAhtr5escXS7TqEqWcaDV7qHuI+0Vy/KQRuVGnLQREcSJWYauyV3oqg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.5.tgz", + "integrity": "sha512-OJhFmlEfdzMr+avACdi40RPtnkW0B6hXyxL/8r+tnEHBWZji36CYRjEXrrvgBmaYsD3oEOBqwYFRKsYvzFe7Bw==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.11.3", + "@emnapi/runtime": "^1.11.3", + "@emnapi/wasi-threads": "^1.2.3", + "@napi-rs/wasm-runtime": "^1.2.2", + "@tybys/wasm-util": "^0.10.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.5.tgz", + "integrity": "sha512-9o8jgthi+QE5eandnboiJT64VQfnIArfZzSTdgbhEK5aafdiu2jTW9Honi/mwYHxBZuH1vAC57IFyrh+0iK5Gg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.5.tgz", + "integrity": "sha512-XiKFfIy1RWe7qK4WqByxNW7Oz1/nkOy8o/BWhHminyV1PmpUd8Eedj5v2A8h2kpqeVlz6xRnwk9Fr/ZXNLcZfg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.5.tgz", + "integrity": "sha512-BCNiY0a1ZjdOHVqw7kyb7U72BwfMF3dfUuN+tQsLWky/J5JOI/r7abibglXfygrZhVO/3u3V+E25kkKTeMkXaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.3.5", + "@tailwindcss/oxide": "4.3.5", + "tailwindcss": "4.3.5" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.107.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.107.1.tgz", + "integrity": "sha512-PSyAik11oQBEVOiVy5hjZWHmoUqOXqK1WYy4v55mcxozEfKaQgpUMsgnXhWjuESzSht8JfzqMS1m6M/9CpNgvg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.107.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.107.1.tgz", + "integrity": "sha512-udCOOLp3ZAheUrIHLCe+ZZge6nr2ZUrGMSWcCuXsjY1Bf2JeeE09oxst97PILiCY6N8xo/7bIo3Hvz13zh06FA==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.107.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@types/react": "^18 || ^19", + "react": "^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.2.tgz", + "integrity": "sha512-yzr2S9HyAIdhz2/6qHgbs665Q7PKVcDF05vsOlHPxG1mo36gKVesdYVeDLnXgfjJ03CrKRk08knc6+E/9m8v2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.3", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.3.tgz", + "integrity": "sha512-Uo193NgQbPMz6lrrhtRQQFcMC6Re/ELLFbbuVL30WDlZxlpZf9/lMHTAVxPRLw1q1iu9OJmR1c2BLiENRstdBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@tweenjs/tween.js": { + "version": "23.1.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", + "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.4.tgz", + "integrity": "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/aws-lambda": { + "version": "8.10.164", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.164.tgz", + "integrity": "sha512-XOnrazWcOd6yWPnR7DxqCBPPYciDjHq+NN8LPwwqBCJNXLyPJgKo47fZpJ113+oyAn9Zti0Cf6H4k6yPcE3WFg==", + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-selection": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.12.tgz", + "integrity": "sha512-Qe/KWYhEiIIxGs7HrAAjMfShxKldx19SJtr5zu53f3afPsdZNz7HHtdTLXo/kqeiWNXVycI24kSnfzBYkTzpgw==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.9.tgz", + "integrity": "sha512-0sE1406XBYJGiqD3AusTl9ZqC//2mIXix51tbom25gDCA8ri4xnSZg28CaSE8Srl6FClqABUKfsn0qghgdepMA==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/draco3d": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz", + "integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==", + "license": "MIT" + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.10.tgz", + "integrity": "sha512-lTyOMnOcmRBzdCv6/4zUZCrEhV0xrqQiUZBZtVcbmLHBXKLnN8q89v/wKRF/Q0HbwVsqbIG3o5HDoFl9sduM+g==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.19.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.2.tgz", + "integrity": "sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/@types/offscreencanvas": { + "version": "2019.7.3", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", + "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.3.0" + } + }, + "node_modules/@types/react-reconciler": { + "version": "0.28.9", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz", + "integrity": "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/stats.js": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", + "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", + "license": "MIT" + }, + "node_modules/@types/three": { + "version": "0.187.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.187.0.tgz", + "integrity": "sha512-v+vKNarUtk4n2QRZ4+CN5ygMM0ARUjXjIQl0R/unMUfmStFeVqGbgqarbrpoGTXRZoulSH16ePrVJVxPJEbMUA==", + "license": "MIT", + "dependencies": { + "@dimforge/rapier3d-compat": "~0.12.0", + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": ">=0.5.17", + "fflate": "~0.8.3", + "meshoptimizer": "~1.1.1" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@types/webxr": { + "version": "0.5.24", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz", + "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==", + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.72.2.tgz", + "integrity": "sha512-222PKFXKihmFpi/pS5njoBgdAqsPhj2/GBmFbrNw8Tq8gEG9Sv+kSlKFy4u2q+mJv9ZzJgM2Gkv/bUzRZwZw5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.72.2", + "@typescript-eslint/type-utils": "8.72.2", + "@typescript-eslint/utils": "8.72.2", + "@typescript-eslint/visitor-keys": "8.72.2", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.72.2", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.14.tgz", + "integrity": "sha512-wCBiZ77u1tuWde6G/nfOtLaCTYcFDU5yCzARzK10y+rLhzYoL7a7yEemcopcc2Mzow7gZOIjnV2ym1NYmdiJOQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.72.2.tgz", + "integrity": "sha512-llP+T1YuJOLlxEciP6OyQGtz5SMxyn+9LA2BvZw5RmToGVa1y4beEDVQL6Gje7T5WFYh19WREjDCN9Ev4gm5AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.72.2", + "@typescript-eslint/types": "8.72.2", + "@typescript-eslint/typescript-estree": "8.72.2", + "@typescript-eslint/visitor-keys": "8.72.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.72.2.tgz", + "integrity": "sha512-6y5dLTZdHhI8Eh3yIQ/bfQhRKwn5e+TpJj64o18Cngc0iW/BCrVvrr6zGYqXPnYH31u6YXAYiFh0+qxX5mybJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.72.2", + "@typescript-eslint/types": "^8.72.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.72.2.tgz", + "integrity": "sha512-iIoMJ6/8c1/QpFNyFjU0d1YzPco4MsZjQw0k3V+vfzNWAFmUmvhlyMoYEoYYDQZXc+J6Gi1X5XcxlzW2taIIGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.72.2", + "@typescript-eslint/visitor-keys": "8.72.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.72.2.tgz", + "integrity": "sha512-+h3iCgZXuTNtoLXcnnjP12ZUHLMqoUcIHPfQrFEXTUqvb9dF8QK9b5nv5VtSo5fLkdHuks8ehbTzZj3rImAm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.72.2.tgz", + "integrity": "sha512-STfkR38qIdhfkLpgtXnUjAzsNy4xouqiBO0lrVc/Wpk9Kem5/aHXUx1J8dGC16zpdYN1+yc2ILQ28er1kXX7ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.72.2", + "@typescript-eslint/typescript-estree": "8.72.2", + "@typescript-eslint/utils": "8.72.2", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.2.tgz", + "integrity": "sha512-Xfn37OLZx03+PCU7qWx9DTv2FCRh1E6fk2+wONeNY15HXIwtcwuveaSwVpGAUptkNmPQegRxW5JyRel9T7wrog==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.72.2.tgz", + "integrity": "sha512-pQEGqIK/cqEvKivVWaFLYpe7XYejFxfuAOi4mu1oAWFvIo36aRHI9esRFTUxcIy/z8N482RJyH+LpZB0ZIU7Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.72.2", + "@typescript-eslint/tsconfig-utils": "8.72.2", + "@typescript-eslint/types": "8.72.2", + "@typescript-eslint/visitor-keys": "8.72.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.6.tgz", + "integrity": "sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.72.2.tgz", + "integrity": "sha512-hv3eRYbpPbbpezuax1EfGrzpa3C4ySgNZkPUkLOWOAjU8HsOKowEDAr8C7nsNl1C+SBSKDpvno6VKHnlhvp9iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.72.2", + "@typescript-eslint/types": "8.72.2", + "@typescript-eslint/typescript-estree": "8.72.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.2.tgz", + "integrity": "sha512-NAGrjn0Pitjqzq/GkgMC4kBYm233PQ8GffyQ9+kTA3AlNQYEzOf25EIM02BAHZv5FRJSpHpJk+OGUxVkOB93GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.72.2", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz", + "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==", + "license": "ISC" + }, + "node_modules/@use-gesture/core": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz", + "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==", + "license": "MIT" + }, + "node_modules/@use-gesture/react": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz", + "integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==", + "license": "MIT", + "dependencies": { + "@use-gesture/core": "10.3.1" + }, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@vectora/graph-engine": { + "resolved": "packages/graph-engine", + "link": true + }, + "node_modules/@vectora/graph-layout": { + "resolved": "packages/graph-layout", + "link": true + }, + "node_modules/@vectora/graph-schema": { + "resolved": "packages/graph-schema", + "link": true + }, + "node_modules/@vectora/language-adapters": { + "resolved": "packages/language-adapters", + "link": true + }, + "node_modules/@vectora/local-engine": { + "resolved": "apps/local-engine", + "link": true + }, + "node_modules/@vectora/repository-indexer": { + "resolved": "packages/repository-indexer", + "link": true + }, + "node_modules/@vectora/search": { + "resolved": "packages/search", + "link": true + }, + "node_modules/@vectora/shared": { + "resolved": "packages/shared", + "link": true + }, + "node_modules/@vectora/web": { + "resolved": "apps/web", + "link": true + }, + "node_modules/@vitest/coverage-v8": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.1.0.tgz", + "integrity": "sha512-OY9aShBQG5KOIw2zCo9fDoCHI9RHliNHJ//nM7m6jGg41Hyke9JOGWmeMlK74xYErsxMoK8mIB3gAeEyFVA7LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/istanbul-lib-coverage": "^2.1.0", + "@vitest/istanbul-lib-report": "^2.1.0", + "ast-v8-to-istanbul": "^1.0.7", + "magicast": "^0.5.5", + "obug": "^3.0.0", + "std-env": "^4.3.0", + "tinyrainbow": "^3.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "5.1.0", + "vitest": "5.1.0" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/istanbul-lib-coverage": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/istanbul-lib-coverage/-/istanbul-lib-coverage-2.1.0.tgz", + "integrity": "sha512-WOjuS+xcjSIy7ruYBQ+9BUcV7XZQ0FyVcbWbWxW9TRx/kLGx5SQaeFRIFDJxjNplb6YsT7SpKo2zuXXUo91OIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22" + } + }, + "node_modules/@vitest/istanbul-lib-report": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitest/istanbul-lib-report/-/istanbul-lib-report-2.1.0.tgz", + "integrity": "sha512-+ZFta25nWtGCOBG9/IET8w1RO5Oawsd6H8Uf6AJ9EA/StFuKVtKAEJEJ6uRt84OH+T4YkI0ASmIHAhRA+0KVxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/istanbul-lib-coverage": "2.1.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@vitest/mocker": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.1.0.tgz", + "integrity": "sha512-5umB9/jlWcqVS6fsrFmv5Gdnpu6wAUio/lEOwAmvB7v+lFo/IW2B9FhAD0p19GCULTgMzLCdUmuCDCnAzWgppQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.31", + "@vitest/spy": "5.1.0", + "estree-walker": "^3.0.3", + "magic-string": "^1.4.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9 || ^3.0.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/spy": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.1.0.tgz", + "integrity": "sha512-2DPO5OMHWKrBngC+fCmTQqemNF0gidRhp3lxbBmRhW+M1XJrfgPpqNqWVevXtn2f2ufD5ZaR1B6B641aAlcX5A==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@xyflow/react": { + "version": "12.12.1", + "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.12.1.tgz", + "integrity": "sha512-g41OHmP+GL5wDBQKpgYt8AF6RlB4CrABtiStXhCMqdItK6gPdSpsuDk8V0YtdyvIvMPTjDJvkuLkz0JbSYu5Cw==", + "license": "MIT", + "dependencies": { + "@xyflow/system": "0.0.84", + "classcat": "^5.0.3", + "zustand": "^4.4.0" + }, + "peerDependencies": { + "@types/react": ">=17", + "@types/react-dom": ">=17", + "react": ">=17", + "react-dom": ">=17" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@xyflow/react/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@xyflow/system": { + "version": "0.0.84", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.84.tgz", + "integrity": "sha512-96zfGFjH3oZ3T0MRdH4gJ0SlXuCIxbBuHVevZ4xry5UTxqjzjt010+LRdholgepq7jhrcaz1JNtzrETscwnkEA==", + "license": "MIT", + "dependencies": { + "@types/d3-drag": "^3.0.7", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-selection": "^3.0.10", + "@types/d3-transition": "^3.0.8", + "@types/d3-zoom": "^3.0.8", + "d3-drag": "^3.0.0", + "d3-interpolate": "^3.0.1", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + } + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/fast-uri": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz", + "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.8.tgz", + "integrity": "sha512-lPdpagk13ANXV+HClJEpCZM7kUsl5XcvgqKzZhaj6Ve1ZFICcY2sGhAN1n1vT0tML6EclT7bfVgTxqL57Gkpow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/avvio": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-9.3.1.tgz", + "integrity": "sha512-QyTKW61/qlba+cUQBm/sT9X8lri4UdomqSDwCnrnj1IvLVDRRiXRkz4CgBRWB+/cmfC7SK5WQc8T1vSdGvaUcQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/error": "^4.0.0", + "fastq": "^1.17.1" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.36", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.36.tgz", + "integrity": "sha512-AbPFGS4K9S3meMRCLTM0Zas+e9X7b5ygUBOboDT5zevCZt9ByKSbMtKhwyVqW+oL8WemPVsbP7X3rdZcIyOa0w==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bcp-47": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.2.tgz", + "integrity": "sha512-wsv86UuNFuPnVieKLyECTT+CP1WSAHeoIg5P3xu2kA9Z+7fVPoKt7dxzSeEhtJel0AI+NW3fIW3KtTKQKUCngg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "license": "Apache-2.0" + }, + "node_modules/bidi-js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.1.0.tgz", + "integrity": "sha512-fX1Onk0tdVPC7obPWB5EbJ1z7NVhLq4m2xZLq2YXBkxzMXIGRpNMU88n0EPgWseKl12J7zXs7qrDxPK4sRs2fg==", + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.13.tgz", + "integrity": "sha512-Vh3dmFbc4wZeox7M9I/0L9GfFd83Su4+yCck/OF9Gi/P/dAHn0RT7X4K9R7gMNMhDck3DvhR6QXsnQdjjgwNvQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "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/browserslist": { + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.5.tgz", + "integrity": "sha512-khTmKu5NGYTotqcYo8Bew2k4RAE9PuXRSFRXG2lQBrCEQHyeQ/vX6gKMxfokwywBsLiXZMnHsmWMG1pnO8J7uQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.33", + "caniuse-lite": "^1.0.30001819", + "electron-to-chromium": "^1.5.464", + "node-releases": "^2.0.60", + "update-browserslist-db": "^1.3.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/cacheable": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz", + "integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/memory": "^2.2.0", + "@cacheable/utils": "^2.5.0", + "hookified": "^1.15.0", + "keyv": "^5.6.0", + "qified": "^0.10.1" + } + }, + "node_modules/camera-controls": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-3.1.2.tgz", + "integrity": "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA==", + "license": "MIT", + "engines": { + "node": ">=22.0.0", + "npm": ">=10.5.1" + }, + "peerDependencies": { + "three": ">=0.126.1" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001826", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001826.tgz", + "integrity": "sha512-wTB+9tIbLro/BCXwLuNV1meHE4L9dS6dArMDwgYfNBPMYScqClHyGunhkCSDtHhe/69Xl0sHlKgBVZ+fNsYtWA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chai": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/classcat": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", + "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==", + "license": "MIT" + }, + "node_modules/cmdk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", + "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.2" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/codemirror": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.2.tgz", + "integrity": "sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-3.1.1.tgz", + "integrity": "sha512-GW4qUsfFo59d0HbUibDlWv5wPz+vAAcaTWbKIuKCf0JkC7wWkSyf8f13IpXn5JkeMlB2P8iTSSIjwXljorg2vA==", + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.2.tgz", + "integrity": "sha512-SL0cVuEdETEp7pN0FuZb01toc3vnODEfVUCooxG1SJN0yIirh7JMb9X9bvfCFf0vzzbT68RdbKDHYTiWy7a7iw==", + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz", + "integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==", + "license": "MIT" + }, + "node_modules/crelt": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.7.tgz", + "integrity": "sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==", + "license": "MIT" + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "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/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/d3-binarytree": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d3-binarytree/-/d3-binarytree-1.0.2.tgz", + "integrity": "sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==", + "license": "MIT" + }, + "node_modules/d3-color": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.1.tgz", + "integrity": "sha512-lfab8x0Bj0UO7SNsY8dZSbNIA6ipbkE3X0NG9nqjCu6CfCHZseuDnOSJY7hidKrjpP++i1M2qT+FlAdPKYRilA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.2.tgz", + "integrity": "sha512-sAzH4Y4nsLo8eSqw5jKiZt+LU2wZmL/qS+OkxQGjhwazB/D7TY34R/QK1eshfGr7cZEKymKZ/Haem7m+lu98Sg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.1.tgz", + "integrity": "sha512-OWeoayCq8J69hUIjvL+Mb6Q6Oaj/fyHV5XaXByEUAG+JUjIfTGDnk3qGpcXrD3VmQ3BSV96fcbM6fqq7C0tbPA==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-B5znKqRmKROAN4oHWQ50W/qisVjA9GXh2WMsVKdFVp4DxWmcrOsweqgUOUVsv5th96kwaZlokU6SlV4J3gak1w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force-3d": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/d3-force-3d/-/d3-force-3d-3.0.6.tgz", + "integrity": "sha512-4tsKHUPLOVkyfEffZo1v6sFHvGFwAIIjt/W8IThbp08DYAsXZck+2pSHEG5W1+gQgEvFLdZkYvmJAbRM2EzMnA==", + "license": "MIT", + "dependencies": { + "d3-binarytree": "1", + "d3-dispatch": "1 - 3", + "d3-octree": "1", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.2.tgz", + "integrity": "sha512-IRzGU62DtxhvsnSTWMQIdnoZ6gA+BCWwBon1EJI6SjoN595799b6z/QRBzXfFhE8iupUPp3042yBNo0STPqnzQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-octree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-octree/-/d3-octree-1.1.0.tgz", + "integrity": "sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A==", + "license": "MIT" + }, + "node_modules/d3-quadtree": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.2.tgz", + "integrity": "sha512-9Lu9mqJKRbIk0d6mKDjpvPURaPdwHVK5CYbcdd0/4vBgz4ldz/7TIOse3kNERsByGNfld58KEco507AztJWyTQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.1.tgz", + "integrity": "sha512-ODSf35vqCrlCfp7hrm0eZjvOosSXSYLjqvIlhMBV9q9VOx7EBJG6pc+uXBswEZNJgCGJ+qnKYcWutbZDIxe/Xg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-1Il1aliroVSErrv5aulRBxAY+7+DnaoLIWGd1C6SsBTWDeobWiP/V69vwb8vT6abR1kKwaNe1196pmaQ1fK90A==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.2.tgz", + "integrity": "sha512-RcjCsdFgyFoDB+QXLC5m60ZkTN0k9zH+ovoLlTdJnDS1AbfbcuowiM4pCKSTOclNibS4f4J4cbv2m7O7y8NTOQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.1.tgz", + "integrity": "sha512-kfjD3BDQu/FOatpZ6JdMSyIoDwTxIpI29ySTI2J5ZlDaH1WbuJGQJ2Q9oJkWTEZEW98j6idezoomSD3Cn2zwiw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-8.0.0.tgz", + "integrity": "sha512-JQUCCK+/CAGbGGx618PlFZMXH81Jtj7t73CHv9dd/zVWvxgGT2zLFRjnKb+Ng46GIwcy+f7f88qd4duqllK+WQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^17.1.2" + }, + "engines": { + "node": "^22.14.0 || >=24.0.0" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-gpu": { + "version": "5.0.70", + "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.70.tgz", + "integrity": "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==", + "license": "MIT", + "dependencies": { + "webgl-constants": "^1.1.1" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/draco3d": { + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.9.tgz", + "integrity": "sha512-MqC0eAfW5gPATGY3GABIyFWpHwdDGAyewTdek5R/e+mhI9ZDUMKb2mTDkTMUW0+Vm7an+ThEMUop3+svS72Uug==", + "license": "Apache-2.0" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.481", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.481.tgz", + "integrity": "sha512-dNUsbAP6E2S1dHIYEuN3cQ0dViThjMtpVRheGdvv5HgHFtzLi4Cu4Mbzms85YggP3Eh2VVZTl5+XxEN8ofCbmQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.26.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.26.1.tgz", + "integrity": "sha512-PPnnSJq3azKOIewXR/uppBV/6h98dprBJ/WaQ9Qgj10xX1lJLNfg+XShpbsrSqcDSy2yYYyhfXM1wWhftqgyzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-9.0.0.tgz", + "integrity": "sha512-oJFNDJg3kTPwAD1cNn2+WmUq4wFoo09npc3Ydf1D7ED4smRiWrsKnaLxykrTWgyGEcusc87P5dxlAleol9kpkg==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.14.0.tgz", + "integrity": "sha512-T0pNsxkb9IKmtQjhpK3d7nWOpFv+YHuMbTJnSVMoQblF0onvXfErrtp4V1jHtsQPan7dKaGVD0q1WCXnzMF31A==", + "dev": true, + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.7.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.3", + "@humanfs/node": "^0.16.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "11.1.5 || >11.1.6 <12", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.6", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "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-glob/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/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stringify": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-7.3.5.tgz", + "integrity": "sha512-g7H3xqJmdH9aWLWh8S3CqrRZFZ321yaeNHZp3QUDl3wtXDWjPChDXCDDTwA4M/zsU42nOhE+z5KmpCzgBaaCgw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/merge-json-schemas": "^0.2.0", + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^4.0.0", + "json-schema-ref-resolver": "^3.0.0", + "rfdc": "^1.2.0" + } + }, + "node_modules/fast-json-stringify/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/fast-json-stringify/node_modules/ajv/node_modules/fast-uri": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz", + "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "license": "MIT", + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "node_modules/fast-uri": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.2.3.tgz", + "integrity": "sha512-I1PXwP5eAhlNlcdpjt9CgB59op2ZvZfxw+BkqGFVIUOgNpCVTcTqp3HhTX7brxj5vsip+nSY4nTvff+eIA76hg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastify": { + "version": "5.12.8", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.12.8.tgz", + "integrity": "sha512-moP8exb2sCHLUbJkwp+I6C0padhy4D8lp0SdmzY7HhSdZuqm7O/u3o2aq7u8okaQ//33QDzj3G/u+FsSdB8Qzw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/ajv-compiler": "^4.0.5", + "@fastify/error": "^4.0.0", + "@fastify/fast-json-stringify-compiler": "^5.0.0", + "@fastify/proxy-addr": "^5.0.0", + "abstract-logging": "^2.0.1", + "avvio": "^9.0.0", + "fast-json-stringify": "^7.0.0", + "find-my-way": "^9.10.0", + "light-my-request": "^6.0.0", + "pino": "^9.14.0 || ^10.1.0", + "process-warning": "^5.1.0", + "rfdc": "^1.3.1", + "secure-json-parse": "^4.0.0", + "semver": "^7.6.0", + "toad-cache": "^3.7.0" + } + }, + "node_modules/fastify-plugin": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-6.0.1.tgz", + "integrity": "sha512-4wW4RxSmvPXLrh5mgQEiu43qU3bw44N2ss4FTkTkQIbprUhE+/s43QX0j/ttcztdWK7PEkHqVthdc5GdEGDvjA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fastify/node_modules/semver": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.6.tgz", + "integrity": "sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fastq": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fflate": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz", + "integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==", + "license": "MIT" + }, + "node_modules/file-entry-cache": { + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz", + "integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^6.1.23" + } + }, + "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/find-my-way": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.10.0.tgz", + "integrity": "sha512-eru+uCPQ2g+nLBkf84MHP/KyNNMar0BDy0j+i8Fb72GF9/YHBZ58q7FODUtfVV7XU9nfRUHXSmaM8NmZcIbZ4Q==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^5.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "6.1.23", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz", + "integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cacheable": "^2.5.0", + "flatted": "^3.4.2", + "hookified": "^1.15.0" + } + }, + "node_modules/flatted": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "13.0.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.7.tgz", + "integrity": "sha512-wfsFgXQ8A3SEI9XGf7Nl3Y9l7ffSrGh7SUCT7vU/2CzYPep9kjxAn1S40F9OPKxAMGCVl7HtNlJhrCJUeUq83g==", + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glsl-noise": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz", + "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==", + "license": "MIT" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphology": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/graphology/-/graphology-0.26.0.tgz", + "integrity": "sha512-8SSImzgUUYC89Z042s+0r/vMibY7GX/Emz4LDO5e7jYXhuoWfHISPFJYjpRLUSJGq6UQ6xlenvX1p/hJdfXuXg==", + "license": "MIT", + "dependencies": { + "events": "^3.3.0" + }, + "peerDependencies": { + "graphology-types": ">=0.24.0" + } + }, + "node_modules/graphology-communities-louvain": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/graphology-communities-louvain/-/graphology-communities-louvain-2.0.2.tgz", + "integrity": "sha512-zt+2hHVPYxjEquyecxWXoUoIuN/UvYzsvI7boDdMNz0rRvpESQ7+e+Ejv6wK7AThycbZXuQ6DkG8NPMCq6XwoA==", + "license": "MIT", + "dependencies": { + "graphology-indices": "^0.17.0", + "graphology-utils": "^2.4.4", + "mnemonist": "^0.39.0", + "pandemonium": "^2.4.1" + }, + "peerDependencies": { + "graphology-types": ">=0.19.0" + } + }, + "node_modules/graphology-indices": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/graphology-indices/-/graphology-indices-0.17.1.tgz", + "integrity": "sha512-ZY5zVyAVPJh/x+Topc+lcW+z2HHPn4YjhPS/orydotmmIhQ4dA13lK4KAD2RfPdsU8Z3HGwWQaBthQkJaTAF6w==", + "license": "MIT", + "dependencies": { + "graphology-utils": "^2.4.2", + "mnemonist": "^0.39.0" + }, + "peerDependencies": { + "graphology-types": ">=0.20.0" + } + }, + "node_modules/graphology-layout-forceatlas2": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/graphology-layout-forceatlas2/-/graphology-layout-forceatlas2-0.10.1.tgz", + "integrity": "sha512-ogzBeF1FvWzjkikrIFwxhlZXvD2+wlY54lqhsrWprcdPjopM2J9HoMweUmIgwaTvY4bUYVimpSsOdvDv1gPRFQ==", + "license": "MIT", + "dependencies": { + "graphology-utils": "^2.1.0" + }, + "peerDependencies": { + "graphology-types": ">=0.19.0" + } + }, + "node_modules/graphology-layout-noverlap": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/graphology-layout-noverlap/-/graphology-layout-noverlap-0.4.2.tgz", + "integrity": "sha512-13WwZSx96zim6l1dfZONcqLh3oqyRcjIBsqz2c2iJ3ohgs3605IDWjldH41Gnhh462xGB1j6VGmuGhZ2FKISXA==", + "license": "MIT", + "dependencies": { + "graphology-utils": "^2.3.0" + }, + "peerDependencies": { + "graphology-types": ">=0.19.0" + } + }, + "node_modules/graphology-types": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.8.tgz", + "integrity": "sha512-hDRKYXa8TsoZHjgEaysSRyPdT6uB78Ci8WnjgbStlQysz7xR52PInxNsmnB7IBOM1BhikxkNyCVEFgmPKnpx3Q==", + "license": "MIT" + }, + "node_modules/graphology-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/graphology-utils/-/graphology-utils-2.5.2.tgz", + "integrity": "sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==", + "license": "MIT", + "peerDependencies": { + "graphology-types": ">=0.23.0" + } + }, + "node_modules/hashery": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.15.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.7.tgz", + "integrity": "sha512-F7DNV2NMcTxA4GqPVHnXzX+mpoPHAIY9rJAVH3CZ1FdBZOcBUEjUuvMkMpHVs/sicEtznh9tMGj5WUR9S4E2rg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^2.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/hls.js": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.7.4.tgz", + "integrity": "sha512-3GlxGdPvT2YHvQYOt+yOzT/DEior/qJVNIylHA77kgeoBTdQQqi70GwefNEUmHQeNGyjC8U62+bruqW/Tpm+tg==", + "license": "Apache-2.0" + }, + "node_modules/hookified": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-encoding-sniffer": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-7.0.0.tgz", + "integrity": "sha512-UikN5yr7xsCDAq87Or5or0PAlD3HJJOKVzM05az588WnpDJ4Ux7a2A53Qi6gofGg2/EtvF/H4hCi/TXfCW4Y6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.15.1" + }, + "engines": { + "node": "^22.13.0 || >=24.0.0" + } + }, + "node_modules/html-to-image": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.13.tgz", + "integrity": "sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg==", + "license": "MIT" + }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/inline-style-parser": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.9.tgz", + "integrity": "sha512-IttN8BqKLxzUrnTqHI+/hwAJQItBAUjdoHERCDv+oOuX48VP6bzW8+QjOXSfoevzq3YrYAwX1uLHp8TqO9yIeg==", + "license": "MIT" + }, + "node_modules/ipaddr.js": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.5.0.tgz", + "integrity": "sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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-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", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "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/its-fine": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-2.1.1.tgz", + "integrity": "sha512-C5ZoVkeqSt0Aje0tzESO+iT/EQpNFNL39GkP7mCACtoZUFD6GcyerFCr6kp0ZtiII4W9HoYkY48Soy5xE/uHKw==", + "license": "MIT", + "dependencies": { + "@types/react-reconciler": "^0.28.9" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsdom": { + "version": "31.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-31.0.0.tgz", + "integrity": "sha512-xAkhD9z1eyFC5+QUi9K24CaZJgdCQ2GOGLW1GdVDoQvkp/AxEH9TQ0pAplPOlIiV92hfcgnFOADZypbjgbBT6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.16.0", + "bcp-47": "^2.1.2", + "bcp-47-match": "^2.0.3", + "data-urls": "^8.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^7.0.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.5.3", + "parse5": "^8.1.0", + "parse5-parser-stream": "^8.1.0", + "saxes": "^6.0.0", + "tough-cookie": "^6.0.2", + "undici": "^8.12.3", + "w3c-xmlserializer": "^6.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^17.3.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + }, + "peerDependencies": { + "@napi-rs/canvas": "^1.0.13" + }, + "peerDependenciesMeta": { + "@napi-rs/canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/lru-cache": { + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz", + "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-schema-ref-resolver": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-3.0.1.tgz", + "integrity": "sha512-w+HwgljXpVwZ3IidoUR1qPZxSOQ+NRQWuVe6a5pe8XbHsNZE4UAwVPUvzZagn7yBKbJtt6UJnRFYbNTRPZI45Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-with-bigint": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.12.tgz", + "integrity": "sha512-uwbF/wSSuOgC7qqlq27Xp5B6a2MHVug3t0idZdTqu0JnlFvgJuH7ju+KAk/J06C7GfhoYy2gnb9wz2INqcne7w==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/light-my-request": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-6.8.0.tgz", + "integrity": "sha512-5Q8PjoSEdtGIB8fikZsTem5vgRo4F2mR6vUKTDW/H1g6MtAt8e3duQbg/QxL5yzg6BZhor2KOUm3hhWMWLTZwg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "@fastify/deepmerge": "^3.1.0", + "cookie": "^2.0.0", + "process-warning": "^5.0.0", + "set-cookie-parser": "^3.0.1" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "1.72.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.72.0.tgz", + "integrity": "sha512-fbF5i1GU8GODETa3Q7rXqrJrcx3iPYrQtxthom103zGx+Z0BGwKYAW9s+9435ohYJ7hQm0av0PoZcqI1CRwNrg==", + "license": "ISC", + "peerDependencies": { + "@types/react": "*", + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/maath": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz", + "integrity": "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==", + "license": "MIT", + "peerDependencies": { + "@types/three": ">=0.134.0", + "three": ">=0.134.0" + } + }, + "node_modules/magic-string": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.5.tgz", + "integrity": "sha512-oLLC2+YvQUfAa+vxoufE/yc1icb87M9iXIRqAoR/2EhE/8cb3SF/+Gi0c2By1B+5Vz2e2vQtUvHiu1+63Znh+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.6.0" + } + }, + "node_modules/magicast": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.5.tgz", + "integrity": "sha512-UicdXN8zQ3JHlxVq+28afMXPr1z7WNY6+7EJnzTdQWkTAlMLF5fNCCKxJHBQwGaNGR11581EiQmQzx73+MvszA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "source-map-js": "^1.2.1" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.1.0.tgz", + "integrity": "sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.1.tgz", + "integrity": "sha512-oXp1GIa+E9IwIs3a106+tr3Bz2MlTTBvlXjOZMoIat11kk7vjqgmBnksB9WHmWv+gZh7k3IUgpAHlwHB7DH4GQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.2.3.tgz", + "integrity": "sha512-dImdB6VZRMRac1SwAW6o1c0ESk/7pFFAMCMuKM+9v7LpTSthMM5nzXpqKw4Mjo66aXVKhNkyrP4bMB9MurPyWg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "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/meshline": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz", + "integrity": "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==", + "license": "MIT", + "peerDependencies": { + "three": ">=0.137" + } + }, + "node_modules/meshoptimizer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-1.1.1.tgz", + "integrity": "sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g==", + "license": "MIT" + }, + "node_modules/micromark": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.3.tgz", + "integrity": "sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.4.tgz", + "integrity": "sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.1.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.3" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.1.0.tgz", + "integrity": "sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-edit-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-edit-map/-/micromark-util-edit-map-1.0.0.tgz", + "integrity": "sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.3.tgz", + "integrity": "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "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/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mnemonist": { + "version": "0.39.8", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz", + "integrity": "sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==", + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.63", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.63.tgz", + "integrity": "sha512-6li2QanLsAXpIH2R6j77MzRyvOyrvdTqlKtO4CgBdHGNvN99ZZfyxszHc5o5+IZBWD5u6Hzwg83JoGXmqZNG9Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/obliterator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", + "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", + "license": "MIT" + }, + "node_modules/obug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/obug/-/obug-3.0.0.tgz", + "integrity": "sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/octokit": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/octokit/-/octokit-5.0.5.tgz", + "integrity": "sha512-4+/OFSqOjoyULo7eN7EA97DE0Xydj/PW5aIckxqQIoFjFwqXKuFCvXUJObyJfBF9Khu4RL/jlDRI9FPaMGfPnw==", + "license": "MIT", + "dependencies": { + "@octokit/app": "^16.1.2", + "@octokit/core": "^7.0.6", + "@octokit/oauth-app": "^8.0.3", + "@octokit/plugin-paginate-graphql": "^6.0.0", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-rest-endpoint-methods": "^17.0.0", + "@octokit/plugin-retry": "^8.0.3", + "@octokit/plugin-throttling": "^11.0.3", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "@octokit/webhooks": "^14.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.3.tgz", + "integrity": "sha512-SKgVvDU5TNIxQ4r30U75BNLC6a+6GOEjngrk/ysM5+Zu3oJuk1SC5ApzIzY/7PjCEjoVPMWJ0zho/4QUiEB7TQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.2.1" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pandemonium": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/pandemonium/-/pandemonium-2.4.1.tgz", + "integrity": "sha512-wRqjisUyiUfXowgm7MFH2rwJzKIr20rca5FsHXCMNm1W5YPP1hCtrZfgmQ62kP7OZ7Xt+cR858aB28lu5NX55g==", + "license": "MIT", + "dependencies": { + "mnemonist": "^0.39.2" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse5": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.1.1.tgz", + "integrity": "sha512-EcR/6WDcU7b2N3vQSxKALCk9lXGtUMQxXio008OEMBE0kavu/7JLfBEeFPzi43nMqVDSbEn3QCK+BMCc9zO//w==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^9.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-8.1.1.tgz", + "integrity": "sha512-hMcVbbUJcQmP8rURWUdYrT1flRiBiBVjq/RYGguJpDUgIXSqdYKlE0CxthmdMWoSlBAuL5bUBa73g0pttSy7Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^8.1.1" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz", + "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "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/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-10.4.0.tgz", + "integrity": "sha512-bk1ZMTwG/Vymx+zPoa28MhNzucFvXJWp3csrSuxuHPSMeUettaCoQ5Jvg07mtC4JGNpcfTwz41oVCnNgBK9+vA==", + "license": "MIT", + "dependencies": { + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^3.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^1.0.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^4.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-3.0.0.tgz", + "integrity": "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", + "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", + "license": "MIT" + }, + "node_modules/playwright": { + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.65.0.tgz", + "integrity": "sha512-F3AMWcR44qMBt4kq+6Kb6mX7bjGXshktKFOPULd7reED6ZJWevjbNRqysP7q+AATE9kdPEZBibex1BYsvpVoeA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.65.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/playwright-core": { + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.65.0.tgz", + "integrity": "sha512-vNSKgH6YqtN7cdT/L334zo0a+YwkrpicyrHJlWWPIm/Q+Nn2SWInil01oT0mbu96U4GgoRtCYQD9CzJQgju+lA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/postcss": { + "version": "8.5.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.32.tgz", + "integrity": "sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.20", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/potpack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", + "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==", + "license": "ISC" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.10.0.tgz", + "integrity": "sha512-mBi4765LgjO1PFjlEs7pUeK0nb1bw71c+N4/ItfeUWNdY5cV2pRKaFpbbFRYmDJMO+5ZwzGxHRqHxFZna7iv5w==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/process-warning": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.1.1.tgz", + "integrity": "sha512-oCkNVj4OKnKEcocVBcDfiIugN1/cE6rgfT3nCtzeqZPA8+rIxMaQ0xXzIkGP8Gj2qUaP1UR7uhJ1VD8lUCpzCg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/promise-worker-transferable": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz", + "integrity": "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==", + "license": "Apache-2.0", + "dependencies": { + "is-promise": "^2.1.0", + "lie": "^3.0.2" + } + }, + "node_modules/property-information": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qified": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz", + "integrity": "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^2.1.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/qified/node_modules/hookified": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz", + "integrity": "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, + "node_modules/radix-ui": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/radix-ui/-/radix-ui-1.8.1.tgz", + "integrity": "sha512-HPfpVGizO9xANlsFSauruLhRe/3+iOt3vPX0MXYle/UQi3gorQrSYtBcdiv0BZYewcl2rvL59qrIuLFMGAmUrw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.2.0", + "@radix-ui/react-accessible-icon": "1.2.0", + "@radix-ui/react-accordion": "1.3.1", + "@radix-ui/react-alert-dialog": "1.2.1", + "@radix-ui/react-arrow": "1.1.17", + "@radix-ui/react-aspect-ratio": "1.2.0", + "@radix-ui/react-avatar": "1.3.1", + "@radix-ui/react-checkbox": "1.4.1", + "@radix-ui/react-collapsible": "1.2.1", + "@radix-ui/react-collection": "1.2.0", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.3.0", + "@radix-ui/react-context-menu": "2.4.1", + "@radix-ui/react-dialog": "1.3.1", + "@radix-ui/react-direction": "1.2.0", + "@radix-ui/react-dismissable-layer": "1.2.1", + "@radix-ui/react-dropdown-menu": "2.2.1", + "@radix-ui/react-focus-guards": "1.2.0", + "@radix-ui/react-focus-scope": "1.3.1", + "@radix-ui/react-form": "0.3.0", + "@radix-ui/react-hover-card": "1.2.1", + "@radix-ui/react-label": "2.1.17", + "@radix-ui/react-menu": "2.2.1", + "@radix-ui/react-menubar": "1.2.1", + "@radix-ui/react-navigation-menu": "1.4.1", + "@radix-ui/react-one-time-password-field": "0.2.1", + "@radix-ui/react-password-toggle-field": "0.2.1", + "@radix-ui/react-popover": "1.3.1", + "@radix-ui/react-popper": "1.4.0", + "@radix-ui/react-portal": "1.2.0", + "@radix-ui/react-presence": "1.1.11", + "@radix-ui/react-primitive": "2.2.0", + "@radix-ui/react-progress": "1.2.1", + "@radix-ui/react-radio-group": "1.5.1", + "@radix-ui/react-roving-focus": "1.2.1", + "@radix-ui/react-scroll-area": "1.4.0", + "@radix-ui/react-select": "2.4.1", + "@radix-ui/react-separator": "1.2.0", + "@radix-ui/react-slider": "1.6.1", + "@radix-ui/react-slot": "1.5.0", + "@radix-ui/react-switch": "1.4.1", + "@radix-ui/react-tabs": "1.2.1", + "@radix-ui/react-toast": "1.3.1", + "@radix-ui/react-toggle": "1.2.1", + "@radix-ui/react-toggle-group": "1.2.1", + "@radix-ui/react-toolbar": "1.2.1", + "@radix-ui/react-tooltip": "1.4.1", + "@radix-ui/react-use-callback-ref": "1.1.5", + "@radix-ui/react-use-controllable-state": "1.3.0", + "@radix-ui/react-use-effect-event": "0.0.5", + "@radix-ui/react-use-escape-keydown": "1.1.6", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-size": "1.1.5", + "@radix-ui/react-visually-hidden": "1.2.13" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/react": { + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.1.tgz", + "integrity": "sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.1.tgz", + "integrity": "sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.1" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/react-markdown": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", + "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-router": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-8.5.1.tgz", + "integrity": "sha512-5u1eQ46QjuXjNfEnLwzrnou1Bm5dquO3xjVYkkMYCudtkicD2AQHtx+fvXzPATtPJx8TW6DR1x1TDRqsfHyZBw==", + "license": "MIT", + "dependencies": { + "@remix-run/route-pattern": "^0.22.1", + "cookie-es": "^3.1.1" + }, + "engines": { + "node": ">=22.22.0" + }, + "peerDependencies": { + "@types/react": ">=19.2.0", + "@types/react-dom": ">=19.2.0", + "react": ">=19.2.7", + "react-dom": ">=19.2.7" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-use-measure": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz", + "integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.13", + "react-dom": ">=16.13" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/real-require": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-1.0.0.tgz", + "integrity": "sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==", + "license": "MIT" + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ret": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.5.1.tgz", + "integrity": "sha512-Z/nyvABwcRnRD2mMP7Kz6G1dFZZqX1mNErOnxF42OCQKE07b9k9hK9SQxHL3LFEZUdzQaLM4dId1E/E6Vm4WhA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "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/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/rolldown": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.19.tgz", + "integrity": "sha512-QIiV1J9d0pzN4jeeTH4sjPy0AZ6cAy2cG0ExeoE1+U8Rvj+hR3gYkokx0YbeUNGlZqiQJJ2utcETe0oKXwzsuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.156.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.19", + "@rolldown/binding-android-arm64": "1.2.19", + "@rolldown/binding-darwin-arm64": "1.2.19", + "@rolldown/binding-darwin-x64": "1.2.19", + "@rolldown/binding-freebsd-x64": "1.2.19", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.19", + "@rolldown/binding-linux-arm64-gnu": "1.2.19", + "@rolldown/binding-linux-arm64-musl": "1.2.19", + "@rolldown/binding-linux-ppc64-gnu": "1.2.19", + "@rolldown/binding-linux-s390x-gnu": "1.2.19", + "@rolldown/binding-linux-x64-gnu": "1.2.19", + "@rolldown/binding-linux-x64-musl": "1.2.19", + "@rolldown/binding-openharmony-arm64": "1.2.19", + "@rolldown/binding-wasm32-wasi": "1.2.19", + "@rolldown/binding-win32-arm64-msvc": "1.2.19", + "@rolldown/binding-win32-x64-msvc": "1.2.19" + } + }, + "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/safe-regex2": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.1.2.tgz", + "integrity": "sha512-tAtCGFPPP02VroDVzp4daGi6bC7jWG+41D47GKf18FeH/ubvKQHT9VmhAkvtjNOmJwqtApzWeUpEhkyEYULvmw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ret": "~0.5.0" + }, + "bin": { + "safe-regex2": "bin/safe-regex2.js" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/secure-json-parse": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.1.tgz", + "integrity": "sha512-lnd81MQEZKjhW/Gd2TQqdd4XP6QYNdDW/EP+I7nTrFHP9y2LmaGPIHk9xsnzcOiEr1c39c/e84xFgGviQKBTRw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/semver": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.2.tgz", + "integrity": "sha512-GYrCADwpu6yV5OAvchkQ27Z5wwMxWAEMg5NNWjyHh/5DboFFqbdbvYNIvZouQpxXyeMPoTOh0vdPYKlf0ZswdQ==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.2.2.tgz", + "integrity": "sha512-df017qMeYuXo4emL09nlyMpi2i2MtEIKS/6jtXH3vmjFgIRsOi852/5RmhJ4EkvN3ZF8jXadM/EkTPXgc8yPIw==", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "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/sigma": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/sigma/-/sigma-4.0.6.tgz", + "integrity": "sha512-3yD7On7NLHGMkBcG2fyhIECxkliqZ+lVcTBS1Lfm/qnndQVGMB+Xp2qL1A/co1qUJAM5bKank3cSrNO5L6J9Zw==", + "license": "MIT", + "dependencies": { + "events": "^3.3.0", + "graphology-utils": "^2.5.2" + } + }, + "node_modules/simple-git": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-4.0.2.tgz", + "integrity": "sha512-l0sIsv9VrPwovKELFDBOj/lhmIcbMvxBk2B+hRhsMM4/VL3gKtuZvYnBNixVo+N/0HnqQx2cBdLvxnAbygHpqA==", + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "@simple-git/args-pathspec": "1.0.4", + "@simple-git/argv-parser": "2.0.1", + "debug": "^4.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "node_modules/sonic-boom": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", + "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/stats-gl": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.4.2.tgz", + "integrity": "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==", + "license": "MIT", + "dependencies": { + "@types/three": "*", + "three": "^0.170.0" + }, + "peerDependencies": { + "@types/three": "*", + "three": "*" + } + }, + "node_modules/stats-gl/node_modules/three": { + "version": "0.170.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.170.0.tgz", + "integrity": "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==", + "license": "MIT" + }, + "node_modules/stats.js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", + "dev": true, + "license": "MIT" + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/style-mod": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.4.tgz", + "integrity": "sha512-XXWIQt633/EpAFx8aZDOTjBzrCaGmhvEQlQo6MVPfa2OzO2cWo+4hV9h+6UkHYlXGfy+ODXKUdP7Pthmcu5ATw==", + "license": "MIT" + }, + "node_modules/style-to-object": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-2.0.2.tgz", + "integrity": "sha512-QmbXPUylqU80HAgTOJeEOdbA40W9KtxmjMhQy+tq+b8F2aoh3aQLuy82hh2jm2qsC9hR9eI0+eQidTMydKcqRA==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.9" + } + }, + "node_modules/suspend-react": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz", + "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==", + "license": "MIT", + "peerDependencies": { + "react": ">=17.0" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.5.tgz", + "integrity": "sha512-FcQk9BuffmEHJP2G0XmB2SplU1aLTI7j07Kunk+U74Ny+XiWOtzXz9aujFZ/avntw1e2cOv/3PkgzflQ7gX2vQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/thread-stream": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-4.2.1.tgz", + "integrity": "sha512-Stg6edJXC/6/xqGwSXwFokrUhChJ18amEjpKH89WrQQ0oVFDF+pUUcTpiwWhFUrE89Vf16FBOlwhaw+lescxMQ==", + "license": "MIT", + "dependencies": { + "real-require": "^1.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/three": { + "version": "0.187.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.187.0.tgz", + "integrity": "sha512-Qiu7R+Cmh8CstZsY1uJOSWnVlfo7ZtNLV7mF8Jltk3LB3AtDu9cRZlcnRKkAk8Y4z6KKw35z7Y7Urd7jWY8etA==", + "license": "MIT" + }, + "node_modules/three-mesh-bvh": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.8.3.tgz", + "integrity": "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==", + "license": "MIT", + "peerDependencies": { + "three": ">= 0.159.0" + } + }, + "node_modules/three-stdlib": { + "version": "2.36.1", + "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.36.1.tgz", + "integrity": "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg==", + "license": "MIT", + "dependencies": { + "@types/draco3d": "^1.4.0", + "@types/offscreencanvas": "^2019.6.4", + "@types/webxr": "^0.5.2", + "draco3d": "^1.4.1", + "fflate": "^0.6.9", + "potpack": "^1.0.1" + }, + "peerDependencies": { + "three": ">=0.128.0" + } + }, + "node_modules/three-stdlib/node_modules/fflate": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.11.tgz", + "integrity": "sha512-3JyEFWGjFn7zHmoa9+zG1BmW7X2okcmAB+0Cnu9UFbVs/jCBnl2A8o065ZlXiw145K3eBM3uLuzrYXC0RK7eDg==", + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.2.3.tgz", + "integrity": "sha512-Al01C2JIBnO2CXCAPbpAl6sUiOZHeThGtHYNTa51JRw9PyWOCdr+9Ong05R4qg/Sk3+H645E8ov1h2c58ityNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/tinyexec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinyrainbow": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.2.0.tgz", + "integrity": "sha512-LgO3D9yZJjApUiuUfl9iFAwrtaX4+lok3wJIqttGoKCHlWUqHqbQpnxCf82L8FjgKsh4iGo78hqJwgL8F6To2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.4.22", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.22.tgz", + "integrity": "sha512-TmLwkCZ1GFMxGkKfg2ooQhPF8rDMuuXvJHSxFiOU1fofh27L6NaO5T9KSlQXCJX2eoSt14I8F4saSMILOmXmaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.4.22" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.4.22", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.22.tgz", + "integrity": "sha512-NRyhrlvJcTwvoRibE0dEZvp6C5RwV4RxpsX1zbkI1k7Fk2pzIhmQ+MvswJEd5KKl3VRFRMDTipXse/ejh/ld/w==", + "dev": true, + "license": "MIT" + }, + "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/toad-cache": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.4.tgz", + "integrity": "sha512-m1TdR/rvT7kgGJZhspNtXdsdYk0fddFpJJFlG5s+UkPFo6lkLoZ3YLOaovPYjq1R75NP5JfeTlSHaOsE09peCg==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.1.0.tgz", + "integrity": "sha512-FTxc8u8Kl2tz0Lat1u8ksvcy8bwHRyEMawwTWybo51JqaC6O7SvfuhAKg+Ld6VqyIe2QRJBzY9HA7y2WyFRT2w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-7.0.0.tgz", + "integrity": "sha512-BcDSDW+SIGWVOns1Zm6Yg91q9AEj7eaID0QDY9oIqJD1A8dscNwMcl9Sms2DeuWCNov1X0/oXanHGYQBSLwZsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": "^22.14.0 || >=24.0.0" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/troika-three-text": { + "version": "0.52.5", + "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.5.tgz", + "integrity": "sha512-Ry3jRhic9pzcY4JduSvRRyDmVOSqEW19gT4vtK+aCiPNVcDlmkxvGG0YbFd36RTDq1wExOupXnvNF/j1oiHHDA==", + "license": "MIT", + "dependencies": { + "bidi-js": "^1.0.2", + "troika-three-utils": "^0.52.5", + "troika-worker-utils": "^0.52.0", + "webgl-sdf-generator": "1.1.1" + }, + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-three-utils": { + "version": "0.52.5", + "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.52.5.tgz", + "integrity": "sha512-WsePbcX8RtfidRfsxK1eCZCjF81ZDzAKHH/evLs0hdV2wpoCb0vArGZHdzdOJrSS3k4zfdtbKDaBh8+phkrYnw==", + "license": "MIT", + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-worker-utils": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz", + "integrity": "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==", + "license": "MIT" + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.9.1.tgz", + "integrity": "sha512-a4Ux9VKuIMHsOS7ENbEq6hK2ZGYIT27Rtl0E4eD9KqwxhKiQeMZE/9xb3IdYwWaSOyIBQLExhQgXDTYoiCxnWA==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.23.15", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.15.tgz", + "integrity": "sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tunnel-rat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz", + "integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==", + "license": "MIT", + "dependencies": { + "zustand": "^4.3.2" + } + }, + "node_modules/tunnel-rat/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.72.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.72.2.tgz", + "integrity": "sha512-c/+AKMW1KB81r28Sp0AAdcyXj5dzNmAsZFcsrxKbZTKmcBK2xIwBR31dcSYSDu3bKmzXe8GKrSxO+eDQ401Uzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.72.2", + "@typescript-eslint/parser": "8.72.2", + "@typescript-eslint/typescript-estree": "8.72.2", + "@typescript-eslint/utils": "8.72.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/undici": { + "version": "8.12.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.12.4.tgz", + "integrity": "sha512-8Mx+uNKKER2bA4AdtedkqRbwUCIJFr2nJckXRe5yrDqzePqwLP7VNcctN8/XdmDSbF7mS+jJKIszlL+vbam1VA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.2.0.tgz", + "integrity": "sha512-fpsYs/VVoZxfGY9/j3FQpZmN8wdLJaV1Pt38AaJNZu9uKIHcFU3halCdBveEq1HGKO1OEfJY65w1zvoFV1b3qQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.1.0.tgz", + "integrity": "sha512-vKXxz6O38sKDj1mtx/k2cWvkkFBuYGx6uGrlzBkVeWCRF/F8sdI0j3Wbkz/5rVNRRuVc8UrgRdbCxNhmYXgP3w==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universal-github-app-jwt": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-2.2.2.tgz", + "integrity": "sha512-dcmbeSrOdTnsjGjUfAlqNDJrhxXizjAz94ija9Qw8YkZ1uu0d+GoZzyH+Jb9tIIqvGsadUfwg+22k5aDqqwzbw==", + "license": "MIT" + }, + "node_modules/universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "license": "ISC" + }, + "node_modules/update-browserslist-db": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.7.0.tgz", + "integrity": "sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.4.tgz", + "integrity": "sha512-66ycRswIkNmHH9PHku7ADtv5RVwgIrOcuv3J8Svz6h4qgGRrKVa+9/neuKyJZUXyOpYwLTvS+whZ4R2urHHgQg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "8.3.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.8.tgz", + "integrity": "sha512-LzOn3h9rG/0vhLdXrV4yJ4QFA9eEoqCl+Yx+kGJd7aB9w6nfNgVHKSYwLPZUHrz4ZGa+t+kXjV9itvcHDLQouA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.32", + "rolldown": "~1.2.18", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1 || ^0.8.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.1.0.tgz", + "integrity": "sha512-MzmNFnrwa8v8lF1bLxw3UJ4EREwVOVb75VqJZmUDRjJ6EluK/x9th7qTbaeDk41WxE1GxWqmTXcdsfobfH5sOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/mocker": "5.1.0", + "chai": "^6.3.0", + "es-module-lexer": "^2.3.2", + "expect-type": "^1.4.0", + "magic-string": "^1.4.3", + "obug": "^3.0.0", + "picomatch": "^4.0.7", + "std-env": "^4.3.0", + "tinybench": "^6.2.2", + "tinyexec": "^1.3.1", + "tinyglobby": "^0.2.17", + "why-is-node-running": "3.2.1" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^22.12.0 || ^24.0.0 || >=26.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "5.1.0", + "@vitest/browser-preview": "5.1.0", + "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", + "@vitest/coverage-istanbul": "5.1.0", + "@vitest/coverage-v8": "5.1.0", + "@vitest/ui": "5.1.0", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "license": "MIT" + }, + "node_modules/w3c-xmlserializer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-6.0.0.tgz", + "integrity": "sha512-4Nsy8K5Tr6SPDH9jhKJOHf7ChDrc1zufZTVSF7x72hwuEXBqxqk9G6cK+K2NRUtB3iELRJqjXb4JPDMBjMTl2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + } + }, + "node_modules/web-tree-sitter": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.27.2.tgz", + "integrity": "sha512-ZRo86GKI4aOSBAqOrPmCtriExI3xIzu1sNw/V6v3b4QGxrEmO19FGwbMNdyhw3MJLAZIw0xAV0oSpqX361eAyQ==", + "license": "MIT" + }, + "node_modules/webgl-constants": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz", + "integrity": "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==" + }, + "node_modules/webgl-sdf-generator": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz", + "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==", + "license": "MIT" + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-url": { + "version": "17.3.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.3.0.tgz", + "integrity": "sha512-KwOAJrpf+GTgBvcBQJcP38sMF0DsQKdwtG+TxM2pW44P6E5k0hDbWrDmyuJDIF0Uef0aQq0ZoJs+5oI+k8ddhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.16.0", + "tr46": "^7.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^22.14.0 || >=24.0.0" + } + }, + "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/why-is-node-running": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-3.2.1.tgz", + "integrity": "sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==", + "dev": true, + "license": "MIT", + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=20.11" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yauzl": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.4.0.tgz", + "integrity": "sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw==", + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz", + "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + }, + "node_modules/zustand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.1.0.tgz", + "integrity": "sha512-ciJZlP48M1PTQbVQq81CGVFxHTLpZNrFjKqwjtCU34AWuXTZT/jrF3p9+fI84Cf1eSCMLapxqBy/SNTfwOBuqA==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "packages/graph-engine": { + "name": "@vectora/graph-engine", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@vectora/graph-schema": "*", + "@vectora/shared": "*", + "graphology": "^0.26.0", + "graphology-communities-louvain": "^2.0.2", + "graphology-types": "^0.24.8" + } + }, + "packages/graph-layout": { + "name": "@vectora/graph-layout", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@vectora/graph-schema": "*", + "d3-force-3d": "^3.0.6" + } + }, + "packages/graph-schema": { + "name": "@vectora/graph-schema", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "zod": "^4.6.7" + } + }, + "packages/language-adapters": { + "name": "@vectora/language-adapters", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@vectora/graph-schema": "*", + "typescript": "~5.9.3", + "web-tree-sitter": "0.27.2" + } + }, + "packages/repository-indexer": { + "name": "@vectora/repository-indexer", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@vectora/graph-engine": "*", + "@vectora/graph-schema": "*", + "@vectora/language-adapters": "*", + "@vectora/shared": "*", + "fast-glob": "^3.3.3", + "ignore": "^7.0.14", + "p-limit": "^7.3.3" + } + }, + "packages/repository-indexer/node_modules/ignore": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.14.tgz", + "integrity": "sha512-wCBiZ77u1tuWde6G/nfOtLaCTYcFDU5yCzARzK10y+rLhzYoL7a7yEemcopcc2Mzow7gZOIjnV2ym1NYmdiJOQ==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "packages/search": { + "name": "@vectora/search", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@vectora/graph-schema": "*" + } + }, + "packages/shared": { + "name": "@vectora/shared", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "zod": "^4.6.7" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ed8bb7a --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "vectora", + "version": "0.1.0", + "private": true, + "description": "VECTORA — codebase intelligence platform. Understand what connects.", + "license": "MIT", + "type": "module", + "engines": { + "node": ">=22.13.0" + }, + "workspaces": [ + "packages/*", + "apps/*" + ], + "scripts": { + "dev": "node scripts/dev.mjs", + "dev:engine": "npm run dev -w @vectora/local-engine", + "dev:web": "npm run dev -w @vectora/web", + "build": "npm run build -w @vectora/web && node scripts/build-engine.mjs", + "start": "node dist/engine/server.mjs", + "typecheck": "tsc --noEmit -p tsconfig.json", + "lint": "eslint .", + "format": "prettier --write .", + "format:check": "prettier --check .", + "test": "vitest run", + "test:watch": "vitest", + "test:coverage": "vitest run --coverage", + "test:e2e": "playwright test", + "bench": "tsx scripts/bench.ts", + "licenses": "node scripts/license-inventory.mjs" + }, + "devDependencies": { + "@eslint/js": "^10.0.0", + "@playwright/test": "^1.65.0", + "@testing-library/jest-dom": "^6.6.0", + "@testing-library/react": "^16.3.3", + "@types/node": "^24.0.0", + "@vitest/coverage-v8": "^5.1.0", + "esbuild": "^0.28.0", + "eslint": "^10.14.0", + "eslint-plugin-react-hooks": "^7.0.0", + "globals": "^16.0.0", + "jsdom": "^31.0.0", + "prettier": "^3.10.0", + "tsx": "^4.23.15", + "typescript": "~5.9.3", + "typescript-eslint": "^8.72.2", + "vitest": "^5.1.0" + } +} diff --git a/packages/graph-engine/package.json b/packages/graph-engine/package.json new file mode 100644 index 0000000..dba5283 --- /dev/null +++ b/packages/graph-engine/package.json @@ -0,0 +1,9 @@ +{ + "name": "@vectora/graph-engine", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MIT", + "exports": { ".": "./src/index.ts" }, + "dependencies": { "@vectora/graph-schema": "*", "@vectora/shared": "*", "graphology": "^0.26.0", "graphology-communities-louvain": "^2.0.2", "graphology-types": "^0.24.8" } +} diff --git a/packages/graph-engine/src/algorithms.ts b/packages/graph-engine/src/algorithms.ts new file mode 100644 index 0000000..e5855af --- /dev/null +++ b/packages/graph-engine/src/algorithms.ts @@ -0,0 +1,267 @@ +/** + * Graph algorithms over the knowledge graph: adjacency index, traversal, + * cycle detection, impact analysis and community detection. + */ +import Graph from 'graphology'; +import louvain from 'graphology-communities-louvain'; +import type { EdgeType, GraphEdge, GraphNode, KnowledgeGraph } from '@vectora/graph-schema'; + +export interface GraphIndex { + nodes: Map; + edges: Map; + out: Map; + in: Map; +} + +export function buildIndex(graph: Pick): GraphIndex { + const nodes = new Map(); + const edges = new Map(); + const out = new Map(); + const inn = new Map(); + for (const n of graph.nodes) nodes.set(n.id, n); + for (const e of graph.edges) { + edges.set(e.id, e); + (out.get(e.source) ?? out.set(e.source, []).get(e.source)!).push(e); + (inn.get(e.target) ?? inn.set(e.target, []).get(e.target)!).push(e); + } + return { nodes, edges, out, in: inn }; +} + +/** Relationship types that express "A needs B to work". */ +export const DEPENDENCY_EDGES: readonly EdgeType[] = ['IMPORTS', 'CALLS', 'USES', 'EXTENDS', 'IMPLEMENTS', 'INSTANTIATES', 'READS_FROM', 'WRITES_TO', 'ROUTES_TO', 'DEPENDS_ON']; +const HIERARCHY_EDGES: readonly EdgeType[] = ['CONTAINS', 'DEFINED_IN', 'BELONGS_TO', 'EXPORTS']; + +export interface TraversalResult { + /** node id -> distance from the start */ + distances: Map; + edges: GraphEdge[]; + truncated: boolean; +} + +export function traverse( + index: GraphIndex, + start: string, + direction: 'out' | 'in', + opts: { types?: readonly EdgeType[]; maxDepth?: number; maxNodes?: number } = {}, +): TraversalResult { + const types = new Set(opts.types ?? DEPENDENCY_EDGES); + const maxDepth = opts.maxDepth ?? 4; + const maxNodes = opts.maxNodes ?? 500; + const distances = new Map([[start, 0]]); + const edges: GraphEdge[] = []; + let frontier = [start]; + let truncated = false; + for (let d = 1; d <= maxDepth && frontier.length; d++) { + const next: string[] = []; + for (const id of frontier) { + for (const e of (direction === 'out' ? index.out : index.in).get(id) ?? []) { + if (!types.has(e.type)) continue; + const other = direction === 'out' ? e.target : e.source; + edges.push(e); + if (distances.has(other)) continue; + if (distances.size >= maxNodes) { + truncated = true; + continue; + } + distances.set(other, d); + next.push(other); + } + } + frontier = next; + } + return { distances, edges, truncated }; +} + +/** Shortest directed path between two nodes over dependency edges. */ +export function shortestPath(index: GraphIndex, from: string, to: string, types: readonly EdgeType[] = DEPENDENCY_EDGES, maxDepth = 12): GraphEdge[] | null { + if (from === to) return []; + const allowed = new Set(types); + const prev = new Map(); + const seen = new Set([from]); + let frontier = [from]; + for (let d = 0; d < maxDepth && frontier.length; d++) { + const next: string[] = []; + for (const id of frontier) { + for (const e of index.out.get(id) ?? []) { + if (!allowed.has(e.type) || seen.has(e.target)) continue; + seen.add(e.target); + prev.set(e.target, e); + if (e.target === to) { + const path: GraphEdge[] = []; + for (let cur = to; cur !== from; ) { + const pe = prev.get(cur)!; + path.unshift(pe); + cur = pe.source; + } + return path; + } + next.push(e.target); + } + } + frontier = next; + } + return null; +} + +/** + * Strongly connected components (Tarjan, iterative) over the given edge + * types. Components with more than one node are dependency cycles. + */ +export function findCycles(index: GraphIndex, types: readonly EdgeType[] = ['IMPORTS'], nodeFilter?: (n: GraphNode) => boolean): string[][] { + const allowed = new Set(types); + const ids = [...index.nodes.values()].filter((n) => !nodeFilter || nodeFilter(n)).map((n) => n.id); + const idx = new Map(); + const low = new Map(); + const onStack = new Set(); + const stack: string[] = []; + const result: string[][] = []; + let counter = 0; + const succ = (id: string): string[] => { + const out: string[] = []; + for (const e of index.out.get(id) ?? []) { + if (!allowed.has(e.type) || e.target === id) continue; + const t = index.nodes.get(e.target); + if (t && (!nodeFilter || nodeFilter(t))) out.push(e.target); + } + return out; + }; + for (const root of ids) { + if (idx.has(root)) continue; + const work: { id: string; next: string[]; i: number }[] = [{ id: root, next: succ(root), i: 0 }]; + idx.set(root, counter); + low.set(root, counter++); + stack.push(root); + onStack.add(root); + while (work.length) { + const frame = work[work.length - 1]!; + if (frame.i < frame.next.length) { + const w = frame.next[frame.i++]!; + if (!idx.has(w)) { + idx.set(w, counter); + low.set(w, counter++); + stack.push(w); + onStack.add(w); + work.push({ id: w, next: succ(w), i: 0 }); + } else if (onStack.has(w)) low.set(frame.id, Math.min(low.get(frame.id)!, idx.get(w)!)); + } else { + work.pop(); + const parent = work[work.length - 1]; + if (parent) low.set(parent.id, Math.min(low.get(parent.id)!, low.get(frame.id)!)); + if (low.get(frame.id) === idx.get(frame.id)) { + const comp: string[] = []; + let w: string; + do { + w = stack.pop()!; + onStack.delete(w); + comp.push(w); + } while (w !== frame.id); + if (comp.length > 1) result.push(comp.reverse()); + } + } + } + } + return result.sort((a, b) => b.length - a.length); +} + +/** One concrete cycle path inside a strongly connected component. */ +export function cyclePath(index: GraphIndex, component: string[], types: readonly EdgeType[] = ['IMPORTS']): GraphEdge[] { + const set = new Set(component); + const start = component[0]!; + const allowed = new Set(types); + const prev = new Map(); + let frontier = [start]; + const seen = new Set(); + while (frontier.length) { + const next: string[] = []; + for (const id of frontier) { + for (const e of index.out.get(id) ?? []) { + if (!allowed.has(e.type) || !set.has(e.target)) continue; + if (e.target === start) { + const path = [e]; + for (let cur = id; cur !== start; ) { + const pe = prev.get(cur)!; + path.unshift(pe); + cur = pe.source; + } + return path; + } + if (seen.has(e.target)) continue; + seen.add(e.target); + prev.set(e.target, e); + next.push(e.target); + } + } + frontier = next; + } + return []; +} + +/** Everything that directly or transitively depends on `id` (reverse reachability). */ +export function impactOf(index: GraphIndex, id: string, maxDepth = 5, maxNodes = 400): TraversalResult { + // A change to a container affects dependants of its members too. + const seeds = [id]; + for (const e of index.out.get(id) ?? []) if (e.type === 'CONTAINS') seeds.push(e.target); + const merged: TraversalResult = { distances: new Map([[id, 0]]), edges: [], truncated: false }; + const edgeSeen = new Set(); + for (const s of seeds) { + const r = traverse(index, s, 'in', { maxDepth, maxNodes }); + for (const [k, v] of r.distances) if (!merged.distances.has(k) || merged.distances.get(k)! > v) merged.distances.set(k, v); + for (const e of r.edges) if (!edgeSeen.has(e.id)) (edgeSeen.add(e.id), merged.edges.push(e)); + merged.truncated ||= r.truncated; + } + return merged; +} + +/** The file (or the node itself) that owns a symbol. */ +export function containerChain(index: GraphIndex, id: string): GraphNode[] { + const chain: GraphNode[] = []; + let cur: string | undefined = id; + const seen = new Set(); + while (cur && !seen.has(cur)) { + seen.add(cur); + const parent: GraphEdge | undefined = (index.in.get(cur) ?? []).find((e) => e.type === 'CONTAINS' && e.extractionMethod === 'filesystem'); + if (!parent) break; + const n = index.nodes.get(parent.source); + if (n) chain.unshift(n); + cur = parent.source; + } + return chain; +} + +/** + * Louvain community detection on the undirected projection of dependency + * edges. Writes `metadata.community` on each node and returns the count. + */ +export function assignCommunities(nodes: GraphNode[], edges: GraphEdge[]): number { + const g = new Graph({ type: 'undirected', multi: false, allowSelfLoops: false }); + for (const n of nodes) g.addNode(n.id); + const skip = new Set(HIERARCHY_EDGES.filter((t) => t !== 'CONTAINS')); + for (const e of edges) { + if (skip.has(e.type) || e.source === e.target) continue; + if (!g.hasNode(e.source) || !g.hasNode(e.target)) continue; + // Containment keeps symbols near their file; dependencies pull related files together. + const w = e.type === 'CONTAINS' ? 1.5 : 1; + if (g.hasEdge(e.source, e.target)) g.updateEdgeAttribute(e.source, e.target, 'weight', (x: number | undefined) => (x ?? 0) + w); + else g.addEdge(e.source, e.target, { weight: w }); + } + if (g.size === 0) { + for (const n of nodes) n.metadata.community = 0; + return nodes.length ? 1 : 0; + } + // A fixed seed keeps community ids stable between runs on the same graph. + let seed = 42; + const rng = () => { + seed = (seed * 1664525 + 1013904223) % 4294967296; + return seed / 4294967296; + }; + const communities = louvain(g, { getEdgeWeight: 'weight', rng, resolution: 1 }); + const remap = new Map(); + for (const n of nodes) { + const c = communities[n.id] ?? -1; + if (!remap.has(c)) remap.set(c, remap.size); + n.metadata.community = remap.get(c)!; + } + return remap.size; +} + +export { HIERARCHY_EDGES }; diff --git a/packages/graph-engine/src/analysis.ts b/packages/graph-engine/src/analysis.ts new file mode 100644 index 0000000..61da9aa --- /dev/null +++ b/packages/graph-engine/src/analysis.ts @@ -0,0 +1,163 @@ +/** + * Repository analysis record (persisted next to the graph) and the overview + * derived from it. Every summary statement carries the evidence it is based on. + */ +import { type GraphNode, type KnowledgeGraph, type UnresolvedReference, type ValidationIssue, isSymbolType } from '@vectora/graph-schema'; +import type { IndexSummary, RepositoryOverview, RepositoryRecord } from '@vectora/shared'; +import { type GraphIndex, buildIndex, findCycles } from './algorithms'; + +export interface ExecutionFlow { + id: string; + name: string; + kind: 'request' | 'startup'; + steps: string[]; + reachesData: boolean; +} + +export interface RepositoryAnalysis { + generatedAt: string; + description: string | null; + descriptionSource: string | null; + languages: { language: string; name: string; tier: number; files: number; analyzedFiles: number; symbols: number; parseErrors: number; adapter: string | null; lines: number }[]; + frameworks: { name: string; evidence: string }[]; + entryPoints: { path: string; nodeId: string; reason: string }[]; + flows: ExecutionFlow[]; + declaredDependencies: { name: string; version: string | null; manifest: string; ecosystem: string; dev: boolean; line: number }[]; + unresolvedCount: number; + unresolvedByReason: Record; + unresolvedSamples: UnresolvedReference[]; + validation: { errors: number; warnings: number; issues: ValidationIssue[] }; + normalization: { removedNodes: number; mergedEdges: number; droppedEdges: number }; + skipped: Record; + truncated: boolean; + parseIssues: { path: string; message: string; line?: number; severity: string }[]; + communities: number; + summary: IndexSummary; +} + +export function buildOverview(repository: RepositoryRecord, graph: KnowledgeGraph, analysis: RepositoryAnalysis | null, index?: GraphIndex): RepositoryOverview { + const idx = index ?? buildIndex(graph); + const fileNodes = graph.nodes.filter((n) => n.type === 'File' || n.type === 'Configuration'); + + const symbolsPerFile = new Map(); + for (const n of graph.nodes) if (isSymbolType(n.type) && n.filePath) symbolsPerFile.set(n.filePath, (symbolsPerFile.get(n.filePath) ?? 0) + 1); + + const subsystems = graph.nodes + .filter((n) => n.type === 'Subsystem') + .map((s) => { + const files = (idx.in.get(s.id) ?? []).filter((e) => e.type === 'BELONGS_TO'); + let symbols = 0; + for (const e of files) symbols += symbolsPerFile.get(idx.nodes.get(e.source)?.filePath ?? '') ?? 0; + const dep = (list: typeof graph.edges | undefined) => (list ?? []).filter((e) => e.type === 'DEPENDS_ON').reduce((a, e) => a + Number(e.metadata?.count ?? 1), 0); + return { id: s.id, name: s.name, files: files.length, symbols, inbound: dep(idx.in.get(s.id)), outbound: dep(idx.out.get(s.id)) }; + }) + .sort((a, b) => b.files - a.files); + + const concepts = graph.nodes + .filter((n) => n.type === 'Concept') + .map((c) => { + const members = (idx.in.get(c.id) ?? []).filter((e) => e.type === 'BELONGS_TO').sort((a, b) => b.confidence - a.confidence); + return { id: c.id, name: c.name, members: members.length, evidence: members.slice(0, 3).map((e) => `${idx.nodes.get(e.source)?.filePath ?? e.source}: ${e.evidence}`) }; + }) + .sort((a, b) => b.members - a.members); + + const largestModules = fileNodes + .filter((f) => f.type === 'File') + .map((f) => ({ id: f.id, path: f.filePath!, symbols: symbolsPerFile.get(f.filePath!) ?? 0, lines: Number(f.metadata.lines ?? 0) })) + .sort((a, b) => b.symbols - a.symbols || b.lines - a.lines) + .slice(0, 12); + + const packages = graph.nodes.filter((n) => n.type === 'Package'); + const externalPackages = packages + .map((p) => ({ + name: p.name, + importers: new Set((idx.in.get(p.id) ?? []).filter((e) => e.type === 'IMPORTS').map((e) => e.source)).size, + declared: !!p.metadata.declared, + version: (p.metadata.version as string | null) ?? null, + })) + .sort((a, b) => b.importers - a.importers || (a.name < b.name ? -1 : 1)); + const internalImports = graph.edges.filter((e) => e.type === 'IMPORTS' && !e.target.startsWith('pkg:')).length; + + // ---- architecture summary: statements with evidence --------------------- + const summary: RepositoryOverview['architectureSummary'] = []; + const langs = analysis?.languages ?? []; + const analysed = langs.filter((l) => l.tier > 0 && l.files > 0).sort((a, b) => b.files - a.files); + if (analysed.length) { + const top = analysed[0]!; + summary.push({ + statement: `${fileNodes.length} files indexed; the primary language is ${top.name} (${top.files} files, ${top.symbols} symbols).`, + evidence: `File extensions and ${top.adapter ?? 'syntax'} analysis`, + verified: true, + }); + } + if (subsystems.length > 1) { + summary.push({ + statement: `The repository is organised into ${subsystems.length} subsystems; the largest are ${subsystems.slice(0, 3).map((s) => `${s.name} (${s.files} files)`).join(', ')}.`, + evidence: 'Directory layout and workspace manifests', + verified: true, + }); + const deps = graph.edges.filter((e) => e.type === 'DEPENDS_ON' && e.source.startsWith('sub:')).sort((a, b) => Number(b.metadata?.count ?? 0) - Number(a.metadata?.count ?? 0)); + for (const d of deps.slice(0, 4)) + summary.push({ + statement: `${idx.nodes.get(d.source)?.name} depends on ${idx.nodes.get(d.target)?.name} through ${d.metadata?.count} relationships.`, + evidence: d.evidence, + verified: true, + }); + } + const endpoints = graph.nodes.filter((n) => n.type === 'ApiEndpoint'); + if (endpoints.length) + summary.push({ + statement: `${endpoints.length} API endpoint${endpoints.length === 1 ? ' is' : 's are'} defined, for example ${endpoints.slice(0, 3).map((e) => e.name).join(', ')}.`, + evidence: endpoints.slice(0, 3).map((e) => `${e.filePath}:${e.location?.startLine}`).join(', '), + verified: true, + }); + const models = graph.nodes.filter((n) => n.type === 'DatabaseModel'); + if (models.length) + summary.push({ + statement: `${models.length} database model${models.length === 1 ? '' : 's'} detected: ${models.slice(0, 5).map((m) => m.name).join(', ')}${models.length > 5 ? ', ...' : ''}.`, + evidence: models.slice(0, 3).map((m) => `${m.filePath}:${m.location?.startLine}`).join(', '), + verified: true, + }); + const dataFlows = (analysis?.flows ?? []).filter((f) => f.reachesData); + if (dataFlows.length) + summary.push({ + statement: `${dataFlows.length} request flow${dataFlows.length === 1 ? '' : 's'} can be traced from an endpoint to data access.`, + evidence: `e.g. ${dataFlows[0]!.name}: ${dataFlows[0]!.steps.map((s) => idx.nodes.get(s)?.name ?? s).join(' → ')}`, + verified: false, + }); + const cycles = findCycles(idx, ['IMPORTS'], (n: GraphNode) => n.type === 'File'); + if (cycles.length) + summary.push({ + statement: `${cycles.length} circular import group${cycles.length === 1 ? '' : 's'} found; the largest involves ${cycles[0]!.length} files.`, + evidence: cycles[0]!.slice(0, 4).map((id) => idx.nodes.get(id)?.filePath).join(' → '), + verified: true, + }); + if (analysis && analysis.unresolvedCount > 0) + summary.push({ + statement: `${analysis.unresolvedCount} references could not be tied to a definition and are not shown as relationships.`, + evidence: Object.entries(analysis.unresolvedByReason).map(([r, c]) => `${c} × ${r}`).join('; '), + verified: true, + }); + + return { + repository, + description: analysis?.description ?? null, + descriptionSource: analysis?.descriptionSource ?? null, + languages: (analysis?.languages ?? []).map((l) => ({ ...l, language: l.name })), + frameworks: analysis?.frameworks ?? [], + entryPoints: analysis?.entryPoints ?? [], + subsystems, + concepts, + largestModules, + dependencies: { + declared: analysis?.declaredDependencies.length ?? 0, + imported: externalPackages.filter((p) => p.importers > 0).length, + internalImports, + externalPackages: externalPackages.slice(0, 200), + }, + architectureSummary: summary, + unresolved: analysis?.unresolvedCount ?? 0, + validation: { errors: analysis?.validation.errors ?? 0, warnings: analysis?.validation.warnings ?? 0 }, + summary: analysis?.summary ?? null, + }; +} diff --git a/packages/graph-engine/src/explore.ts b/packages/graph-engine/src/explore.ts new file mode 100644 index 0000000..6b11d6d --- /dev/null +++ b/packages/graph-engine/src/explore.ts @@ -0,0 +1,343 @@ +/** + * Question-driven repository exploration. + * + * Questions are answered by querying the knowledge graph: the engine picks an + * intent, locates the subject node, retrieves the relevant relationships and + * returns statements that each cite files and lines. Anything the graph does + * not establish is listed under `caveats` instead of being asserted. + */ +import { EDGE_TYPE_LABELS, type EdgeType, type GraphEdge, type GraphNode, NODE_TYPE_LABELS, isSymbolType } from '@vectora/graph-schema'; +import type { EvidenceRef, ExplorationAnswer, ExplorationStatement } from '@vectora/shared'; +import { type GraphIndex, containerChain, cyclePath, findCycles, impactOf, traverse } from './algorithms'; +import type { RepositoryAnalysis } from './analysis'; + +export type NodeFinder = (query: string, limit?: number) => GraphNode[]; + +type Intent = 'cycles' | 'startup' | 'callers' | 'dependents' | 'impact' | 'data-access' | 'trace' | 'explain'; + +const INTENTS: [Intent, RegExp][] = [ + ['cycles', /\b(circular|cycles?|cyclic)\b/i], + ['startup', /\b(start[- ]?up|boot(strap)?|entry points?|application start|launch sequence)\b/i], + ['callers', /\b(what|who|which)\b.*\bcalls?\b|\bcallers? of\b|\bcalled by\b|\bwhere is .* (called|used)\b/i], + ['impact', /\b(affected|impact|break|breaks|ripple)\b|\bif i (change|modify|remove|delete|rename)\b|\bchang(e|ing)\b.*\b(affect|impact)/i], + ['dependents', /\bdepend(s|ents?)? on\b|\bdependents of\b|\bwhich .* (use|uses|import|imports)\b|\bwho uses\b/i], + ['data-access', /\b(database|data|db|storage)\b.*\b(access|path|flow|queries|reads?|writes?)\b/i], + ['trace', /\b(trace|flow of|walk through|how does .* work|process|sequence|path from)\b/i], + ['explain', /\b(explain|what is|what does|describe|tell me about|overview of|summari[sz]e)\b/i], +]; + +const STOP = new Set( + ('a an the this that these those is are was were be been do does did what which who whom where when why how can could would should i me my we our you your it its of in on at to ' + + 'for from by with about into through and or if then than as so explain describe show tell trace identify list find give complete entire whole all any some ' + + 'calls call called caller callers depend depends dependents dependency dependencies on affected affect impact change changing changed modify remove delete rename ' + + 'break breaks module modules function functions class classes method methods service services file files process flow path access sequence overview work works ' + + 'happens happen use uses used using import imports there here please could').split(' '), +); + +const ev = (n: GraphNode | undefined, e?: GraphEdge): EvidenceRef[] => { + const out: EvidenceRef[] = []; + if (e?.location) out.push({ path: e.location.path, startLine: e.location.startLine, endLine: e.location.endLine, snippet: e.evidence, nodeId: e.source }); + else if (n?.location) out.push({ path: n.location.path, startLine: n.location.startLine, endLine: n.location.endLine, nodeId: n.id }); + return out; +}; +const where = (n: GraphNode | undefined): string => (n?.location ? ` (${n.location.path}:${n.location.startLine})` : n?.filePath ? ` (${n.filePath})` : ''); +const label = (n: GraphNode): string => `${NODE_TYPE_LABELS[n.type].toLowerCase()} \`${n.name}\``; + +export function detectIntent(question: string): Intent { + for (const [intent, re] of INTENTS) if (re.test(question)) return intent; + return 'explain'; +} + +/** Extracts the subject of a question: quoted or code-formatted text first, otherwise the remaining keywords. */ +export function extractSubject(question: string): string { + const quoted = /[`"'“]([^`"'”]{2,80})[`"'”]/.exec(question); + if (quoted) return quoted[1]!.trim(); + const words = question + .replace(/[?!.,;:()]/g, ' ') + .split(/\s+/) + .filter((w) => w && !STOP.has(w.toLowerCase())); + // Prefer tokens that look like identifiers or paths. + const ident = words.filter((w) => /[A-Z].*[a-z]|[a-z][A-Z]|[_/.]|\d/.test(w)); + return (ident.length ? ident : words).join(' ').trim(); +} + +export function explore(question: string, index: GraphIndex, analysis: RepositoryAnalysis | null, find: NodeFinder): ExplorationAnswer { + const intent = detectIntent(question); + const subject = extractSubject(question); + const answer: ExplorationAnswer = { question, intent, title: '', statements: [], nodeIds: [], edgeIds: [], caveats: [] }; + const say = (text: string, evidence: EvidenceRef[], verified = true) => answer.statements.push({ text, verified, evidence } satisfies ExplorationStatement); + const mark = (...ids: string[]) => { + for (const id of ids) if (!answer.nodeIds.includes(id) && answer.nodeIds.length < 300) answer.nodeIds.push(id); + }; + const markEdge = (e: GraphEdge) => { + if (answer.edgeIds.length < 600) answer.edgeIds.push(e.id); + }; + const node = (id: string) => index.nodes.get(id); + + const locate = (preferred?: (n: GraphNode) => boolean): GraphNode | null => { + if (!subject) return null; + const candidates = find(subject, 12); + if (!candidates.length) { + // Retry with individual words, longest first. + for (const w of subject.split(/\s+/).sort((a, b) => b.length - a.length)) { + const c = find(w, 8); + if (c.length) return (preferred && c.find(preferred)) || c[0]!; + } + return null; + } + return (preferred && candidates.slice(0, 5).find(preferred)) || candidates[0]!; + }; + const notFound = () => { + answer.title = subject ? `No match for “${subject}”` : 'No subject found'; + answer.caveats.push( + subject + ? `Nothing in the indexed graph matches “${subject}”. Try an exact symbol name, a file path or a concept.` + : 'The question does not name a symbol, file or concept that could be looked up.', + ); + return answer; + }; + + switch (intent) { + case 'cycles': { + const cycles = findCycles(index, ['IMPORTS'], (n) => n.type === 'File'); + answer.title = 'Circular dependencies'; + if (!cycles.length) { + say('No circular imports between files were found in the indexed graph.', []); + answer.caveats.push('Only import relationships that were resolved to files in this repository are considered.'); + return answer; + } + say(`${cycles.length} group${cycles.length === 1 ? '' : 's'} of files import each other in a cycle.`, []); + for (const comp of cycles.slice(0, 8)) { + const path = cyclePath(index, comp); + mark(...comp); + path.forEach(markEdge); + say( + `${comp.length} files: ${path.map((e) => node(e.source)?.filePath).join(' → ')} → ${node(path[0]?.source ?? comp[0]!)?.filePath}`, + path.slice(0, 6).flatMap((e) => ev(undefined, e)), + ); + } + if (cycles.length > 8) answer.caveats.push(`${cycles.length - 8} further cycle groups are not listed.`); + return answer; + } + + case 'startup': { + answer.title = 'Application startup'; + const entries = analysis?.entryPoints ?? []; + if (!entries.length) { + answer.caveats.push('No entry point could be identified from manifests or file conventions.'); + return answer; + } + for (const e of entries.slice(0, 6)) { + const n = node(e.nodeId); + mark(e.nodeId); + say(`\`${e.path}\` is an entry point: ${e.reason}.`, ev(n)); + const imports = (index.out.get(e.nodeId) ?? []).filter((x) => x.type === 'IMPORTS' && x.target.startsWith('file:')); + if (imports.length) { + imports.slice(0, 12).forEach((x) => (markEdge(x), mark(x.target))); + say(`It imports ${imports.length} internal file${imports.length === 1 ? '' : 's'}: ${imports.slice(0, 8).map((x) => `\`${node(x.target)?.filePath}\``).join(', ')}${imports.length > 8 ? ', ...' : ''}.`, imports.slice(0, 4).flatMap((x) => ev(undefined, x))); + } + } + for (const f of (analysis?.flows ?? []).filter((f) => f.kind === 'startup').slice(0, 4)) { + mark(...f.steps); + say(`Call chain from startup: ${f.steps.map((s) => `\`${node(s)?.name ?? s}\``).join(' → ')}.`, f.steps.slice(0, 5).flatMap((s) => ev(node(s))), false); + } + answer.caveats.push('Startup order is inferred from imports and resolved calls; runtime configuration can change it.'); + return answer; + } + + case 'callers': { + const target = locate((n) => n.type === 'Function' || n.type === 'Method' || n.type === 'Component' || n.type === 'Class'); + if (!target) return notFound(); + answer.title = `Callers of ${target.name}`; + mark(target.id); + const ids = [target.id, ...(index.out.get(target.id) ?? []).filter((e) => e.type === 'CONTAINS').map((e) => e.target)]; + const calls = ids.flatMap((id) => (index.in.get(id) ?? []).filter((e) => ['CALLS', 'INSTANTIATES', 'ROUTES_TO', 'USES'].includes(e.type))); + say(`${label(target)} is defined at ${target.location?.path}:${target.location?.startLine}.`, ev(target)); + if (!calls.length) { + say('No resolved call, instantiation or route points to it.', []); + answer.caveats.push('Calls made through dynamic dispatch, reflection or unresolved references are not visible in the graph.'); + return answer; + } + for (const e of calls.slice(0, 40)) { + const src = node(e.source); + mark(e.source); + markEdge(e); + say(`${src ? label(src) : e.source} ${EDGE_TYPE_LABELS[e.type]} \`${node(e.target)?.name}\`.`, ev(src, e), e.verified); + } + if (calls.length > 40) answer.caveats.push(`${calls.length - 40} further references are not listed.`); + return answer; + } + + case 'dependents': + case 'impact': { + const target = locate(); + if (!target) return notFound(); + const r = impactOf(index, target.id, intent === 'impact' ? 5 : 2, 400); + answer.title = intent === 'impact' ? `Impact of changing ${target.name}` : `What depends on ${target.name}`; + mark(target.id); + say(`${label(target)}${where(target)} is the subject.`, ev(target)); + const direct = [...r.distances.entries()].filter(([, d]) => d === 1).map(([id]) => id); + const transitive = [...r.distances.entries()].filter(([, d]) => d > 1); + if (!direct.length) { + say('Nothing in the indexed graph depends on it.', []); + answer.caveats.push('Unresolved or dynamic references cannot be ruled out.'); + return answer; + } + r.edges.forEach(markEdge); + const byFile = new Map(); + for (const id of direct) { + const n = node(id); + if (!n) continue; + mark(id); + const key = n.filePath ?? n.id; + (byFile.get(key) ?? byFile.set(key, []).get(key)!).push(n); + } + say(`${direct.length} node${direct.length === 1 ? '' : 's'} in ${byFile.size} file${byFile.size === 1 ? '' : 's'} depend on it directly.`, []); + for (const [file, list] of [...byFile.entries()].slice(0, 25)) { + const e = r.edges.find((x) => list.some((n) => n.id === x.source)); + say(`\`${file}\`: ${list.slice(0, 6).map((n) => `\`${n.name}\``).join(', ')}${list.length > 6 ? ', ...' : ''}${e ? ` — ${EDGE_TYPE_LABELS[e.type]}` : ''}.`, e ? ev(undefined, e) : ev(list[0]), e?.verified ?? true); + } + if (intent === 'impact' && transitive.length) { + transitive.slice(0, 150).forEach(([id]) => mark(id)); + const files = new Set(transitive.map(([id]) => node(id)?.filePath).filter(Boolean)); + say(`${transitive.length} further node${transitive.length === 1 ? '' : 's'} across ${files.size} file${files.size === 1 ? '' : 's'} are reachable through those dependants (up to 5 steps).`, [], false); + const subs = new Set([...r.distances.keys()].map((id) => node(id)?.metadata.subsystem as string | undefined).filter(Boolean)); + if (subs.size > 1) say(`The change crosses ${subs.size} subsystems: ${[...subs].map((s) => node(s!)?.name).join(', ')}.`, [], false); + } + if (r.truncated) answer.caveats.push('The result was truncated at 400 nodes.'); + answer.caveats.push('Impact is computed from resolved relationships only; unresolved references and runtime wiring are not included.'); + return answer; + } + + case 'data-access': { + answer.title = 'Database access paths'; + const dataEdges = [...index.edges.values()].filter((e) => e.type === 'READS_FROM' || e.type === 'WRITES_TO'); + const models = [...index.nodes.values()].filter((n) => n.type === 'DatabaseModel'); + if (!models.length && !dataEdges.length) { + answer.caveats.push('No database models or data-access relationships were detected in this repository.'); + return answer; + } + for (const m of models.slice(0, 15)) { + mark(m.id); + const inc = (index.in.get(m.id) ?? []).filter((e) => e.type === 'READS_FROM' || e.type === 'WRITES_TO'); + say(`Model \`${m.name}\`${where(m)} — ${inc.filter((e) => e.type === 'READS_FROM').length} readers, ${inc.filter((e) => e.type === 'WRITES_TO').length} writers.`, ev(m)); + for (const e of inc.slice(0, 6)) { + mark(e.source); + markEdge(e); + say(`\`${node(e.source)?.name}\` ${EDGE_TYPE_LABELS[e.type]} \`${m.name}\`${e.metadata?.operation ? ` via \`${String(e.metadata.operation)}\`` : ''}.`, ev(node(e.source), e), e.verified); + } + } + for (const f of (analysis?.flows ?? []).filter((f) => f.reachesData).slice(0, 8)) { + mark(...f.steps); + say(`${f.name}: ${f.steps.map((s) => `\`${node(s)?.name ?? s}\``).join(' → ')}.`, f.steps.slice(0, 6).flatMap((s) => ev(node(s))), false); + } + answer.caveats.push('Read and write relationships are detected from call patterns on known models and are marked as derived.'); + return answer; + } + + case 'trace': { + const target = locate((n) => n.type === 'ApiEndpoint' || n.type === 'Function' || n.type === 'Method'); + if (!target) return notFound(); + answer.title = `Trace: ${target.name}`; + let starts: GraphNode[] = [target]; + if (target.type === 'Concept' || target.type === 'Subsystem' || target.type === 'File' || target.type === 'Module' || target.type === 'Directory') { + const files = new Set( + target.type === 'File' ? [target.id] : (index.in.get(target.id) ?? []).filter((e) => e.type === 'BELONGS_TO').map((e) => e.source), + ); + const inFiles = [...index.nodes.values()].filter((n) => n.filePath && files.has(`file:${n.filePath}`)); + const endpoints = inFiles.filter((n) => n.type === 'ApiEndpoint'); + const tokens = subject.toLowerCase().split(/\s+/); + const named = inFiles.filter((n) => (n.type === 'Function' || n.type === 'Method') && tokens.some((t) => n.name.toLowerCase().includes(t))); + starts = (endpoints.length ? endpoints : named).slice(0, 4); + say(`${label(target)} groups ${files.size} file${files.size === 1 ? '' : 's'}; tracing from ${starts.length ? starts.map((s) => `\`${s.name}\``).join(', ') : 'no callable entry'}.`, [], target.verified); + if (!starts.length) { + answer.caveats.push('No endpoint or function inside this group could be used as a starting point.'); + return answer; + } + } + for (const s of starts) { + mark(s.id); + say(`Starts at ${label(s)}${where(s)}.`, ev(s)); + const r = traverse(index, s.id, 'out', { types: ['ROUTES_TO', 'CALLS', 'INSTANTIATES', 'READS_FROM', 'WRITES_TO'], maxDepth: 6, maxNodes: 80 }); + if (r.distances.size === 1) { + say('No outgoing calls were resolved from here.', []); + continue; + } + const seen = new Set(); + for (const e of r.edges) { + if (seen.has(e.id)) continue; + seen.add(e.id); + if (seen.size > 40) break; + markEdge(e); + mark(e.source, e.target); + const depth = r.distances.get(e.source) ?? 0; + say(`${'· '.repeat(depth)}\`${node(e.source)?.name}\` ${EDGE_TYPE_LABELS[e.type]} \`${node(e.target)?.name}\`${where(node(e.target))}.`, ev(node(e.source), e), e.verified); + } + if (r.truncated || r.edges.length > 40) answer.caveats.push('The trace was shortened; expand nodes in the graph to follow it further.'); + } + answer.caveats.push('Only statically resolved calls are followed. Callbacks, events and framework wiring may add steps that are not shown.'); + return answer; + } + + case 'explain': + default: { + const target = locate((n) => n.type === 'Concept' || n.type === 'Subsystem'); + if (!target) return notFound(); + answer.title = target.name; + mark(target.id); + const outE = index.out.get(target.id) ?? []; + const inE = index.in.get(target.id) ?? []; + if (target.type === 'Concept' || target.type === 'Subsystem') { + const members = inE.filter((e) => e.type === 'BELONGS_TO').sort((a, b) => b.confidence - a.confidence); + say( + `${target.name} is a ${target.type === 'Concept' ? 'concept group derived from identifier and path evidence' : 'subsystem derived from the repository layout'} with ${members.length} file${members.length === 1 ? '' : 's'}.`, + [], + target.verified, + ); + for (const m of members.slice(0, 12)) { + const f = node(m.source); + mark(m.source); + markEdge(m); + const syms = (index.out.get(m.source) ?? []).filter((e) => e.type === 'CONTAINS').map((e) => node(e.target)).filter((n): n is GraphNode => !!n && isSymbolType(n.type)); + say(`\`${f?.filePath}\` — ${m.evidence}${syms.length ? `. Defines ${syms.slice(0, 6).map((s) => `\`${s.name}\``).join(', ')}${syms.length > 6 ? ', ...' : ''}` : ''}.`, ev(f), m.verified); + } + const deps = [...outE, ...inE].filter((e) => e.type === 'DEPENDS_ON' || e.type === 'RELATED_TO'); + for (const d of deps.slice(0, 8)) { + markEdge(d); + mark(d.source, d.target); + say(`${node(d.source)?.name} ${EDGE_TYPE_LABELS[d.type]} ${node(d.target)?.name}: ${d.evidence}`, ev(undefined, d), d.verified); + } + if (members.length > 12) answer.caveats.push(`${members.length - 12} further member files are not listed.`); + if (target.type === 'Concept') answer.caveats.push('Concept membership is an interpretation based on names and paths, not a verified fact.'); + return answer; + } + const chain = containerChain(index, target.id); + say(`${label(target)} is defined at ${target.location ? `${target.location.path}:${target.location.startLine}–${target.location.endLine}` : (target.filePath ?? 'an unknown location')}${chain.length ? `, inside ${chain.slice(-2).map((c) => c.name).join(' / ')}` : ''}.`, ev(target)); + if (target.description) say(`Documented as: ${target.description}`, ev(target)); + if (target.metadata.signature) say(`Signature: \`${String(target.metadata.signature)}\``, ev(target)); + const group = (edges: GraphEdge[], dir: 'out' | 'in') => { + const byType = new Map(); + for (const e of edges) { + if (e.type === 'CONTAINS' && dir === 'in') continue; + if (e.type === 'DEFINED_IN' || e.type === 'BELONGS_TO') continue; + (byType.get(e.type) ?? byType.set(e.type, []).get(e.type)!).push(e); + } + for (const [type, list] of byType) { + list.slice(0, 15).forEach((e) => (markEdge(e), mark(dir === 'out' ? e.target : e.source))); + const names = list.slice(0, 8).map((e) => `\`${node(dir === 'out' ? e.target : e.source)?.name}\``).join(', '); + say( + dir === 'out' ? `It ${EDGE_TYPE_LABELS[type]} ${names}${list.length > 8 ? ` and ${list.length - 8} more` : ''}.` : `${names}${list.length > 8 ? ` and ${list.length - 8} more` : ''} ${list.length === 1 ? EDGE_TYPE_LABELS[type] : EDGE_TYPE_LABELS[type].replace(/s\b/, '')} it.`, + list.slice(0, 4).flatMap((e) => ev(node(e.source), e)), + list.every((e) => e.verified), + ); + } + }; + group(outE, 'out'); + group(inE, 'in'); + const concepts = ((target.filePath ? node(`file:${target.filePath}`)?.metadata.concepts : null) as string[] | null) ?? []; + if (concepts.length) say(`Its file is associated with: ${concepts.map((c) => node(c)?.name).join(', ')}.`, [], false); + if (outE.length + inE.length <= 1) answer.caveats.push('Few relationships were resolved for this node; it may be used dynamically or not at all.'); + return answer; + } + } +} diff --git a/packages/graph-engine/src/exports.ts b/packages/graph-engine/src/exports.ts new file mode 100644 index 0000000..9f7bd1f --- /dev/null +++ b/packages/graph-engine/src/exports.ts @@ -0,0 +1,250 @@ +/** + * Graph exports: JSON, GraphML, Markdown analysis and architecture + * documentation. Node ids and relationships are always preserved. Source + * text (evidence lines, signatures, doc comments) is only included when the + * caller explicitly asks for it. + */ +import { EDGE_TYPE_LABELS, type GraphEdge, type GraphNode, type KnowledgeGraph, NODE_TYPE_LABELS, isSymbolType } from '@vectora/graph-schema'; +import { APP_VERSION, type RepositoryOverview, type RepositoryRecord } from '@vectora/shared'; +import { buildIndex, cyclePath, findCycles } from './algorithms'; +import type { RepositoryAnalysis } from './analysis'; + +export interface ExportOptions { + includeSource?: boolean; +} + +const SOURCE_METADATA_KEYS = ['signature', 'attributes', 'hash']; + +/** Removes source text from a graph so it can be shared without repository contents. */ +export function stripSource(graph: Pick): { nodes: GraphNode[]; edges: GraphEdge[] } { + const nodes = graph.nodes.map((n) => { + const metadata = { ...n.metadata }; + for (const k of SOURCE_METADATA_KEYS) delete metadata[k]; + const out: GraphNode = { ...n, metadata }; + // Descriptions of symbols are doc comments, i.e. repository content. + if (isSymbolType(n.type) || n.type === 'Repository') delete out.description; + return out; + }); + const edges = graph.edges.map((e) => ({ + ...e, + evidence: e.location ? `${e.location.path}:${e.location.startLine}` : e.extractionMethod, + })); + return { nodes, edges }; +} + +export function exportJson(repository: RepositoryRecord, graph: KnowledgeGraph, opts: ExportOptions = {}): string { + const { nodes, edges } = opts.includeSource ? graph : stripSource(graph); + return JSON.stringify( + { + format: 'vectora-graph', + schemaVersion: graph.schemaVersion, + exportedAt: new Date().toISOString(), + generator: `VECTORA ${APP_VERSION}`, + includesSource: !!opts.includeSource, + repository: { id: repository.id, name: repository.name, sourceKind: repository.sourceKind, branch: repository.branch, lastIndexedAt: repository.lastIndexedAt }, + stats: graph.stats, + nodes, + edges, + }, + null, + 2, + ); +} + +const xml = (s: unknown): string => + String(s ?? '') + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + // eslint-disable-next-line no-control-regex + .replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g, ''); + +export function exportGraphML(repository: RepositoryRecord, graph: KnowledgeGraph, opts: ExportOptions = {}): string { + const { nodes, edges } = opts.includeSource ? graph : stripSource(graph); + const nodeKeys: [string, string, (n: GraphNode) => unknown][] = [ + ['name', 'string', (n) => n.name], + ['type', 'string', (n) => n.type], + ['filePath', 'string', (n) => n.filePath ?? ''], + ['startLine', 'int', (n) => n.location?.startLine ?? ''], + ['endLine', 'int', (n) => n.location?.endLine ?? ''], + ['language', 'string', (n) => n.language ?? ''], + ['extractionMethod', 'string', (n) => n.extractionMethod], + ['confidence', 'double', (n) => n.confidence], + ['verified', 'boolean', (n) => n.verified], + ]; + const edgeKeys: [string, string, (e: GraphEdge) => unknown][] = [ + ['relationship', 'string', (e) => e.type], + ['evidence', 'string', (e) => e.evidence], + ['evidencePath', 'string', (e) => e.location?.path ?? ''], + ['evidenceLine', 'int', (e) => e.location?.startLine ?? ''], + ['edgeExtractionMethod', 'string', (e) => e.extractionMethod], + ['edgeConfidence', 'double', (e) => e.confidence], + ['edgeVerified', 'boolean', (e) => e.verified], + ]; + const out: string[] = [ + '', + '', + ` `, + ]; + for (const [k, t] of nodeKeys) out.push(` `); + for (const [k, t] of edgeKeys) out.push(` `); + out.push(` `); + for (const n of nodes) { + out.push(` `); + for (const [k, , get] of nodeKeys) { + const v = get(n); + if (v !== '' && v !== null && v !== undefined) out.push(` ${xml(v)}`); + } + out.push(' '); + } + for (const e of edges) { + out.push(` `); + for (const [k, , get] of edgeKeys) { + const v = get(e); + if (v !== '' && v !== null && v !== undefined) out.push(` ${xml(v)}`); + } + out.push(' '); + } + out.push(' ', '', ''); + return out.join('\n'); +} + +const mdEscape = (s: string): string => s.replace(/\|/g, '\\|').replace(/\n/g, ' '); + +export function exportMarkdownAnalysis(overview: RepositoryOverview, graph: KnowledgeGraph, analysis: RepositoryAnalysis | null): string { + const r = overview.repository; + const L: string[] = []; + L.push(`# ${r.name} — repository analysis`, ''); + L.push(`Generated by VECTORA ${APP_VERSION} on ${new Date().toISOString().slice(0, 10)}.`, ''); + if (overview.description) L.push(`> ${overview.description}`, '', `Source: \`${overview.descriptionSource}\``, ''); + L.push('## Index', ''); + L.push(`| | |`, `|---|---|`); + L.push(`| Source | ${r.sourceKind} |`); + if (r.branch) L.push(`| Branch | ${r.branch} |`); + L.push(`| Last indexed | ${r.lastIndexedAt ?? 'never'} |`); + L.push(`| Files | ${graph.stats.fileCount} |`, `| Symbols | ${graph.stats.symbolCount} |`, `| Relationships | ${graph.stats.edgeCount} |`); + L.push(`| Verified relationships | ${graph.stats.verifiedEdges} |`, `| Derived relationships | ${graph.stats.unverifiedEdges} |`, `| Unresolved references | ${overview.unresolved} |`, ''); + + L.push('## Languages', '', '| Language | Files | Analysed | Symbols | Technique |', '|---|---:|---:|---:|---|'); + for (const l of overview.languages) L.push(`| ${l.language} | ${l.files} | ${l.analyzedFiles} | ${l.symbols} | ${l.adapter ?? 'not analysed at symbol level'} |`); + L.push(''); + if (overview.frameworks.length) { + L.push('## Frameworks', ''); + for (const f of overview.frameworks) L.push(`- **${f.name}** — ${f.evidence}`); + L.push(''); + } + L.push('## Architecture summary', ''); + for (const s of overview.architectureSummary) L.push(`- ${s.statement}${s.verified ? '' : ' _(derived)_'} \n Evidence: ${s.evidence}`); + L.push(''); + if (overview.entryPoints.length) { + L.push('## Entry points', ''); + for (const e of overview.entryPoints) L.push(`- \`${e.path}\` — ${e.reason}`); + L.push(''); + } + if (overview.subsystems.length) { + L.push('## Subsystems', '', '| Subsystem | Files | Symbols | Outbound | Inbound |', '|---|---:|---:|---:|---:|'); + for (const s of overview.subsystems) L.push(`| ${mdEscape(s.name)} | ${s.files} | ${s.symbols} | ${s.outbound} | ${s.inbound} |`); + L.push(''); + } + if (overview.concepts.length) { + L.push('## Concepts', '', 'Concept groups are derived from identifier and path evidence; they are interpretations, not verified facts.', ''); + for (const c of overview.concepts) L.push(`- **${c.name}** — ${c.members} files`); + L.push(''); + } + L.push('## Largest modules', '', '| File | Symbols | Lines |', '|---|---:|---:|'); + for (const m of overview.largestModules) L.push(`| \`${m.path}\` | ${m.symbols} | ${m.lines} |`); + L.push(''); + L.push('## Dependencies', ''); + L.push(`${overview.dependencies.declared} declared in manifests, ${overview.dependencies.imported} imported by source files, ${overview.dependencies.internalImports} internal imports.`, ''); + const top = overview.dependencies.externalPackages.filter((p) => p.importers > 0).slice(0, 30); + if (top.length) { + L.push('| Package | Importing files | Declared | Version |', '|---|---:|---|---|'); + for (const p of top) L.push(`| ${mdEscape(p.name)} | ${p.importers} | ${p.declared ? 'yes' : 'no'} | ${p.version ?? ''} |`); + L.push(''); + } + if (analysis && analysis.unresolvedCount) { + L.push('## Unresolved references', ''); + for (const [reason, count] of Object.entries(analysis.unresolvedByReason)) L.push(`- ${count} × ${reason}`); + L.push(''); + } + return L.join('\n'); +} + +export function exportArchitectureDoc(overview: RepositoryOverview, graph: KnowledgeGraph, analysis: RepositoryAnalysis | null): string { + const idx = buildIndex(graph); + const name = (id: string) => idx.nodes.get(id)?.name ?? id; + const L: string[] = []; + L.push(`# ${overview.repository.name} — architecture`, ''); + L.push(`Generated by VECTORA ${APP_VERSION} from the knowledge graph (${graph.stats.nodeCount} nodes, ${graph.stats.edgeCount} relationships).`, ''); + L.push('Statements marked _derived_ are interpretations built on top of verified structure.', ''); + L.push('## Subsystems', ''); + for (const s of overview.subsystems) { + const node = idx.nodes.get(s.id); + L.push(`### ${s.name}`, ''); + L.push(`${node?.description ?? ''} ${s.files} files, ${s.symbols} symbols.`.trim(), ''); + const deps = (idx.out.get(s.id) ?? []).filter((e) => e.type === 'DEPENDS_ON'); + if (deps.length) { + L.push('Depends on:', ''); + for (const d of deps.sort((a, b) => Number(b.metadata?.count ?? 0) - Number(a.metadata?.count ?? 0))) L.push(`- **${name(d.target)}** — ${d.metadata?.count} relationships (${d.location ? `\`${d.location.path}:${d.location.startLine}\`` : 'aggregated'})`); + L.push(''); + } + const users = (idx.in.get(s.id) ?? []).filter((e) => e.type === 'DEPENDS_ON'); + if (users.length) L.push(`Used by: ${users.map((u) => name(u.source)).join(', ')}.`, ''); + } + const deps = graph.edges.filter((e) => e.type === 'DEPENDS_ON' && e.source.startsWith('sub:')); + if (deps.length) { + L.push('## Subsystem dependency diagram', '', '```mermaid', 'graph LR'); + const mid = (id: string) => `n${[...idx.nodes.keys()].indexOf(id)}`; + const ids = new Set(); + for (const d of deps) (ids.add(d.source), ids.add(d.target)); + for (const id of ids) L.push(` ${mid(id)}["${name(id).replace(/"/g, "'")}"]`); + for (const d of deps) L.push(` ${mid(d.source)} -->|${d.metadata?.count ?? ''}| ${mid(d.target)}`); + L.push('```', ''); + } + if (overview.entryPoints.length) { + L.push('## Entry points', ''); + for (const e of overview.entryPoints) L.push(`- \`${e.path}\` — ${e.reason}`); + L.push(''); + } + const endpoints = graph.nodes.filter((n) => n.type === 'ApiEndpoint'); + if (endpoints.length) { + L.push('## API endpoints', '', '| Endpoint | Defined at | Handler |', '|---|---|---|'); + for (const e of endpoints.slice(0, 200)) { + const h = (idx.out.get(e.id) ?? []).find((x) => x.type === 'ROUTES_TO'); + L.push(`| \`${mdEscape(e.name)}\` | \`${e.filePath}:${e.location?.startLine}\` | ${h ? `\`${mdEscape(name(h.target))}\`` : 'inline'} |`); + } + L.push(''); + } + const models = graph.nodes.filter((n) => n.type === 'DatabaseModel'); + if (models.length) { + L.push('## Database models', '', '| Model | Defined at | Readers | Writers |', '|---|---|---:|---:|'); + for (const m of models) { + const inc = idx.in.get(m.id) ?? []; + L.push(`| \`${mdEscape(m.name)}\` | \`${m.filePath}:${m.location?.startLine}\` | ${inc.filter((e) => e.type === 'READS_FROM').length} | ${inc.filter((e) => e.type === 'WRITES_TO').length} |`); + } + L.push(''); + } + if (analysis?.flows.length) { + L.push('## Execution flows', '', '_Derived by following route and call relationships._', ''); + for (const f of analysis.flows.slice(0, 40)) L.push(`- **${f.name}**${f.reachesData ? ' (reaches data access)' : ''}: ${f.steps.map((s) => `\`${name(s)}\``).join(' → ')}`); + L.push(''); + } + const cycles = findCycles(idx, ['IMPORTS'], (n) => n.type === 'File'); + L.push('## Circular dependencies', ''); + if (!cycles.length) L.push('No circular imports between files were found.', ''); + for (const c of cycles.slice(0, 20)) { + const path = cyclePath(idx, c); + L.push(`- ${c.length} files: ${path.map((e) => `\`${idx.nodes.get(e.source)?.filePath}\``).join(' → ')} → \`${idx.nodes.get(path[0]?.source ?? c[0]!)?.filePath}\``); + } + L.push(''); + L.push('## Relationship legend', ''); + for (const [k, v] of Object.entries(EDGE_TYPE_LABELS)) L.push(`- \`${k}\` — ${v} (${graph.stats.edgesByType[k as keyof typeof EDGE_TYPE_LABELS] ?? 0})`); + L.push('', '## Node types', ''); + for (const [k, v] of Object.entries(NODE_TYPE_LABELS)) { + const c = graph.stats.nodesByType[k as keyof typeof NODE_TYPE_LABELS] ?? 0; + if (c) L.push(`- ${v}: ${c}`); + } + L.push(''); + return L.join('\n'); +} diff --git a/packages/graph-engine/src/index.ts b/packages/graph-engine/src/index.ts new file mode 100644 index 0000000..6d420c6 --- /dev/null +++ b/packages/graph-engine/src/index.ts @@ -0,0 +1,5 @@ +export * from './algorithms'; +export * from './analysis'; +export * from './exports'; +export * from './explore'; +export * from './store'; diff --git a/packages/graph-engine/src/store.ts b/packages/graph-engine/src/store.ts new file mode 100644 index 0000000..b57245f --- /dev/null +++ b/packages/graph-engine/src/store.ts @@ -0,0 +1,329 @@ +/** + * SQLite persistence for repositories, knowledge graphs, cached per-file + * analysis, sessions and settings. Uses the SQLite engine built into Node.js + * (`node:sqlite`), so no native module has to be compiled or downloaded. + */ +import fs from 'node:fs'; +import { createRequire } from 'node:module'; +import path from 'node:path'; +import type { DatabaseSync, StatementSync } from 'node:sqlite'; +import { type GraphEdge, type GraphNode, type KnowledgeGraph, type NodeType, SCHEMA_VERSION, computeStats } from '@vectora/graph-schema'; +import { type RepositoryRecord, type SessionState, type Settings, SettingsSchema, defaultSettings } from '@vectora/shared'; + +const DB_VERSION = 1; + +export interface StoredRepository extends RepositoryRecord { + /** Absolute path of the indexed source tree on this machine. */ + rootPath: string; + /** True when VECTORA owns the source copy (GitHub / ZIP imports) and may delete it. */ + managedSource: boolean; +} + +export interface CachedFacts { + path: string; + hash: string; + facts: T; +} + +function openDatabase(file: string): DatabaseSync { + // `node:sqlite` prints an ExperimentalWarning on first load; it is expected here. + const original = process.emitWarning; + process.emitWarning = ((warning: string | Error, ...rest: unknown[]) => { + const text = typeof warning === 'string' ? warning : warning.message; + if (/SQLite is an experimental feature/.test(text)) return; + return (original as (...a: unknown[]) => void).call(process, warning, ...rest); + }) as typeof process.emitWarning; + try { + const require = createRequire(import.meta.url); + const sqlite = require('node:sqlite') as typeof import('node:sqlite'); + return new sqlite.DatabaseSync(file); + } finally { + process.emitWarning = original; + } +} + +type Row = Record; + +export class Store { + private db: DatabaseSync; + private statements = new Map(); + + constructor(public readonly file: string) { + if (file !== ':memory:') fs.mkdirSync(path.dirname(file), { recursive: true }); + this.db = openDatabase(file); + this.db.exec('PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL; PRAGMA foreign_keys = ON;'); + this.migrate(); + } + + private migrate(): void { + this.db.exec(` + CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT NOT NULL); + CREATE TABLE IF NOT EXISTS repositories ( + id TEXT PRIMARY KEY, name TEXT NOT NULL, source_kind TEXT NOT NULL, origin TEXT NOT NULL, + branch TEXT, subdirectory TEXT, root_path TEXT NOT NULL, managed_source INTEGER NOT NULL DEFAULT 0, + status TEXT NOT NULL, created_at TEXT NOT NULL, last_indexed_at TEXT, + file_count INTEGER NOT NULL DEFAULT 0, symbol_count INTEGER NOT NULL DEFAULT 0, relationship_count INTEGER NOT NULL DEFAULT 0, + error TEXT, analysis TEXT + ); + CREATE TABLE IF NOT EXISTS nodes ( + repo_id TEXT NOT NULL, id TEXT NOT NULL, type TEXT NOT NULL, name TEXT NOT NULL, file_path TEXT, data TEXT NOT NULL, + PRIMARY KEY (repo_id, id) + ) WITHOUT ROWID; + CREATE INDEX IF NOT EXISTS nodes_type ON nodes (repo_id, type); + CREATE INDEX IF NOT EXISTS nodes_path ON nodes (repo_id, file_path); + CREATE TABLE IF NOT EXISTS edges ( + repo_id TEXT NOT NULL, id TEXT NOT NULL, source TEXT NOT NULL, target TEXT NOT NULL, type TEXT NOT NULL, data TEXT NOT NULL, + PRIMARY KEY (repo_id, id) + ) WITHOUT ROWID; + CREATE INDEX IF NOT EXISTS edges_source ON edges (repo_id, source); + CREATE INDEX IF NOT EXISTS edges_target ON edges (repo_id, target); + CREATE TABLE IF NOT EXISTS file_facts ( + repo_id TEXT NOT NULL, path TEXT NOT NULL, hash TEXT NOT NULL, facts TEXT NOT NULL, + PRIMARY KEY (repo_id, path) + ) WITHOUT ROWID; + CREATE TABLE IF NOT EXISTS sessions (repo_id TEXT PRIMARY KEY, data TEXT NOT NULL); + CREATE TABLE IF NOT EXISTS settings (id INTEGER PRIMARY KEY CHECK (id = 1), data TEXT NOT NULL); + CREATE TABLE IF NOT EXISTS credentials (name TEXT PRIMARY KEY, value TEXT NOT NULL, updated_at TEXT NOT NULL); + `); + const v = this.db.prepare('SELECT value FROM meta WHERE key = ?').get('db_version') as Row | undefined; + if (!v) this.db.prepare('INSERT INTO meta (key, value) VALUES (?, ?)').run('db_version', String(DB_VERSION)); + } + + private stmt(sql: string): StatementSync { + let s = this.statements.get(sql); + if (!s) { + s = this.db.prepare(sql); + this.statements.set(sql, s); + } + return s; + } + + private transaction(fn: () => T): T { + this.db.exec('BEGIN'); + try { + const r = fn(); + this.db.exec('COMMIT'); + return r; + } catch (err) { + this.db.exec('ROLLBACK'); + throw err; + } + } + + close(): void { + this.statements.clear(); + this.db.close(); + } + + // ---- repositories ------------------------------------------------------- + + private toRepo(r: Row): StoredRepository { + return { + id: r.id as string, + name: r.name as string, + sourceKind: r.source_kind as StoredRepository['sourceKind'], + origin: r.origin as string, + branch: (r.branch as string | null) ?? null, + subdirectory: (r.subdirectory as string | null) ?? null, + rootPath: r.root_path as string, + managedSource: !!r.managed_source, + status: r.status as StoredRepository['status'], + createdAt: r.created_at as string, + lastIndexedAt: (r.last_indexed_at as string | null) ?? null, + fileCount: Number(r.file_count), + symbolCount: Number(r.symbol_count), + relationshipCount: Number(r.relationship_count), + error: (r.error as string | null) ?? null, + }; + } + + listRepositories(): StoredRepository[] { + return (this.stmt('SELECT * FROM repositories ORDER BY created_at DESC').all() as Row[]).map((r) => this.toRepo(r)); + } + + getRepository(id: string): StoredRepository | null { + const r = this.stmt('SELECT * FROM repositories WHERE id = ?').get(id) as Row | undefined; + return r ? this.toRepo(r) : null; + } + + insertRepository(repo: StoredRepository): void { + this.stmt( + `INSERT INTO repositories (id, name, source_kind, origin, branch, subdirectory, root_path, managed_source, status, created_at, last_indexed_at, file_count, symbol_count, relationship_count, error) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + ).run( + repo.id, repo.name, repo.sourceKind, repo.origin, repo.branch, repo.subdirectory, repo.rootPath, repo.managedSource ? 1 : 0, repo.status, + repo.createdAt, repo.lastIndexedAt, repo.fileCount, repo.symbolCount, repo.relationshipCount, repo.error, + ); + } + + updateRepository(id: string, patch: Partial>): void { + const map: Record = { + status: 'status', lastIndexedAt: 'last_indexed_at', fileCount: 'file_count', symbolCount: 'symbol_count', + relationshipCount: 'relationship_count', error: 'error', name: 'name', branch: 'branch', + }; + const sets: string[] = []; + const values: (string | number | null)[] = []; + for (const [k, v] of Object.entries(patch)) { + if (v === undefined || !map[k]) continue; + sets.push(`${map[k]} = ?`); + values.push(v as string | number | null); + } + if (!sets.length) return; + this.db.prepare(`UPDATE repositories SET ${sets.join(', ')} WHERE id = ?`).run(...values, id); + } + + deleteRepository(id: string): void { + this.transaction(() => { + for (const t of ['nodes', 'edges', 'file_facts']) this.db.prepare(`DELETE FROM ${t} WHERE repo_id = ?`).run(id); + this.db.prepare('DELETE FROM sessions WHERE repo_id = ?').run(id); + this.db.prepare('DELETE FROM repositories WHERE id = ?').run(id); + }); + } + + getAnalysis(id: string): T | null { + const r = this.stmt('SELECT analysis FROM repositories WHERE id = ?').get(id) as Row | undefined; + return r?.analysis ? (JSON.parse(r.analysis as string) as T) : null; + } + + setAnalysis(id: string, analysis: unknown): void { + this.stmt('UPDATE repositories SET analysis = ? WHERE id = ?').run(JSON.stringify(analysis), id); + } + + // ---- graph -------------------------------------------------------------- + + saveGraph(repoId: string, graph: Pick): void { + this.transaction(() => { + this.stmt('DELETE FROM nodes WHERE repo_id = ?').run(repoId); + this.stmt('DELETE FROM edges WHERE repo_id = ?').run(repoId); + const insNode = this.stmt('INSERT INTO nodes (repo_id, id, type, name, file_path, data) VALUES (?, ?, ?, ?, ?, ?)'); + for (const n of graph.nodes) insNode.run(repoId, n.id, n.type, n.name, n.filePath, JSON.stringify(n)); + const insEdge = this.stmt('INSERT INTO edges (repo_id, id, source, target, type, data) VALUES (?, ?, ?, ?, ?, ?)'); + for (const e of graph.edges) insEdge.run(repoId, e.id, e.source, e.target, e.type, JSON.stringify(e)); + }); + } + + /** + * Loads a graph. With `types`, only nodes of those types are returned and + * edges are limited to those between returned nodes (progressive loading). + */ + loadGraph(repoId: string, opts: { types?: readonly NodeType[] } = {}): KnowledgeGraph { + let nodes: GraphNode[]; + if (opts.types?.length) { + const marks = opts.types.map(() => '?').join(','); + nodes = (this.db.prepare(`SELECT data FROM nodes WHERE repo_id = ? AND type IN (${marks})`).all(repoId, ...opts.types) as Row[]).map( + (r) => JSON.parse(r.data as string) as GraphNode, + ); + } else { + nodes = (this.stmt('SELECT data FROM nodes WHERE repo_id = ?').all(repoId) as Row[]).map((r) => JSON.parse(r.data as string) as GraphNode); + } + let edges = (this.stmt('SELECT data FROM edges WHERE repo_id = ?').all(repoId) as Row[]).map((r) => JSON.parse(r.data as string) as GraphEdge); + if (opts.types?.length) { + const ids = new Set(nodes.map((n) => n.id)); + edges = edges.filter((e) => ids.has(e.source) && ids.has(e.target)); + } + const analysis = this.getAnalysis<{ unresolvedCount?: number; generatedAt?: string }>(repoId); + return { + schemaVersion: SCHEMA_VERSION, + repositoryId: repoId, + generatedAt: analysis?.generatedAt ?? new Date().toISOString(), + nodes, + edges, + stats: computeStats(nodes, edges, analysis?.unresolvedCount ?? 0), + }; + } + + /** Nodes whose members were left out by a typed load, e.g. the symbols of one file. */ + loadNodesByFile(repoId: string, filePath: string): { nodes: GraphNode[]; edges: GraphEdge[] } { + const nodes = (this.stmt('SELECT data FROM nodes WHERE repo_id = ? AND file_path = ?').all(repoId, filePath) as Row[]).map( + (r) => JSON.parse(r.data as string) as GraphNode, + ); + const edges = new Map(); + const bySource = this.stmt('SELECT data FROM edges WHERE repo_id = ? AND source = ?'); + const byTarget = this.stmt('SELECT data FROM edges WHERE repo_id = ? AND target = ?'); + for (const n of nodes) { + for (const r of [...(bySource.all(repoId, n.id) as Row[]), ...(byTarget.all(repoId, n.id) as Row[])]) { + const e = JSON.parse(r.data as string) as GraphEdge; + edges.set(e.id, e); + } + } + return { nodes, edges: [...edges.values()] }; + } + + countGraph(repoId: string): { nodes: number; edges: number } { + const n = this.stmt('SELECT COUNT(*) AS c FROM nodes WHERE repo_id = ?').get(repoId) as Row; + const e = this.stmt('SELECT COUNT(*) AS c FROM edges WHERE repo_id = ?').get(repoId) as Row; + return { nodes: Number(n.c), edges: Number(e.c) }; + } + + // ---- cached per-file analysis ------------------------------------------ + + saveFacts(repoId: string, entries: CachedFacts[]): void { + this.transaction(() => { + this.stmt('DELETE FROM file_facts WHERE repo_id = ?').run(repoId); + const ins = this.stmt('INSERT INTO file_facts (repo_id, path, hash, facts) VALUES (?, ?, ?, ?)'); + for (const e of entries) ins.run(repoId, e.path, e.hash, JSON.stringify(e.facts)); + }); + } + + loadFacts(repoId: string): Map> { + const out = new Map>(); + for (const r of this.stmt('SELECT path, hash, facts FROM file_facts WHERE repo_id = ?').all(repoId) as Row[]) + out.set(r.path as string, { path: r.path as string, hash: r.hash as string, facts: JSON.parse(r.facts as string) as T }); + return out; + } + + clearFacts(repoId?: string): void { + if (repoId) this.stmt('DELETE FROM file_facts WHERE repo_id = ?').run(repoId); + else this.db.exec('DELETE FROM file_facts'); + } + + // ---- sessions, settings, credentials ----------------------------------- + + getSession(repoId: string): SessionState | null { + const r = this.stmt('SELECT data FROM sessions WHERE repo_id = ?').get(repoId) as Row | undefined; + return r ? (JSON.parse(r.data as string) as SessionState) : null; + } + + saveSession(repoId: string, session: SessionState): void { + this.stmt('INSERT INTO sessions (repo_id, data) VALUES (?, ?) ON CONFLICT(repo_id) DO UPDATE SET data = excluded.data').run(repoId, JSON.stringify(session)); + } + + getSettings(): Settings { + const r = this.stmt('SELECT data FROM settings WHERE id = 1').get() as Row | undefined; + if (!r) return defaultSettings(); + const parsed = SettingsSchema.safeParse(JSON.parse(r.data as string)); + return parsed.success ? parsed.data : defaultSettings(); + } + + saveSettings(settings: Settings): void { + this.stmt('INSERT INTO settings (id, data) VALUES (1, ?) ON CONFLICT(id) DO UPDATE SET data = excluded.data').run(JSON.stringify(settings)); + } + + getCredential(name: string): string | null { + const r = this.stmt('SELECT value FROM credentials WHERE name = ?').get(name) as Row | undefined; + return r ? (r.value as string) : null; + } + + setCredential(name: string, encryptedValue: string): void { + this.stmt('INSERT INTO credentials (name, value, updated_at) VALUES (?, ?, ?) ON CONFLICT(name) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at').run( + name, encryptedValue, new Date().toISOString(), + ); + } + + deleteCredential(name: string): void { + this.stmt('DELETE FROM credentials WHERE name = ?').run(name); + } + + listCredentials(): { name: string; updatedAt: string }[] { + return (this.stmt('SELECT name, updated_at FROM credentials ORDER BY name').all() as Row[]).map((r) => ({ name: r.name as string, updatedAt: r.updated_at as string })); + } + + /** Removes every repository, graph, cache, session and credential. Settings are kept unless asked. */ + deleteAllData(includeSettings = false): void { + this.transaction(() => { + for (const t of ['nodes', 'edges', 'file_facts', 'sessions', 'repositories', 'credentials']) this.db.exec(`DELETE FROM ${t}`); + if (includeSettings) this.db.exec('DELETE FROM settings'); + }); + this.db.exec('VACUUM'); + } +} diff --git a/packages/graph-layout/package.json b/packages/graph-layout/package.json new file mode 100644 index 0000000..69a9bd1 --- /dev/null +++ b/packages/graph-layout/package.json @@ -0,0 +1,9 @@ +{ + "name": "@vectora/graph-layout", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MIT", + "exports": { ".": "./src/index.ts" }, + "dependencies": { "@vectora/graph-schema": "*", "d3-force-3d": "^3.0.6" } +} diff --git a/packages/graph-schema/package.json b/packages/graph-schema/package.json new file mode 100644 index 0000000..7ec2ece --- /dev/null +++ b/packages/graph-schema/package.json @@ -0,0 +1,9 @@ +{ + "name": "@vectora/graph-schema", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MIT", + "exports": { ".": "./src/index.ts" }, + "dependencies": { "zod": "^4.6.7" } +} diff --git a/packages/graph-schema/src/index.ts b/packages/graph-schema/src/index.ts new file mode 100644 index 0000000..b8a9f93 --- /dev/null +++ b/packages/graph-schema/src/index.ts @@ -0,0 +1,408 @@ +/** + * VECTORA knowledge graph schema. + * + * Every node and edge carries the evidence it was derived from: where in the + * source it was found, which extraction method produced it, and how confident + * the extractor is. Structural facts (`verified: true`) are kept apart from + * derived interpretations (`verified: false`). + */ +import { z } from 'zod'; + +export const SCHEMA_VERSION = 1; + +export const NODE_TYPES = [ + 'Repository', + 'Directory', + 'File', + 'Package', + 'Module', + 'Class', + 'Function', + 'Method', + 'Interface', + 'Type', + 'Variable', + 'Constant', + 'ApiEndpoint', + 'DatabaseModel', + 'Component', + 'Concept', + 'Subsystem', + 'Configuration', +] as const; +export type NodeType = (typeof NODE_TYPES)[number]; + +export const EDGE_TYPES = [ + 'CONTAINS', + 'IMPORTS', + 'EXPORTS', + 'CALLS', + 'EXTENDS', + 'IMPLEMENTS', + 'USES', + 'INSTANTIATES', + 'DEPENDS_ON', + 'READS_FROM', + 'WRITES_TO', + 'ROUTES_TO', + 'DEFINED_IN', + 'BELONGS_TO', + 'RELATED_TO', +] as const; +export type EdgeType = (typeof EDGE_TYPES)[number]; + +/** How a fact was obtained. Ordered roughly from most to least precise. */ +export const EXTRACTION_METHODS = [ + 'filesystem', // directory / file structure + 'manifest', // package manifests (package.json, pyproject.toml, go.mod, ...) + 'typescript-compiler', // TypeScript Compiler API, syntax level + 'typescript-checker', // TypeScript Compiler API, type-checker symbol resolution + 'python-ast', // Python `ast` module + 'tree-sitter', // Tree-sitter syntax tree + 'scope-resolution', // name resolved through imports / same-file scope + 'name-resolution', // unique-name resolution limited to imported or same-package files + 'pattern', // framework pattern (routes, models, components) + 'structural-grouping', // subsystem grouping from repository layout + 'keyword-evidence', // concept grouping from identifiers and paths + 'aggregation', // derived by aggregating other edges +] as const; +export type ExtractionMethod = (typeof EXTRACTION_METHODS)[number]; + +/** Node types that represent a source-code symbol. */ +export const SYMBOL_TYPES: readonly NodeType[] = [ + 'Class', + 'Function', + 'Method', + 'Interface', + 'Type', + 'Variable', + 'Constant', + 'ApiEndpoint', + 'DatabaseModel', + 'Component', +]; +/** Node types that form the structural skeleton of a repository. */ +export const STRUCTURAL_TYPES: readonly NodeType[] = [ + 'Repository', + 'Subsystem', + 'Module', + 'Directory', + 'File', + 'Package', + 'Concept', + 'Configuration', +]; + +export const isSymbolType = (t: NodeType): boolean => SYMBOL_TYPES.includes(t); + +export const SourceLocationSchema = z.object({ + path: z.string(), + startLine: z.number().int().min(1), + endLine: z.number().int().min(1), + startColumn: z.number().int().min(0).optional(), + endColumn: z.number().int().min(0).optional(), +}); +export type SourceLocation = z.infer; + +export const GraphNodeSchema = z.object({ + id: z.string().min(1), + name: z.string(), + type: z.enum(NODE_TYPES), + repositoryId: z.string().min(1), + filePath: z.string().nullable(), + location: SourceLocationSchema.nullable(), + description: z.string().optional(), + language: z.string().nullable(), + metadata: z.record(z.string(), z.unknown()), + extractionMethod: z.enum(EXTRACTION_METHODS), + confidence: z.number().min(0).max(1), + verified: z.boolean(), +}); +export type GraphNode = z.infer; + +export const GraphEdgeSchema = z.object({ + id: z.string().min(1), + source: z.string().min(1), + target: z.string().min(1), + type: z.enum(EDGE_TYPES), + /** Source text or statement that justifies this relationship. */ + evidence: z.string(), + location: SourceLocationSchema.nullable(), + extractionMethod: z.enum(EXTRACTION_METHODS), + confidence: z.number().min(0).max(1), + verified: z.boolean(), + metadata: z.record(z.string(), z.unknown()).optional(), +}); +export type GraphEdge = z.infer; + +/** A reference the indexer found but could not tie to a definition. */ +export interface UnresolvedReference { + fromPath: string; + fromSymbol: string | null; + kind: EdgeType; + name: string; + line: number; + reason: string; +} + +export interface LanguageCoverage { + language: string; + tier: 1 | 2 | 0; + files: number; + analyzedFiles: number; + symbols: number; + parseErrors: number; + adapter: string | null; +} + +export interface GraphStats { + nodeCount: number; + edgeCount: number; + symbolCount: number; + fileCount: number; + nodesByType: Partial>; + edgesByType: Partial>; + unresolvedCount: number; + verifiedEdges: number; + unverifiedEdges: number; +} + +export interface KnowledgeGraph { + schemaVersion: number; + repositoryId: string; + generatedAt: string; + nodes: GraphNode[]; + edges: GraphEdge[]; + stats: GraphStats; +} + +export const KnowledgeGraphSchema = z.object({ + schemaVersion: z.number().int(), + repositoryId: z.string(), + generatedAt: z.string(), + nodes: z.array(GraphNodeSchema), + edges: z.array(GraphEdgeSchema), +}); + +// --------------------------------------------------------------------------- +// Identifier helpers. IDs are deterministic so that re-indexing an unchanged +// repository yields the same graph and exports stay comparable. +// --------------------------------------------------------------------------- + +export const normalizePath = (p: string): string => + p + .replace(/\\/g, '/') + .replace(/^\.\//, '') + .replace(/\/+/g, '/') + .replace(/\/$/, ''); + +export const nodeId = { + repository: (): string => 'repo:root', + directory: (path: string): string => `dir:${normalizePath(path)}`, + file: (path: string): string => `file:${normalizePath(path)}`, + symbol: (path: string, localId: string): string => `sym:${normalizePath(path)}#${localId}`, + pkg: (name: string): string => `pkg:${name}`, + module: (path: string): string => `mod:${normalizePath(path)}`, + subsystem: (key: string): string => `sub:${key}`, + concept: (key: string): string => `concept:${key}`, + config: (path: string): string => `cfg:${normalizePath(path)}`, +}; + +export const edgeId = (type: EdgeType, source: string, target: string): string => `${type}|${source}|${target}`; + +// --------------------------------------------------------------------------- +// Validation and normalization +// --------------------------------------------------------------------------- + +export interface ValidationIssue { + severity: 'error' | 'warning'; + code: + | 'duplicate-node' + | 'duplicate-edge' + | 'dangling-edge' + | 'self-loop' + | 'invalid-node' + | 'invalid-edge' + | 'missing-evidence' + | 'orphan-node'; + message: string; + id?: string; +} + +export interface ValidationResult { + valid: boolean; + issues: ValidationIssue[]; + errorCount: number; + warningCount: number; +} + +/** Edge types where a node pointing at itself is meaningful (recursion). */ +const SELF_LOOP_ALLOWED: ReadonlySet = new Set(['CALLS', 'USES']); + +/** + * Checks graph integrity: schema conformance, unique IDs, no dangling edges, + * evidence present on every non-structural edge. + */ +export function validateGraph( + graph: Pick, + opts: { checkSchema?: boolean; maxIssues?: number } = {}, +): ValidationResult { + const issues: ValidationIssue[] = []; + const max = opts.maxIssues ?? 500; + const push = (i: ValidationIssue) => { + if (issues.length < max) issues.push(i); + }; + const ids = new Set(); + for (const n of graph.nodes) { + if (ids.has(n.id)) push({ severity: 'error', code: 'duplicate-node', message: `Duplicate node id ${n.id}`, id: n.id }); + ids.add(n.id); + if (opts.checkSchema) { + const r = GraphNodeSchema.safeParse(n); + if (!r.success) + push({ severity: 'error', code: 'invalid-node', message: `${n.id}: ${r.error.issues[0]?.message ?? 'invalid'}`, id: n.id }); + } + } + const edgeIds = new Set(); + const connected = new Set(); + for (const e of graph.edges) { + if (edgeIds.has(e.id)) push({ severity: 'error', code: 'duplicate-edge', message: `Duplicate edge id ${e.id}`, id: e.id }); + edgeIds.add(e.id); + if (!ids.has(e.source) || !ids.has(e.target)) { + push({ + severity: 'error', + code: 'dangling-edge', + message: `Edge ${e.id} references a missing node`, + id: e.id, + }); + continue; + } + connected.add(e.source); + connected.add(e.target); + if (e.source === e.target && !SELF_LOOP_ALLOWED.has(e.type)) + push({ severity: 'warning', code: 'self-loop', message: `Self-referencing ${e.type} edge on ${e.source}`, id: e.id }); + if (!e.evidence) push({ severity: 'warning', code: 'missing-evidence', message: `Edge ${e.id} has no evidence`, id: e.id }); + if (opts.checkSchema) { + const r = GraphEdgeSchema.safeParse(e); + if (!r.success) + push({ severity: 'error', code: 'invalid-edge', message: `${e.id}: ${r.error.issues[0]?.message ?? 'invalid'}`, id: e.id }); + } + } + for (const n of graph.nodes) { + if (!connected.has(n.id) && n.type !== 'Repository') + push({ severity: 'warning', code: 'orphan-node', message: `Node ${n.id} has no relationships`, id: n.id }); + } + const errorCount = issues.filter((i) => i.severity === 'error').length; + return { valid: errorCount === 0, issues, errorCount, warningCount: issues.length - errorCount }; +} + +/** + * Removes duplicate nodes (first wins), merges duplicate edges (keeping the + * first evidence and counting occurrences) and drops edges whose endpoints do + * not exist. Returns what was changed so callers can report it. + */ +export function normalizeGraph( + nodes: GraphNode[], + edges: GraphEdge[], +): { nodes: GraphNode[]; edges: GraphEdge[]; removedNodes: number; mergedEdges: number; droppedEdges: number } { + const nodeMap = new Map(); + let removedNodes = 0; + for (const n of nodes) { + if (nodeMap.has(n.id)) removedNodes++; + else nodeMap.set(n.id, { ...n, filePath: n.filePath ? normalizePath(n.filePath) : n.filePath }); + } + const edgeMap = new Map(); + let mergedEdges = 0; + let droppedEdges = 0; + for (const e of edges) { + if (!nodeMap.has(e.source) || !nodeMap.has(e.target)) { + droppedEdges++; + continue; + } + const existing = edgeMap.get(e.id); + if (existing) { + mergedEdges++; + const meta = (existing.metadata ??= {}); + meta.occurrences = ((meta.occurrences as number | undefined) ?? 1) + 1; + const lines = (meta.lines as number[] | undefined) ?? (existing.location ? [existing.location.startLine] : []); + if (e.location && lines.length < 20 && !lines.includes(e.location.startLine)) lines.push(e.location.startLine); + meta.lines = lines; + // Keep the strongest claim when the same relationship is found twice. + if (e.confidence > existing.confidence) { + existing.confidence = e.confidence; + existing.extractionMethod = e.extractionMethod; + existing.verified = e.verified; + } + } else { + edgeMap.set(e.id, { ...e, metadata: e.metadata ? { ...e.metadata } : undefined }); + } + } + return { nodes: [...nodeMap.values()], edges: [...edgeMap.values()], removedNodes, mergedEdges, droppedEdges }; +} + +export function computeStats(nodes: GraphNode[], edges: GraphEdge[], unresolvedCount = 0): GraphStats { + const nodesByType: Partial> = {}; + const edgesByType: Partial> = {}; + let symbolCount = 0; + let fileCount = 0; + for (const n of nodes) { + nodesByType[n.type] = (nodesByType[n.type] ?? 0) + 1; + if (isSymbolType(n.type)) symbolCount++; + if (n.type === 'File') fileCount++; + } + let verifiedEdges = 0; + for (const e of edges) { + edgesByType[e.type] = (edgesByType[e.type] ?? 0) + 1; + if (e.verified) verifiedEdges++; + } + return { + nodeCount: nodes.length, + edgeCount: edges.length, + symbolCount, + fileCount, + nodesByType, + edgesByType, + unresolvedCount, + verifiedEdges, + unverifiedEdges: edges.length - verifiedEdges, + }; +} + +/** Human-readable labels used across the interface and exports. */ +export const NODE_TYPE_LABELS: Record = { + Repository: 'Repository', + Directory: 'Directory', + File: 'File', + Package: 'Package', + Module: 'Module', + Class: 'Class', + Function: 'Function', + Method: 'Method', + Interface: 'Interface', + Type: 'Type', + Variable: 'Variable', + Constant: 'Constant', + ApiEndpoint: 'API endpoint', + DatabaseModel: 'Database model', + Component: 'Component', + Concept: 'Concept', + Subsystem: 'Subsystem', + Configuration: 'Configuration', +}; + +export const EDGE_TYPE_LABELS: Record = { + CONTAINS: 'contains', + IMPORTS: 'imports', + EXPORTS: 'exports', + CALLS: 'calls', + EXTENDS: 'extends', + IMPLEMENTS: 'implements', + USES: 'uses', + INSTANTIATES: 'instantiates', + DEPENDS_ON: 'depends on', + READS_FROM: 'reads from', + WRITES_TO: 'writes to', + ROUTES_TO: 'routes to', + DEFINED_IN: 'defined in', + BELONGS_TO: 'belongs to', + RELATED_TO: 'related to', +}; diff --git a/packages/language-adapters/grammars/tree-sitter-c.wasm b/packages/language-adapters/grammars/tree-sitter-c.wasm new file mode 100644 index 0000000000000000000000000000000000000000..9d4afad2c723b98d60ce6a0ebcb763ceaee1535c GIT binary patch literal 625918 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%0DOf+NEkt`T(n#U*>d~50$>kDQ{9TQma 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 Hy3P21{kCz% literal 0 HcmV?d00001 diff --git a/packages/language-adapters/grammars/tree-sitter-c_sharp.wasm b/packages/language-adapters/grammars/tree-sitter-c_sharp.wasm new file mode 100644 index 0000000000000000000000000000000000000000..bddfd5c8ebcece55153403111518d4d0a97e7837 GIT binary patch literal 5350581 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
YXe`Z``SmXPF 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

S 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

~WE#*A4781|CJbbiaQ7;0E6zf~7j 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%0ASX&TknOLlJA`_ZjHV-i-Q@)EJBQd%BZ)M)=Ou z^*SAR!OYt_QQPC}o97Y4`zK^k78@7wQaU&R1Bas!vJfA12oH=IvkEZmC5`F)mSHi} zuvUJnF09-`Ufv;6L^MmSo)J-(s;|_6e>n42V(w=DQRZi##E)9YqKq~!;-z%n0tOC8 zA!H#wuS0lX%$QYxVJ~S+=eG=tp@y~cTXkXO9`f=Iks_j5YW0kWx>S9o4qP$wR$}gE ze_@_S5HC*1qKq~!;-z%%2^csWg^-2#+z#P^F=JK%hP|XQo!>Gnh8ot&Z`FmBd&tW> zM2d)Jsns(g>QeQUI`EHX-b&2f?4NI*M-ZRCkVP47T*T}CBE|v+4o4wmA%0AU@W7Zc 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­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 iO3iAQmJBZ`Eg3tsqbsZPPZb?buFZ;v|mk z=Fz5~1qcuzK!CuqkwJg}0Wt^>AV3%a0t5&UAV7cs0RjXF5FkLj%y;%ad(X_-bH^H8 zQ~FQ7{Jt8kv-UY_t#i)Yx%bYUNqgp%Us`GE|9znQbANd8gAZ&jNlSY=P5tGnzf==|Y4$3shx7ceetW~S&%F5J zub)kG@Q+_U|I1gNe>Kg8Kf1s0%I{uz>6vGrPqVn~*_ZyH+j>6r)HAQV^8CxMKJ~L_ zUU)I>Mj*I9d-?h2)6(Fdw?6gME3ZED>@S{r>DMp(>ec68c3#6SRFxXw*DwF!sh>Xc z%Ja@^$W4FhsaK!*>5If9~A=)KkAxQ9T95o_hAxU%&iH+6{LS_RLE!z4(Wxo_pri zXP$cbd1d>Rv>R`IRmpzpl^0%BI-h#>rI*rr-qh1dyVve<<1M#!PrvEr9yh;n@x~rb zn$=_J53O5YyVpt-wA5I=)qm?|-QW9BJ5Bwokda3TC?cS3#=V3T6OwhZ$|9(Qp(Col zUTM0kQU)(7P(x(|6`i_|ka9xuIvA;7r2i*~Q%OkM2u7+1DSMNVYC`I=yuoT1@<_Fa z*jh`S{v*NK8i-z9@+lg(k&s#sX`&jN7|ryzLw~o>-!A>#N`H5wzuV~V8|d$L{9EO( zN63U3D7wFQuN$<)Y={%4=~m+B5HOP^<`OXdv&6_FVBRMQ$S0uoOWwp35H$Zw#3>|T z2?Iq0tYx5>fPVK-NeKaKc%76Ia4M4+Wdu}lNjU){7^ooN1W$b>0mrzHDgvf)Ni_ij z8K@!P-H+3-wFFG;ML-<@nY1SBsde_JskMQC)$F5D19}3QsC6;t&`dxT11((7Kq~>| z473rjhksU=`P19b$P`nBV5M2d^a@$dKsEt4Qbi8^%?GYr`g<`K zq;W>gWdnU_>G0UKCa4FT(=%qStC zfQKz5Am>x0w2Xku9AP;D3wjcxf`HMSdL;pSdDtof)_cbf0?u=%H3V>iwe#M0XrDTBVgPuG?n=ToM%P>0Zj}P5^#Wl zA_6WlP)xu|K6xu4U>C2#QUZ2*M-Kv~@ideZP{aGSf`E2DBvle{j1#LOpp6d>)dZa3 zVQUCD&8x7MfEl0Y-K!hD{~)NAbFU|0C2MUUU@;#H8wps#FG)=VTxIdi0Px9f3$;$W zxp%MbdeByadeAJi(cf*{K|29&aK;@3Wb+QYOu$KAw^=9k@;J|ZWE1c@Gja%c)9Kyo zCM_hFprdJ|B#!}hpHIMWo~Z%?PT5paNI)saUPQo1KJXV4ki$w!2+952MzcKbp= zy>8a&v=KB`eVEfjL+u2Wsls#(br5vy4sVJs6I6YtH$_>ew9Ko#C$kAS$mgOt1oZDt zMsf+5&p;lRFpy8cppQ^V0RdA!KtLe@hxnjWL_pS^#3&}~ENBk?(L&_>9^O!`!S*(4-_K&(2^hja2LWY%50`^IWStHu&xSwL8lKA4 zIRvayFInU+H&~Dt{3D;pOE{?Spp=1p0=$C+{k?+;g#_etpG5?0W1yIT zMO;!sz$JdcEG1y#y_8NF0mB(6Ctx{uT0uY#Pi-XubNN)KihwpgwpSA{_M37Eq` z8v(o7MLPlec$5wRGH=%UFH>tH>(6S}i((#c#cTqm@FvM2UsaBcFg4 z-kSvkTw$P)fYq#{2!Kp_AuOiW@ocJufU8U|MLM4}Q0r3ey_|r>{I0ixfOCAnt|VXx zGpY!f!ay|vuk%@K4FRKh0o4*v!i+is#`6hQJpm^^M60ENfGvC!YXl&Z-mNqR|7a%a z*bJ&|Az&x3=vD&O@bRsUfUTdTl6C^}dAJS&c5umM0?K(KWu4XQA^$$=Bb$KoPY{qp zz!*M8<`PiHKpq1;ANkw|9}o)&n883H0RtH*B497uFD9Uhff52Xa!Dxx`+1Vf2{(dAyfgtr?J)4x}MLHYJ#n`_y?b267{NjLq-d=K1gl|k{gLU zg=23bppt=R0uJ*`wGc3aV{av(j3>7Z0DgUF5B|{+{Npm!UE~vltaEw|R5OrGz-m57 z)b+{*Me0><*`L^}aPnbCpuv`{Zo z>m}|z>%3kP#eA&GCg38^UJe1de2C5^U^%}KwwR{G$l}pi{D9_(Q$FImN0<2w1>twUmGf57C5|5pb1(astLbLW~Lm+Ia(35>W8~ zF{%hS$|cnVyvd9j0)~E(N@@w1{{;f-2&m;g>IqoH!WszJ%RnOmN4SqB0@@y?PMZms z#Xt)IV;E>9py~5e(ni24mflXlK$hM?z!c8oG692GSk?tS4V7GyO~3>Oav1m=4Vz2A zN(S->Si+;^6R?wk0sB7hPS{xugbwOu7cCmRd*fM~HO<^yLog2{_0;8VDH8 z)*A_^V4#VBlz(GEgwi7V!gJi6OfH9osWdbhp;W+D( zUI}&lB9sk4CVg3wL#d#Sg{Q zdYb7a1gvMElz;;EP)0!8J-j9e$mdm4!2oAjNx($*QANNg?zEbK96s%+Az%+Kk{&mu zC9Fhs+HGk)-f=AZwM_fLH0vJ6e!_kN{;3+j<35q;B&^@`v@@+l+E*<%Gfm+NOiQ@E z?{N}o_t?%8nb!SwTBeg}C+t^ytABpCrweR=yWg%_Y;|#7FB>cWvS(TkRh#yBnkq=7 zC92YHv+hc_0fYV=H8S*>X+iOww_9mFv75ABZlW>mJL(VjHe3B)5CJSTm}q?^m`oCl4QTmfrQPP-m6@j6GVO%( z8#JQ+W&akkvB{RIu@$Yytv&9wdZi`$JgUkQeLmAWkprEby{GqWZd#8URNl9B>v1z& z)!24et@0jA7j?6&*X~VAA$9P*WmLB` z%XZvuH{94={a7Hq=PkG1cKZiDc*ln_K78j#?)vE6AN#Y9XWrB6-upiB$xq$?>Cb%j zfd@bL(8Hhq!WSR;(xYE~>?@Cd^=n`M#y6ix{P|ye>)YS??vsD{y}$bYU;p55e)zY4 z_xC^ghkyL1AOG{e{OeEt?cbkz`k9|T``q(C`;VW$(EArJ{_kaEoYphjhy=9HF##=?!1Z$!-$tt!cTT`s5R*5yunr_XoO0Bo8nbs_;%$jY@ zvF2Lk);w#zwZN*d7Fvs}#a5-Y#CpeCYE@awtmW1UtJ+#=t+G~IHP#wyt+mdowbol3 ztc_NkwaMCSZL#XDt=2YcyVYRruy$IztVV0Mwa40PHCg+t{ni1i**a()vJP7<))DKd zb?O8|;mCoxRE4Y;Upa?XC7Ud%N9W@342; zyX;1Lx4p;SYd6{Z?EUruyV*WyAF>bIE%p)nsC~?CwU65;?2~qzeab#3(`(690o#pg#`a1obY^T37z!~V|ID?$Q&JZWp8R`skhC6xA2xp`- z%E@;|J7b*JodV|#=S^pYc65HfOuj;OuaAI=h@kXScJ*+3Pep`<(sG0jJqH=p1qm zJ1x!;=csecX?2b}C!CW`n{&!J?VNGiowLq4=e*P5TyQQrmz>Ma73W>&s*~mRar?Uc z+-$eMJHQ?2=D360!R`<@*B$B(bBDWm?g)3JJIc*>N4sO(*WCj54fjoVtXt^5<&Ja5 zyG8Bx{KV! zZl$}#eaBtuR=LaEX}Zkv0`J?)-x z+ugJ7IrqHV;a+erx|iI`?iKf4_o|!KtxvbU-THOQ?$*ECfNlf3<#Zd=ZE&|C-EzAP z?KZ62@NRkCMsyq5ZA>?HI{ctIzfU`8rY_j3xF?|%^33Wc$fhXK>M%ZDi)BnFg zlKLX6-A=a@1z}5_=&JM5y7B6~wD&_+8o-zFY+Rj_-fQ(vY=#!qK6jak6F2KOK0NpYJo!!^3Hg~NqXBx4k`Z2ePqRziqu;zWO}E!-pMJwxYN!r0m>TlE zF@)^tdXT)ZY+MP+WK+p-uS+3Y2kbWs*?xnNjSZ%3Of#8=Xnl*?xnNjSZ%3Of#A6QY||-EZa{-$flAZQL=AD*?zN-?KcS7*kH=WG?U4mp=A#a z%l1Ow%;sd`wc=iHkh(8&1ACQ*0OWLvi($qY$_QTCA$a8_M3%lzd^{x z22(bsnN0RfEqg#%wx5cSO(p%KWcNhbezTD6Hwf9-V9LfclgTdDva`do{Zxc(D(M#` z`&N|gHw)Q*gOH64rff_zne540cHgjUKNTUHO8P{}z8z)z%|f={AY@~MDI3#FCc9P3 z&I-%+QxUSM?$q$UC>~b_^AllRB|Os_J>fm z-z;SN4MH|Hm>Mw6WU`NI*_Xqz{Zxc(D!CLT`@<;PZx*us1|b_8Oxc)bGTBqL?2BR9 zekwvXm0XCD{SlPyHw)Q*gOH64rff_zne2sHc1KvYpNf!8CFi4Le-vf=%|f={AY@~M zDI3#FCVQTieJ(89PesV4lCx2=KZdgXW+B^e5VEnsl#OX7lf6vKZV$`$QxUSMYAsZV^*_dWB*?Y9? zwyEZa{-$flBmQL-OI*?zN-?KcS7*kH=WG?U5Rq-8gUW&5cJ*;H~MO7=r2+iw=K z{RSZ$8%)`lW-{43wCw$1*?uZQHkIs)lKpv@TBizgfuk8-#3ZFlA$!$z<=6=oRI(#V_E%80 z-z;SN4MH|Hn6fd=WU|+2*$rXYekwvXm28ia{Z*9hHw)Q*gOH64rff_zne1a)_O`HW zKNTUHO14JH{yNI`n}uw@LCD4iQ#PiVO!f&ayFM)2PesV4k}XlPzlpN_W+B^e5VEns zl#OX7lf6L8-W-0YUI`|U!v-yn2jgQ*+yOs2a= z>#hy!_G1ycsbpQ0?$uhi-!63f4MI0In7T2~WV#P&-D|_T{aA!c%{i={~7-uL|q-V-dQk zWM!1@^;);zE_C}1LN_*;x-rjWx=Xa~>acD<7NMI;Rz&IEsCE18Lbu-_bYp|58}m%2 zyFu$-9@g#0B6L&9vMAk~v~Is$==K|gZfr1hW1h)$*J<5VVcmW#LN}ExjnchE>-O7) zZofh3#s*V2=9x_QcCGuJux>vVp_@vUMCsnDb^Gl?x8ERiV}q$1^Gv4uwANi2*6qh4 zbW_RVDBat&ZoggV_8Ww5Y%q0Wp2>9Y*18vkb^Eah-BhwLO7{+}+iw@T{RW{M8%*7p zXENQVwC;+qZa)^Gn@Sc$>E5Mv`|U!v-yn2jgQ*+yOs2a->z*Ih?Z+Z?Q^~w2-Mh7J zzg_6|8-#9bFm+>|$#l=sy3515{aA!|$#fslx~F;~dg%>1SYJNp;}2ZsR{+*JB|TvyuPs|}bt z6#z|h{<1gCO^Pt**HkZ zvR&gS@4{jAqv*G*msbZ+|bm%r&}g6GH7?c=6yACJ(j2+4K7*Okkp8#_03`zznn zUF7LD7mbgzK3e&zq3gP6<$Ik57Y%}@SZ{I3i=)Zkco1!t`0IfD@iL&2ah^|cBGj&z z3AUSE`covjoTyjFTVWNRK`ER{3Zqn<(<=OSezBlywEYHtv7l?TvBA`h=_EU{Ptm%^ zhIRYt2&+``W|Zy@t=n%Gy8Q;B8yigBm}fHGYqjn-!n*xfgl;M+h|+yg>-O7)Zofh3 z#s*V2=9x_QO0E0#ux>vVp_@v^MCrb)b^Gl?x8ERiV}q$1^Gv4ufYv=atlN)8=%$kV zDBbUB-F~~!?KcSB*kJ0$Jd^3(sCADD>-J+2x~XJjlOn??b^Eah-BgknrMs{0(r*{K{RW{M8%*7pXENPQdXV8^-F_@WH0oZa)^Gn@Vz{bPv#7`t3ru-yn2jgQ*+yOs0FA9%M*Zw;zkp zO(lb)bm!BmM+mA))rjnc}-GgVCu#^ zlj+{22N@XF?Z+Z?Q^|lR-MP9;zg_6|8-#9bFm+>|$#ieggY*yU_G1ycsU$l}_b}b1 z-!63f4MI0In7T2~WV$EmLHdPt`>_b!RMIy}cb@LjZx_1#2B8}pOx>7gGTrO+AbrBR z{aA!8t*MnRM>-J+2x~b%Hl7K>On4rb^Eah z-BfZhN_T3&mp>9-5reuL1B4W@3) zGnwucdXV#B-F_@WHRxZa)^Gn@ZZFbdS?r z`t3ru-yn2jgQ*+yMBTLcujtR`&Ul0KM+WCb1HSFQ901LZF(df4sMY(nsMY_?xVq=F z_jQqi>Fc7VeNkT*?T41+Ul*xz_`0Yy{B=?H^Xg6j{{PZWJ1KnHF+qoowRD(_{QbBh zb^iNtMUtO);NpO+TD+`U{H)Y1FTJc3Oj%V$ezmqd`l~fn4q3H?v+8k9-8Vu0FYQz+ ziP6U+Sld}*iqv^xiX;=ml?;hBdx{`)}*M_)fZZluP#*%i8Y54yXCC9 z*F^IFrM0D!8=d}OZD+YDQs=oTlFSXaHRRUh<gi4ncLZ`%Ft4=YsN9xAOY+=Q zIpo$9&h7Sgb(fC!`d`|~RMMlL4P$L*=_yj@=_!&-54SF)*XX6!XeTyPdLIs?r(jC2 zZE{q4r=cZzda4}KYt-q19d#EB=Q}-*;|<%$Ud$U{Ox6dm6A)@=!6;Ja!6=dp26rd~ z)8GZu;0JS8AQ%NxFhx_Nf|&>{$%9el5KMy%rZt6N=;P4iae`5#&Vx}T84PYg2&Uc( zrru6`Oqa8CsHCR^?#1PFg;if@QiG^H?0qiX<)LjsVNGp5n78$cITR-tMd~~lMUuhb?t)+{ykIK)bB`|sf>AIZV`fDK zGZ9*n2cya%m#xNX34sb{&=PCTxc!dC;970Q<9L|TTH8_oZN&e!IIrj%7uXmT^OXpe1>1svKe~ma*+kAvXH{yeW=nMUtLzzkuf=&vTLIxjN`s!R&cn zq-SVJ?pc+C=OXEOPwJlczW=47y6AkVD3Xi~_Z-Al=*3oOCmz+ul-0r56wI;BkBkjk zlEe(`&Xb;ZrtW!H%~&)cu<;X!rR`Qbs4WQ4eTAi~R* z!{@pdFPpu=2rsKA0O?zbH$_IcKRQBH4iR3q@Rs8KS1DUlh>$KE+!n{PB1zAYle=+hwD=>wMWLl8g{HBShHlMc8if z5%yp(LIv~D=AEbrCqhf|2vs>m*e)a7l0t-Zi^=*po)t-Y#@z#++dR*0R$@7Q^4AhH zt#C4(w=~N1NN7oJT9t$8Hfefu3a04}y<6g#RwQW}w-1e(`Zk3)lrQn%vfx0=4XGM~palM1*7SD5wx42IPJu8^!d0CX_kIOEJS&p)jO!gdH+!C&JSFP15v+6im}SP&dXgtw_=| zu6Hoq=$UTxCi;BPvx0e|t0N~GT9Qw+DhJPv()0QhJku|DHpKC)NYXQ|cktZcd2X=y zt@Fj8X9e>-M|wUT?OBzB=LYGyHU-agwf_3Z7yQ^CLaHu0f00)t85?dHh^^j>t=^06 zN-#DBzn|DtImA{kV_TPcY_)MbE0Xk#I|e-0d7kS$&skRBgI5KU=em_q+ha4dB;OvY z96Z-a&udfgT%(Wu>*9D;BKlTp@npQZOE?OOBdLpzWH?7LSbd5A!lY(jb1?HMK zrWHw=#`O-St3A`z-m!mB(6fShqHCf&&w-ZYo>e(`u9luxr{I}>)ln12vm!~)xZc5Y zmFKz2+t9f|&kE*wUK8bcBD5s;tjfW2mGrzS1<&-$iq-G`*sr?i{MfHZGB(^Y5L=}e zTcsD<@L+5Tem}9Pa)_-`#mLxk7rbPQmjAee7Qu$Fm|y&$wg2bGhfa+)8{#dmbJ1tYGro6zO??v}aWg zp39}@6)AY89~f81@vKPFGcI@VT;_Q$vl5@wo(qDW6-=J1)zu&ztnx zULMD@B1zA<+`)5+=efk2=W#*L3TDsiBRxY)a?h$9JeNq%RVjF;AB`@HJoKmZ?UCxP z^Opfdk`dzWfe4Ge2#dW4Cj=u@@cW5Sl|zKZGQy>)M_3idvm!~)xO>2Jk>|O{^IRPC ztYGro6uE5nM=u*y4xWpo=XX-@Our3W8ppFDNzb@@z;mJJxzKwVm>Tq~VDenHA!@74 zftKW3MU{i+Lg{%)3ZCg<2=B!4tVq%`E_d);;CU{v68Gyv;`E?r1@qe880C2+v?TYe z%E5Di^jw*OXS(;mk~p3fNqWZR4xaNp&-tF`w}YM)%xgQ+^ZsbhsvJD$OV5i_@JzSf zt&HPYk)&r_?%+Ak^PFe#4dC|{H6aN6Mv>(_?8A8|B($BZHd|^6QL#fKKUd1{iFE8 ze_jf9>1N>bytL(R~K5BY5Lre1MeHHz_D*Vn(!7n{$sXUHfMUsAT zfrHNYXE^aPa#g`+bp5 zTh|5czQ}glwnf=J4K2y-zKC{T6n1B)V3+Q1GbfH+MUr-Lg@fInv)!Mw-3>vzKWDpD z+oS9*hnD1ae~xy4F6@@2V0XVhjhP+Ct|CdhxWK{gb8PoHK5^R=wEG;}&1;CVI}%!w z+kFo0J}2zXO2O^{ZMQ6rT}6_1aeaf`r`hh)d~RMJwEMJYcSodMXi0AOX|(&ausbsa zyL3~SS=aW2O?B7#37aCx^l-aCdOzXxe!}T(52p8%_m$pHFuk9M^xjTAy_s?BDw4E| z+Xd|YnCc1z>fRU~N_*Eik+$-Gtl44@)z z-tO7Qzoze|p098F?c=p{ulKj~?UDQjzEjf#*}!*MI;QWf>R0eBoF;n}f!~J3yafn7 z7eIB|`DVwF&09I)hDegn^oV?XoL$ka{8dBO#nbZyuv1ePuH2xm9R1_BY2hixS%($< zLtfE8rZTNd&v!XS?6$ z?_3T9?S7x_R_%)1z|fL>1AiaweqY#~l7ih#ZDJg|iX`pg`Ubm? zu-!-aS1)ISb{}E8ZIO0QN85b_?LH#x7Nua99^*G5j$K8Pc5!`!-G|xk!-?DUnPf-M z?!#=it|@AEH$zME*?k!8J}m5xPr>dPy_k#Q*i|HH7uPqQk(kff84uJXXOccH&XiO` z*UyyNwRr5*JX6Aj7}T{ypRtaEVMtkB+IQiWp2%uT`>wv7z}x`OV?O)?kNB0q{Ro0L zDp(c#scG=%rHA-N1!uKbr9g&=%P1&zp%(F$7vksiY4lxf zBFXr1`GDQ~+3x-P=I`C0-TT>Y*}kYPI|o{lZ`u3N?)}2MV^@)+U0i^; z+RSJDyy>kr^Ua@+^Oog@)6g@D6rt-|mmX|`otvxAU-h5XtA2oflk-N{3Qi_k`HZF> z)f=QBOvNCA)T?^=zaDa}-*zHy3iE@Y(fVs)W5T1M*5GLG>d{8a(a!48JRI*aOwtfE zC7`h+{pNGO!FmMEdfzQsAYG%3`WAioLC~y6t2jO#k@{)s$Z!OnrG!Zx5jc2-4@xKW z1S*nTww^`qZ<`)EFHH5^FqIDe!;OV{O%CeqTCeI^>cvPfD)Z4)!+?r7Zzp;*m1^kv zHljyUd7a|?)AP&_H0KX<#lb(XH_Tui;?S^u%oV9$(A4AFYHpZ{?t|1Jy4N9|)klpk z5I2Q+1`>}L)WPA=P%DmR_Btp`MXgAE%;+^IO!c)suBmIZ-GN~$YQkRW)39ny9RO6s zzplGj62MKns5MBf(A56n(NJrUxuxOylQi}ylqD7;Zy^k41K$28co2>-+_N7=wnK( zHGQI=prQgj%)3#;sD{pl!CG?|%mRm5MIVq3(5kP%I3^dvKrVk~N>5L_>}leUM(OEk z*kE?z$Fz$ET&ttLYi(%Dh1XVM4ogVN)nCly9CJh}rjSf%T zL2Ag=o%jt$s3FU1;OR)*H1G464%=AH=q zL5l`=hUOj*bCpGU)#rXoHMcd)RpNP5KbV3`i z`MsCOEZrlr{#Q1h>RB#6%nP-)lCPOs#R1Ro32K-SXfO?9kl2af?hg;>2YH$LeOtdQ z?hA8+d41MDnR$>-W)^8dO@UOyZ=BEQ-W5q&R}Q_D-|HjKy}WKk`&POHnE@ ze<E0Dd%6jjNPwTqIa2;kx z8z(T{SM+%Fp~kLooigaT3D=RCo#DC&e>5Jgg&pBKCH-2@al3xw)DRv_`Mu_Y=^5A_ z9!!OFtp}qI?6-vnQ^{WI!SZyBTf>8?WUuvLWAtG4;lWh0*LtwU`tY?SJeW%MS`YS) z9&B@XFqQ1J9;`|awkbTAO7>b0woDIJ7amL{d#wjst_Rx~9!w>Btp{772ip)HOeK4* z2cwTp)`tgE$zJQhR%&Op;lWh0*Ltv3da!lj!Bn!>da%`cu(jdARI=B4uo^wsn($yM z*=s%68a-G|crcahwH|D(9&B}ZFqQ1J9&DW+Y*lzLl`Nlz_@AMEMt_D%UnZ;!S7AgC zruB0Y)^G58hfR8bYM{dRsrT{ssrMxs=~pp*?7)qk?&B|1Q+f>MefWjyed%_O9%?*( zVB88j5L?WvMK^l7IfX>z6EBsy&Mzs&1kCpiIK@fATESsua#)$(Sl9>aK&U zrD0dgaRCR_sqYn%sFSWRAY-m>h*eh=8t=wfbtv5!uY0VzcS7Uc6j6tt4De@lm-RMT z1l7hz2Istn>o8w9ytzk~g#6t6UVi9F%{#T~g-~qvR~hQBM?`;S-Qt*a*CC|^VOJQO zv0BoTy1EYP=7-hcG#Ki7{$Ht^7gkphn%P^Ds*@`Tr@?TQyzV+=J~!+Nr@>HnYlJJ~ zI50(ToH@{;aU7T!XfSsMM%wj}-qjt>4vlo)Yq$={;qa!P^3Zy?Eh0Iy4ky9LA$i?( za5XEu9&kntb+^ZIg#pE=yAH124!bG~&D94YT;XD-R|mRatrUt8r>n~j>y_u@bSV^F z_2%PzO~-LjfNv}4ax`R{D+H&-$g&G+XGEy=aZ;P5Mftc;>oo+`B510enNqfw^=Ea{ zJ+(dcH9Y4ePHHbmoYi)S22^`70GeuXadbIbbsm_l&e;=mUD`CM`k2nr$4T`DiL>ff z(SWMyJt_8Ls>Vg~epQ!vs!er1F4TDqL3Ie4>TprSS4T5_T1PN7LY0pTRbE3-6@sQJ zTv}aL)uvTV@l=_6-p9>d?AEqnZRk*!9NvT^#mF8h)`?2WrF zvehV3Hm;kl%f6yzzja+?t5KwETsK{peO1dYye_iUC{i}AoA|Q%0;IlrZI8V!vehV3 zHm;kl%Wl$Xzj<9`t5KwETsK{pU9V-oab0AqQKW2KH(i&#S<5cCF0$1qQZ}xeuFLMP z*Y@kzMYbA6%Eoomb=d>7>@n9xwi-ps#&y$m*#oug(bq+`8b!*+b<=g(Ia+r9b&;(` zk+N~!#Fxz%c<#_!aujrEd{}qJYq$>QSU9|SYKRLeWj`aY%QUD_bmSfdi9LB zF0$1qQZ_EAuFKx97fIfAk*!9NvT@yXU3R0EJ^Z@JR-;JSxNf>Gd$*Q7?7GNSqe$7f zZn`dekCr|3y2w_eNZGh`NI9- z`T#iiy2w_eNZGh)U$#iQ z|8^Dd z9)`L*B0gF+cP!42QI`>`4g-o+hp!WKzXZAo!c{AjE?P4B`*18BeIN>>?#@_sS+VO- z|AYD~*@OB(bs6*{PIo@3&}-AjAJ+Vnl21A8kvQF8q1D5^&-o*-Q^mo|$;4b^g^|S6 zr3h0#ZkqCO)0B^sDY_Me!aFyG#ipruL077#E=HL0anqEKo8lGTxp*u##b0?p;x9yq z_i;fXYtfsdPO8*y`dob*)3KOZr^kDD`zxH&$~TdL!q^Ts#F zLEIb%qmMt1d2BiBjbl!_!aJXIEH=g9Jj54cPHwv=hD=}4cfUg190&6@#`#FB12pCr zs}7H4pVbH4L;3)E8uXbuFoIP3JLUN`C&kCjN%3*YZMW8?@XjX-i%s#EYpUYgBEk!E6uo8#c*#vjL=u@l}nrfG$DZW@bCF*sTA#hB)fgBY_v z%+=`cu2|azbBa}m+l6%O)XVZ%SO;1)`uk{v4(yLEccIG!k9r}~#T;~r8{(#4j3Cu< zjzo;(n9L^h~G5Y&hEFEacsQa^6buA&^ zACFas(v9(=>Vm!xXx|6C`MPZ0G65URfDgqMhy#fZ_lFZc80s)HmgDBwbwS7bwd1C+ z4)kgycuy=HXem}5>iDF7L7b^|>@baJ&BDw(|;$|L=AzxAYl8nd>l@UsN6XqMVww{;e>msUIyF{e3Eyj_o1+QFW+;?(n!$>(~Ot!Q9^o z;HJK9?`NFNavZvoB;w{c7)`7kf_~_Zm7C-^ISxi___;sU zyka!5>VosPSI^%D&}Ztv2#o$d9ZLsVid7fXL3i1#4eQt#%KbC3bf6_e$LC|!tq+a& zg;;ec-5BqSvFg@^##A~&T>qHh9q178FY2?YITEKE6wj47-HmvO#Q7rj*YyX+{s3)sLVUujP`|6Mn!Lv9 zofv$B7IE9Hd>aP3BNJAei(px3%HG?r(6hvXpYwMztRl%}UKJYlU{uVeUYs&xej*ET z9?V-eFAgigOpFfC#Z!W=jKcHr3M)h2JK`0hdSk>3@d_7(M!XoWaABzMQoO>7P~qix zg$qK3SK<}U4;8)}uW(+d@M^rm@=#%x`cN~*eGcY^3J1h1oD(V>8n1A6sBl=k!m?1| z*r-C>ZuGGZJ#?WIsu8Ep)acm&h@1O**83W0M#Ml0_dcWx-%O8g!iUACnwecxW7?Y@ zXH-R!2gSETqZUSmZOX+wjRV75@e0v;yu#r0(o-&`hAp5gqr-9WluQeGk1T}y2;I%M z#<@H30sR=7fx$cD+|75!X=;voF3WysN&Z}xyYbFAcc+`T5h}JiUrLk1iIjBB*qvFg7WvG4sZl#bIMO`|+k4X6z0&c1Pk)ZER@J z*d1)FF4EZMXk&Mvu{(sZi7|{#3LBf!wHdpOjorpeF)wKBHa3=ZC~C&~LQC=)yA6%q zCX7w6u>Ui`^OXU*ySSff!v&FQSUEK>8FXwB)UIbCQjN;(;Ids4cM>V)uQ;KGY% z43ALs%rUw_ZV_~d_;Na39;45r{f7P2P~tUs+k92vL0X6SL0V_^=L4z(k5?PuwK9*M zjS}RAUxDbhtf^&H4qTb>r^DsxaQR7p zZv>~q<>|;f9Cb_>2`$Nw2`)~DE2g9Hz4jNK>AV$A7MET;W0)*I)%mjC28Drbur;s^ z&WdfIc=C{i)11P{w6Vs9d&GH8p~nvGdF zsNN`?7_V>)*ft6$#VZ^gDlCpym><6oclgcvldBQ>bEQ0}Mx1UvLU*P1aeg$>dVTQp z8~8e0y5+6k&_OS`OT7wj#e`oXM+qHx$Aq8=bHk15qFeJigyEiB^Ew2?&4EUCaUlNS zj2;6&49d+OM}&Hu9B+m(Sz}F2iC2iWjKZn$3Q@gLSQ4*rXvpKVc!jy4!s$_kxLRpm zhw9an1J#JrybkwpUV8GbDah`HH@wAvs` z4Srt|2c#@TRm!vmbx{gU+z_2se~`ktByRGjsfYhu-kyQy@@CS*Ach6X^@{N4J>u5D z(Q817kgjl{85<*FnX-0&czv^;PL^GEcu1UPW5^j%JHuQII4SW8c?aOZmyTe4!%{Gi zI6boaMEH15hxR_<-qHK}?0ux3|EzHD{Q!#ByRY6~Y^gs4nhd`dT1y!4|AnG_9n${` zDZ)wlzfd$?1iLyR&15E}E3a?JM}vX?#y9iZp^_o^1% z)2BOE^!qXo-b^QyQv{vQxhSmP#}E#EniB+5W`xxR;lE?yLZOEXg};lT5Nb_@Fu|!R z{4FaKN`4zd3DlZOVA{K^BuhVa^gkn%{AUa$P-`lIdF-;19KC*CWhJ!SuIlCH!91B$ z1zkk=Y7F7frzsq!H&x-UuyCQ!!-c|EVkm@KQz1-ystR9bg+j^8F_b{9sRX9I%Ss07 zS^Etup-FyMPqGKo1sNrR&B@LXxbWk3!@u9(!~D)Kmw;N+C#;fGeZIs#$lnhJ))WqFEmh&aN-o@kh45d+5D2xV zKv*PQ7T8B0X@AKAg_2*!Py)545}5TaE9s||ycnV6#TZJU)>H!1*kvVy^s@Q|E1|EJynG-utK5ag&0bp)>H!1 z-eo0y^>X`pgp!}fPy)545}3y>E6LVM{v$%kf5cD%wWbo7ulP#LljxsCDEV0oB~WWB zf%)pP5<0(nK0?X!F_b{9sRZV$%Sz}Z;5k-8ubE|f(|fR3$j`+P2(_j_n8q#(q{Gs) zEKn$UHiicPT}hl`6{e;UIk)S5P7jl{S4 z1^o_`F35d`Z3>0Y#83jYrV>~T@s&JcD0wTWGB;&{F<6LdrkKkOH-)6qvI3Quu4z`C7`4Bc%K|h7_nZrNETMmm-d-|HM+% zgZ1zWhZS1lKgEy&wWbu9vXrI#qm*(?OZmqbQlQq90#lZ!|N+~;ZDnE=N1!_$xFl8xA`5TtPmxAup zQvN1}6sR?&z?7vdN|!NP${Y3QSqb zQvOm(p?3&>8AA%xno?lOQkL>0OW_;1lawc8NP${Y3QSqbQobvttkXN_yD_9dttkbj zEM+O*VJU~{IbaUJ8GpHe}sDG{bJWr=?gA@MI_qy@F66qw4CrTn>+Qma$>^B7W~)|3KMnX;6G zl(Jq+NyLx>wWbu9vXrGfA*HO;Ql5w*1!_$xFl8xA`KFXY-#LCWh7_nZrNES>Eae+4 zh2NAM(W!hRh7_nZrNES>EamG`3cX@~J%$vhHKo9mr7Y!ZQcAN<eSrYvPC zUzJj}YbjriAq8qpDKKRzOL<&M*{r2J9zzP$no?lOQkL=+DWyhB`AQ5aP-{woDN9+( zV^Rvet$!?r6sR?&z?7vd<;yIEZ)1K`r}E_(QlQq90#lZ zEagj5N~=!gOEIKCttkbjEM+N=u#}T@N_A38c_fAus5Pa)l%*`?i&DxKE#-?bq(H4H z1*R-zDPNFMmTM_rh#>`PO(`&CDNFghl(J1r`Fsp1P-{woDN9+(!&1tAE#=`DQlQq9 z0#lZ{=N81NtNP${Y3QSqbQa&rCoYJX$Hii_aHKo9mr7Yz$EQQ}4uF+CH z6GIBrno?lOQkL>*meOu6+fT=k0=1?Tn6i|m+%KijY4-gwq(H4H1*R-zDW8&3X6p(1 zR17IlYf6DBOIgY%rIbTj$|qw;fm%}vOj*iOJ|U$X)>1wZLkiTIQeetbmU16U;a`YW zYbp1|kOH-)6qvG#gmU58}aci}d%otLj)|3KMma>$O#~AYCp&?;vj3H-7{eHxh z3OUBB!(YbGueRyF=^sO(cRt6 zig@VrCXPdsdf=KvL#$mN`jQ^vqdc@3h6l5v4wD`X1GuK5KkJ$z`Z+Qgyo(j_&`0z< z+!g)%F`5;qG=;$2bs-uvgO5ldv>-mxsSv0%g}|((Eac7zA&dtn12A)Fn4T^S&8fpp zA_h3=AC5Ll^Y!7-h%gVSkC>sVVS5G_Jz%CQh}aloVZ0*;Oi?s zR~xVHL$Yptyt+GN-G+E|ACz?)Y@J7you4o^wWAI>(Cr{uao*S=6JU7OO2ZWpP zz(z3+@39UK^i#7NI3D5mhU?+?h8TW9py?MjO4t3;58Ap#`0aK*{C11s7X+GqVMBD? zFa2!JWxu@6N9c9#;bPw1>yd*SBL@&@<^U_d>p9Rb%N))@_;s#_UnhoN5NP^^mEU#0 z^!qhC!tej?vv%p_-HzcG1e$(f<#)lam`LM(Lox1lnbLVn)Xnt24QDzDeG`8SKF0xX z*^auuKb!*PIQQG#Z@1IZEqE<6ZR2@S+T&@%VFe_tN9}eb40rBPXHtngr}uqnnQ5w@ zTYIGSc*VNmwM;8vtNZghPh_TLI_eMWx4mxY-Rs7L^J?#2-S4;Ed)!R*A65H3HIn_mL-}|fY|Md_4=7)d#cYpt*fB46L`td*i z%fJ5Q-~Ronr=R)hv(G*Mv;X+{3%!5w;xB*o>z97>@++_Y=Wl=a`#=2GfB*4+{@-g^ zRv)Xc)z8Yd`db66fmV(+$Qo=7v2v}U)-Y?hm1m8xMp~n+d~38d#(LcrVw8mP6 z)?3y%YrIutO|T|fldNKEvNgq;YL!^itm)PatJHeinrY3l%B`YVT5G+v!P;omS(~iQ))uSY z+G=gHwp$I>4r`~i%WAZCTYId%R+F{Q+HW1OnyrJ@A?vW!VjZ!LTF0zb>$r8oI%&08 zr>xV~8LQnoYn`*sTOHN~>!NkZx@=vs-nFh;S#}@0uiekiw)@)y?16TUJ;)wx53zIY zq4qF)xSeN@ut(aX?0kE)J;r|BF0kLQ-?Ycth4x$aID5QZWKXas+LP>Jd$K*no@$ra z)9mT?47=2R+n#C9vdiq*_8fbzU2e~_=i3YH3VWfw$X;w$+Dq(r?4@>{@%hy}{mS*V&uw&Gr_%-rj0&v$xv~_6~cey~}R2ciVgHy>^qm z&)#nzu$%3J_96SQ-C`fHkJ`uVR{OYp!aixY*{AH&_8E0DaMnI&pSL^g3-(3(lKM>Y ziv6yA)y{JIIDMUdPPWtE8Q=_ba-2cVU}uPv>kM^rR35 zhV!N~)+uz}a>hC1og!y~Gtrsk6g!ihDb7@<#F^$ycV;-H&fCsRXO>gu%y#BDbDeT$ zo-^NB;8ZvZokh-Kr_x#CyyGl&s+?uca%Y88?W}ZGIjfx-XN|MgS?AO`>zxhGMyJl% zfKpJDpulqqE!DLbJfXm`?!7Ger~qg-yPr%baUK6 z?qGL_o9hmBhq=SuJa>dU(jDdIyQAGP?(1%W`-c0bJJv09-*U&fd=)VBfE_=%HgX=5EB{{RnNoon#u&) zI!1Z*++(0T_q`012fEiog9B~hE_q4c2eh?}@*?|$hX#u`GmR~(r>174uVIw6t7n)7 zP+sHe$(e)(yWGUZyh+uAEi=+<80BL1m`Or|#dS>Mkv|Kx)r@j#4;Uz~;Rii5*rj*; z;(R^_v{l?C>v_mPIkks9G}t9BW!NKJte$Y95)*s0UdR z8Z7pfFOTsE&{oJXyamOJL3XiIq@R{2d24HkO~ij7y{k?b8Ao3~25 z-i9t*=^gy%Bi}B+pwONnUd1OERto5Xr})I_z{F@Brpn-sHnU?cQqO z>D-LGayg7QW9)GY^5#k&P7OSsC-6L&yY$1ax~XUOsE_MFmiIK6vf$HT((&FGnQ8Z` z2YSx&9tH!Sh&igXoBnVs_$U~C63{*2{^Az9(oLHq#ds6V+3Z8nvn3B_6vEHqoWCD-R-QdBV8R>6JUT888A+J>OaMqwdp7g`W zn<05PYrx}4Z$aL4$-_W_$NTIE@}>bVILuKW4z4ZC8F+j+KZd*#ISl3uJU*{!Mcz~% zhSPz&uxF%uFi+MA9}bR=vjV;HDf>y}P2pbo(BEdlyi`v4aIjaLL-^2hdd)~LlwD)wLF@2n*NpVBl82E4kEOzsTr<+&lsqqT zUZL>d){OKwBoDKN{`j>Op3|C!ed!8(q9K2z&sQ1(A5CUD*O0waKdpW zpq$g`i@Y&%besv`@y_UnywQ^P7RzCk*~rV6Jd8gukpmSi$wb14yz%>EPorc{I6=VU z5#iyn8R;V>4<`tCycA)`jPwyKm|wecd^i{s&Ks2TTmM1G%ag<4yaA8jv=2t!a31Cq zy}S=GVc!0^Cd{)3&$Z1+$4-Kxyvb+r@EF^S^kGsIPG?ZmaO4eTQG79Ro(~6y!C8iK zK30!FUM`pO(i`c+!E&5@DCguyA#aFOiBk(a-ZA;e8!UM^wZZ;IBX5wDGscI5a=aPm z^UK$fmm`P4sfA(qP+EYzfs*G`DuPwksN9F&8T6?6kn6wXNRFNg6ai_?aO z;bx>~OP)6?yrbdSw;AdEBoE^cjtdW%%}DPnc^E(NcwBf0Sw?yv$@Ai`r4L@mf?v}0hl*1JP(TCV6QkU&@1mOc>GgF`b8-o zX9akC(g=^y$wom9mppH3+4WrHosm3m z4tb-OBkwf3;W?b=!$H|NSs;hs3C>5}DK6)Iv%rUg<=z~!>k8zxaXE{EtDQ5_5e}B) z90tQ!guIhn&Y3Uv;b1vVEtK<=RU+>Mlm~g<)bc`wi>Ncwk4qj-7WBt2fA1i#Rq}AM z0-Ihf{@JACX;qQ^=;5A+H5^;E~Ih`*3g= zZwk451@aEdVZ6EGby|(QLz0J+0^{o9RMD{ zyl`twm|r&6_;AoQP7svy!d;8J{c`l9JPf;m%j+}J_c6@k;p+JS%$pG|jwd)cI?f@C z&PPPJ7(OGtNsjK#A$y05-!szp^60!B>U=mj49+18!&9~id3)qAIEO*rX5{UbJe)(| z@u?47Q=gIED0w)CL3?lweMb5&$@Aur^}#js8R!{Cw!q^f&`#vlOCDw$w7v^@ zTO<#&4f<$A-e$?eYy%O&is&RFj2XJ-m)qUgb)D?G0f3-{J;>WAd6;cL0=)N1A_02h zH&uJFrwy_vOdoi>jhc|RUh*(~;PGzVhrC+J!}Nj2$CUlZTPJy#KJa+m9zfn&$;0%6 z{WT+RjpS_t0C@aK{6XZ^NFGKGJU+Y}Lf&f0!^nZhxg18`D#^n@fyaxr1$iqa4+8}r zf2?x^dDW7Kfd=&*McxX@!$5=m9Yfx7$-_W_$MeyOyk(MyfdY?DPL3n5O7bvJ;PJej zK;BZx!$5(@IiEz{JCcWi0*`ZPL*5d}!$5=mokCuv~J)c3| zBFV!*fyaK^k+%?d0Q0fztPclYJ}~FNMun5JBpWqYf{_PDJcnH`kjgOfpoH_tn=g47 zIq-Oeb|7z_#_p=!uVcSFoot*;54ofu7*aOOl>~lY;3(*Zf-ZE_OXrc8%!+k6+%eBJXX< z!}Nj2%PI>mQ7M%?OdohWDSePPL-H{FV1Ip)H(l~DecP~_J$#EyyRidz~j9$ z9C_m;4|4_{@5Maiy(M{=Gw|5Q2;>z?9_9=@&SfO>#!4RM3_SicV-)hP~F~Dy#)ko-(hdBd}?G+$zjO1a?z~j~R z2J%Kr9_9=@o~AdEmoIskGw}E*GZuNHBoA{A_E(6!k&=fw1CN*6TgV$Bd0x)E>&783 zPx3I(z=0D!j_KsUiP;7vjK{8r$*wV5;PF%!A#bSUVYa|KMjt*-KwhroVYUIO@SSBR zQZZ)enm^u|h+PksU1Q9^<4rONd4nVmV+J07-&2gd9Ld9&fye1jM&3Zl8x8>Qc#}*) z-T=wNY=OtCZ7TBmOCDw$9Jd5{*^-CZ0*`mYH01S@ydeMt^-V`!U&+HjgZ<4wULVQB zK!L}nhNZ~Mk~|C)c)ZHrM&4EaC6xC$GwWj?Gm-bMbuHo9DPP)DVeL&azrCd37-7dSn%sk$k^N@E&@-SxTkB{8*k#}11FlONK znpuFnQ<8@<1CRG`1@hV?4`T)%zdc!qypxi59)Mtfi;#Ch@-SQA@hjS5{Lap+8=2OOSU=@-WcgxbGnEsN`XwK_5$zcSQ0qP~h>gtqOT9l81o;kLPz8 z@(xQL1{&;dIr0uk9tH|L_PYXk2PF>!4f3jy*DQG$DDZf_tVG@c$-_W_$LnPk^7cy} z1`0fWpSc=&`y>wo1s>;DgS;lm!$5(@>wXRL_DUWG8sx1--X6)rK!L|cops3DEqNGd zV9Uctgq>`8%oe)lrCp0%?~+|(w!q_;+4acVDS4PJ@c3MG1M+qN4`6=v*yzK-Q+$j( z$g4wMgB%7U2OgipZ9?95$-~Hlyv@klCV3b+@c3153-Y!~9!3s4UU~J%tCze+0D#9U zZ!7Y)NFL@K{%9!3s4p0R_-TOoNEDDe0IaR_utzeAbFTA@Hom-$eS;D zm@V*lNt{OBJjugsfyW1}Gsr8KJj@n&yd>I@H&^m7+u*ookv9i;0Q0N&IUf$jg^>e~ z&(6*xZ?+s}A@|2GVI9aTlRV5hFk^59TPHJykq1iPGTBZ_F#SLYeEr)=2~I?y1g@~| zqy*15lX<+nuOe@<6!JFn_;a%?{7Gc7}0s!#XZ-3;Cmpq(_K=5$+ zPmd(UOOO26@AgmoIt$ zpS>@ElcKmDehtbE3%j!?u&~G_DwhYMqT;oRO1y*Ty1)P%7Z!IH78D6y+=+@O!iq=` zQHcssgBl}BJP+}?yZL{~FV-?WZ@ON+diAb) z^-2&_nL^59PBDdow)ARVHP?z)FLAzF&{jp^Istc`6Hd^U;Fv3y2)JvVaDuif-1P$P z8Yi5ft=jJm0`AvNI6+&2V`X`xfcupbPSBR%c)T|WxW!I5L0f|3Rdcg|TjYeho*pP9 zr!!qCNG@ngujW;Ai+J?{=c@&6367J^mkPM~PB=kZf@6~3D&Xch;RJ07j=6G~fSc=t z6SO5b4)rbu~7t%ZE)vO9u zh*w|ke6^shit6nGZjKX9&{jc#4ke{PL6DhV&5W{Ay!uBv#ihzhL1yLEl(m-P)q>(G z)^~_kfA4&?pg6%XPp=YiyPa@?;tC3M)+hxES1^HD;{8Uv`djC#1;tfVR|~jr2#y}J zjd!Q@SS5~_2!dl4UL)YXc6RdR>1wo3HJlPj|KnT0&bTR zPLQ15$CG@Ifcw%3CrD0k?A_ig;QsA|`;PnNajX+?UpV0eo#}nNbbc$~{^f*A(3!`3 zpMd+^2`30j@8czVzkvIv6HXA6;MhxgK)`+GgcAfMI99~#1>C1jI6+W?WBP3naQ|?^ z34#(F^TF=~+$T;rK~RF@@jfWv{_cbm1SL3@4-W~rkDYLWpelY33%HM*aDt%f`+hIr zK6Jtff)X5Sqm2UYZ%#NtP-R8p(dQHkQjnJ3%rp3ic=P+tHw)4d98>a90r#F0PLNi8 z-(v#quTD5YT7qMa{eyse*9j*`tBeTGe5V+ZATqs~WyIs+&F?thEQm~StiJvz;NEt^ z2_mcSdqTjy<%Iiy9uOSIv^EL2H=S^Tv;@a%;Yk6v(+MX?OK_~NpAv9?cESnLDioq4 zX(>n~sI2^iPEDow$zOPMJYSmyHm^Ie5o9K;Spxn^z`f>#6J#bhUU5$gxL2KUg3JWR zv-FIB+wO!DWF|O{6Fn>7whJ;dpp22)GxWaDvX%FAMG$1>6fxI6-G+X6f8PikTH8r&sgLz9e4# zyz|w9kzX`DKCsGfw;k?Fo)0-75m_ zX(ybZJ;CwRZ4+>Ra>5DP6CBIr?E-GI6K*R#P=-Wj5mO9F&|ZD@tK!v9I$yno9uORh zy4M8UCMVo;PB^+Y35#zy;htqU=CU^g+#j8Ag0|EzlYEDOd)x^pXiIR+-G3Hve{jMH z+A1WXGbt%ZB*?6yuv5JHQRl0lq6aG6n*#0;C!C-y!LfdOOTcY(!U@_csM1OJ6sQU^ zD?g#)A1Qt!D6ahEn$!dl#8-Yo9hS=pD*W zsJKCjpNN?vY?wFR5!kGEVk2fs#riJ-?g1y9m??r|b@{G0_6+RYlcRJw&nF)@C>)!?3 zYA2i^Gr_S0{6xV0#tA3LtPF_`9j9Q>d*~hXYR-cBhj{fJ&Q}XEE3d{nODWzg2(J7B zOD?7O#a)aGGtZ|2mlaN21icAo)?J?oxZ9j?g5Ctji|?NTuF(l6=uL3US)U8Iu%n7%O9uORl;|l?Is}oKTnc&za`L}>u>V#X#@8d=KrGUG|33od^P$*7y zI#Q5a&{joZmw5F}&Q}ZCszdsZfVOroy@+zn1RL0f`j9sIR`yWR;WXiISH zZhRx)mN?-AZ3&K7(zgQcIwzc%_1i@g3JWR)cR4tEp);OG7}un(oX_z zffG)USwWS~f~G)KP@G=Pj50?Q$(-kWwV*h`@mjxJz|D2S35pXOPwW)}?rJC8ujm26 z@mji4z+L5pTkM3pO2A#|gcGz?hE5fWQVd;?S@{XpsZ8+;L2yEv=k;oV%p4~&^XY-| z<~LI#BM45fW|cNqym~giNHu)~y;Th8%9er-mpQ-$xe1Jy1Kn^_&|#JXOi)|Flg{*~ zAb}t}y_pvzU7AtQ;S$H2ui$B8&R!_MW;(zwXE5f1MFMPw156ND!IO@9r@-@<_zFUk zU%Xhnc)H`oL|%eoEPo}Sra7R9x&*~)>DL0P-T_6#B`D^NYXnrC1L{%}ikI890;<*l zMdVbmzfM41?0_O_5)`YqB?4-y1B!^L&<<->rXXE|`C2C3_2RWt9Iqu(Qs*p^ZV*tD z9Z*C{rE@HenWA%|sygx;#cMBeyq2h{y!J1t*B4P(`Na*XIf$sO{DKP6q`;jhul!KFJ~881~cOF^M3^S!JbmWlUX=y>lW6N+(ME}$wLP!mlkPH<=xP!~9$ zh?XjaZxc}GJD`Y`%1EdTq{~R?J?zb{5brt9@gAZ!L9r0OT|k}dfFf!W6pwGEfI7zk zMbuWI?hsICJD@7@vw}Glfpo!KlXcf6PAs=SxVJfs*q(O4b(8u8v!9q%O?EAOQm87ba7 z#(Xc&=w0HyKXbg7XiUAcwplBnMmwO0#stNBNE zh~7#cR1zn}FHXZ>sPlG@!2JY#s&XLFTX`>4UPLx>$-nXdaYb zPzjzCzo0o$enF*$QvBj1`~}g6mFB&IK1btIl|Coh-%B-ZQ@nSS{TEcAB*iaiP88f< zOWnuu_zS|Ft)O)R_apGBihH^Jy;KJ&1t!Ot@8y`vZ^e5@INp1#{k;#Te(y2%Ur@E< z6qwLFC^UIB^)HUH|6)h#UyQW>;yU+n5S>}m+$ZR9F#b-Z^O5+Opjb-WFQA4wplEiK z5n)~J6eKv@d@U=m2gGX+bi9@(hdSpeTQ8sva6lbqLa|WXAfWblKpl#o6%?t|X$l+< zalH3;;=My0?;UPJF&Q5eP=g&%L{^oI4+*G24k#k4f+H3pPl4h==4*NA4~y6C=XfoV zl{#lF_j>`guLFw6N>J=EY!p!YIG~8E>bo8hPy-xLLro}_KaUEiy&X_QN@ciIIx59@ ziLA;m-cCJ{CqATjvcl9@+m}~whpn5o<`r&6~Bv`dS#X$O+ zuVu6F3Gv$Qj@S0FzZQ${r+95|^R;a8ZxXNV>Uiy5_SaH*^%UK1Z z=(yO?F-?K;8oVXIz*uPt=EmS%&Xc>Qk{Pz4UCQWJ{j`%eNY-vLEa zprD9138X-=oB3L1kf+6K^Bk|GDIgSCtUM#2ave}5_*v=v+SChzD6ISfZ?14bSDlz= zMaP{T9T(we73w(wmE(XSx)T&L?G^#m$pJ-lSKsx#fa>UgBDyPx(^U*En5(=HGvCXz zyj8rnz2m(^c(wNz1XMc*6cL`F*f)4lK(%#1bupp1$Cm^Y-FBeFXBi+Y$B`D#jUA1kw{Fa?}Bo1 z*XVXaT|C1=#SdEA ze?a$3r1(V(`!A@BWQt!H^b5RLl!O>vuG)sE)k9pZ+Ecw*wf)l9pEC@+%%T0Y_>b9e z8O)jmmqJBFeeFzaCsa+Ttggm?O{l4@sH?B6k57(IsjnDYGv0hwTRCN7yrR0MW-33N zHf3CWRn3%&sWo-=6RKuFbya=5wz9gSZrTL;IJGuTf9faI)-=GBcms^9nNn8|b<@Vy zjjOGiT3=CFJ8_!mq`C^9V~10#v0KOE_!NYxt*l3^1lWYCc=h;-swq|VRh89Mm&DD- ziC<5xtgW0JM?@s}#3|D%D(fa!jH|90JJ$JdVoiOG`quIBan<;9F(}a)|GH*c{nTmo z6*W^4lPTlvZ?2k>^p$`kjK@{dfG5?|Vv8iL8i%;l#qm?c1SVc(eSK}!*lG3gI-)v$ zHKis#V_bYH!c>_5K)Q(sQ)=*GZT#YCRkd<*5Zh^W@d`oL+RCaa^-x>cfUl{onlh1| z*5eEUQyIxWnWznQ@kuo2)+Ea*Qa%%Pm5(-#070|_gTVM21#(;s;#WVdc8c;WJ_8w{ zu8tVR`c*|evQc$>dK|fhc@4(a#w#yUKG!u=)sLH`JgAzWe4t@e$1A7Dm1i{OswvZK zk1CNuRv!(Ms;bq`NR+8H({N5L5FErz!DQB>#3ZS3)s5z+uCI*n8)m7ufql(IgO8iG{)x=5l zP#vE@Y*ssM96pH?7vMj5_UrIbf^q5qIj61;Dg?sVrC3hb6EA?8+B$1JCRP;wfB^`t z$u;Ava5W;R$${80$&RVvFx8DBLHAJ|tUJy%v?9iV8KIHeLX8)^Py%Cze0sr9vzjKq>Kqox+j@k@DxpT}0= z2%ust%0gTq6KYV>@LC2-5JBZwq;BOnl3=x!GZRF?pQ4ykKZ=FKM4&e(eyKc6JeyjB zOBiL8+jj|hp?oRl8tF5hFdk2fUip^aW{y!xHpC&(9g638Z5&05`YY4}Bwv;HB;aw9 zP<%{^*P+z4L$C<5J)K@zTUCjZrM}CO{p0a9I738k>!DOJ%2$j`0v1IPPPHZbr&dhQQO38@vCb3qe#s0@#?C{q{Cp`Bvb?A=wAsLP*F7= zM=ux~Dx5u9UkPd}pi@v8)lJ3Kt^VG`%KFvC(~x2DDJnMWp~=G){ADe$IU0K z+IpM_3gx$+RZ8IMa{c1RKz z#bd?zs=8m8wv!a*@-f0D9w%%;?ini3wyd`VHNBD+cETP@$SC^8WGN;wJ>oG*Axckb zrV?VvED7ysdq)C=#6R5O60Z>iafe9=(jYMIub5V+DhDwlmf7xTtAn3VTNOu+vOTgX z33^{*oKMFB#i2L+k%Ih3c!`NED;e{Nb!b?P&gcFIp_sh~8)Q7I2uOe>FsP*gv&*~vbW z?K_k0k-L<~H4`S(#p`P(sLzC4wm%|KV}F8b4gDeYXVa#RCr3+pxiEFq&tig=2gp~7 z@>jm7U>i<(HZeXWj@GBz0XZL)>H|}ZD!;N=7xm>u1dApx@s<$V!u~>^2%S0PDkuL5 zm#hMHH-0HKg2JxmbIawBaAT`$up9AjGRmu=Zsz2%HPs{%r;xcwPBAhSO&$J|>{0Wd z)8l05njgkh^S|oq$BSo75b;4+v-oqo>V90cX?;$wtOirp0BRuVmZGS|$7FcmSmX!A zG~q|+?vZ_nauhWOKg3V?Q&gexN_<#@{YqB~J%T9{>nD*Qp9IpGLW>$*s)XH*-T_qC zOqmEmKnS^xjDcnuzMTvQ{HAUuYN^TC*I0hSj7XC~c0tVq)6B+yNbXC#9}TJru$S2) zS5HWML(loUDL5edB>pn>=ttr?|AW6UAIm=^5($dGWQk8SN<5^06JqF8#Zk~yky@)5 zH+3qq7%4c?_~R<4Aj{&fkiIgmVEr1sZH#kFkE0e4;NssE()YwyPKy)Wgxks9TLsQA zK1TYml*Mmo5#md$rXzI|;u7Ri6h66_#_E~Gzc|g}krbNzgbXQ@yG@vclrldjG$#LK zDtZSMY}YUlu>b?atK~bX#|mK&aWC`)DM#LD1qM_m)r{xgm;%NA5M3v^D$QPaMyLZ~ z0crrL&CgDASb>f>i|{BM2SSOPXjH{kD9_h#bpzzV;vBV@b__$_z zytWoS1|e6_y(ec5;>gTsuA#jsKU43*14%HQIh`OCyP~5L?22k{%6RgI(UeSh9d?&H z@z~~h+k9t0PlMFB2u}!anx9apLO$SNi}ciR;5GHQ+T!Dp=)!MEkV2AvJSqd}r654U zFTsCH>1SGXP*E;55DKRHn#on;VCuB77&AdQVkR;*z+CbJ>0!c4s=yDHN~cd0I~0GV zq?7;VRV_YA-Vp!fS;Y?*!1?FHx%mHcVf2|Nodid~;fKRvBMyiC4u@GI;DQnOc?66Y z0f!wn0tStM{YJn(BVfP?=sN=XjDRxw0uF^k4oMKeWC4tvT@;@(RGBq1{EDNP8n3J$ zqWIGs{E^y`zfUl{``5g1{lCRfTooEU_TX#+1=GP*9CZq(CcaLHElcIwzE5E2@jV+@ zYEU=va{e+A+)aGLBa^s$*bq!5evO^$?UZB~+Y+#YphQl{0b9^DffdO^EBcst>kZ0TUo&I00xiouPMy2STP3PE7&u``}!!6${L5?{&Tc|@TSPzljuITGZank?%K z=_I~z#03)1y`1m_fSbpi_)-allAKIDPsnKDObCf1{Lcgc34UpQ*`J$&UnM#ZEirH* zdU$t%zfERB{)TzWGLREkB%9ZXuT=Xn@laZF$d|&bOgu)`L~GDy?Ipfr{=lWe2(ev& zQ5dP>6W=6pq#zUjPI;A!#F$cps*GHN1bDK=B1PU17z6_c4ut*ogMDG2eNd1NfPn*` z|K89aruBm}`@u>5VA{d`pl@I31JioJnZ01zY4`{KI|=`rb};>e{`P`iy-eGV)*v;+el zfY$j2#G$IlKx{9&iZ|DpCaCCdaD3}NHVIeGoMlkYwK`UqtZ6F5Sp%i+-UO3)zm<|mv z17^Y{xT!Y_clTz)FJTT`4p+dHFc%iUB3KN+f?vaOSPvUuJK`%bt|{scIX-<4!ZDO1 z2J%gW#{$HJ-nI-!d~p$D(;hlOXXs+XY5)v{qu>Ojh&y(3O^g~7*whtuONosaF4Kzk zGAZMZ%SgnfJPPgJ2JV8jFdIKT z4_n~{coANL<*`Da`Ifw9&2b~_fLmiFA$X2wbvv{TL`SCI)oIgj9`bN{^rID#-fS;O z8{0*ZXZ!UWlqS%tl>zIFzaTH}HhxvK2OJH@z_D-~Y%7TQ%lx3xeX01kwMU>F<>!!d8+&;;J)a6Fs{C&9@u z8h!?+z^QN=oDOHenQ#{T9LB)ea1NXc=fU}CU01+`PzhsU9E?Z4CyDkDJPf~wN8oYz z6FdXk5)$S52omK+Z4!m0ZS%tB<_NS|s+~6F`CWbZ)?MnOK1BI+LcSXpdvP$!CrdtB zveD9u%OcRGQ5$XcFeT`JVzlCi=XXe~R=K`N!;Zuiy%C1x5A|JT;Z|21ZiZW6skyeu zLZP+wD6XqLO^l|uA-QvXp(S^Q<@@Vy_ZgI{cX)oO7#Zt7)wc1LMLd(1{ov0-Bz@em zuy{!Ad4Q)Bw0d^qqE;r2#tIspsnF<{ye=pS{pFeg)AC}18Znfi-Gr6bQ`mX^O}T9K zz7b~R<%?C*6|F|H8T$yUac?1M?baGeNwybO2z#M-!d|$eNVOMM<0orPEDmiiEKJj0 zU@3W5gtd3KwzZd@U2t#OcENAcwhNeUg}xHhkNb;F395tpSwj2{d8{9Nk85C^ala>3 z$iMN%45dQ~4N%&;{9i*C?5U4I_dG~*>ZUvrNC?OOr-gGuBgnkd)({;=^>|%F{H=k zFQm=oFGc2Zf9c?E$w-Tsr9-eN5!(}Pwv1&F`)e0JY*@SK#AdXwHI*lvKE&?9d!y5x6Even5OmezVs{veIkI@{{1ot|Ubpl_n*FcjX#_5e_^{4?UZ zpNZ?=F)lg4cq7(AXyU)%U-Ga&Y>U>S(aLCJv^Dx0dmCRFuf^J;5AXES-zaMDGE(wM zUMuQ=qqKYb<>*t8FY!vOqmLyVE^_o{+H3UfNRcD9DVmp8|5t}L`b(2)qxU1&@_*B2 z%kxZq5=l3Hs!2Dp)OfZ{3lXo~Rj7JjU*RXq`&v^_Wcq>}6L!WmWTc;Ecq6X6)dg;m z6zLht{e;V0hKwP=AMZlEuKqZ)ra*IKaYUR z7n*VTG6F9D(TvO25peldGcLO$;PQiJTz-mxi&5Uy{Zi!w$%V2h%RX9CgqZ z%baKwJB`dst&7uNV{J9B_x2HR>8Kf(oCvsd(TvM*U%noe6~1PEX^;D3$vHl$t#aDo z>}Y2FShiLwFTjfBY*f4n#-%UcnsMnG0hjKYaVbwzZ)Rd= zzNEmsrAQMlyg%Cy zt*TPk8{7G?wlGZYqLm$Jz&(X-dowaCl`X8)do!$;4vIjZgEi5IaoHyV5AUa$hx_`< zyxv)rdF2sohZ8j04g-DZvTs)DGCBfXPSH%4&vVn)OCRUz_5YvGNgtP|a`fU-5<$Ln z(=1=Ui(or^pQo2Dr4i`TQ!`x#MUcBgG|S!Q`OZ<#tj^H@UtIcU6_-OJ%+UzVb99w&tn7-c#>$rY;<7ZWxUBKT zWp!3@De&dpSXOwqjhQ1LPaz$F{$oG$EYjEFEYjOK)|r4;3%pM(Y%3U`apy;#BcRM8 z_TN_d&fChY%p2zbsJ`|{q*!-28rylWwXh`cnL*X-ezCBpxuaoaM5gO=Hz&JdX6y8Q zg@)F8ZQ^@;`Dblb_=kDD&ms8`I3Y10&!vSTinX zN0_5?HP6v}U*4UYRo-3fi_5~S;_|pJE{|mum-8d=ONC~Bsf>WjIL)|>PBV9f^V@Zv zT8l@Z%S6p|`QDdzzsoA`KIx0g6IsP2*Eh!2IV&+Xwi&7-@XJM-`DJnhTxvAqa&ZJ) z>NMlB)t7g-WR-Vk`Qma(R&ja97nirPip$f!xNOcUF5oL)e#|N^4;Q2#Z+);pZ@hJ= zFI@&_RqjrUAYU3Z%a`V~re{W=%cYv>(wy>&+NWt_W};3*bBe!Q7J*-Wsfl0gwOKF6 zeYZhyCANd%YHUZsx1u&{K?gcfbbATaW@(F1YCZl8JFh7-`7N-%XOORa(x6`Zq$s+%@J@}su`DM5pZeLjLV7$ zxUAHS%f<+?&Xw)-*naKJT#{8n60gQK4%cE9Nh{+BtVuJ(I9$}q-YVoV*QaTlFKcES zF4Zup$^%uN`6<>vkz3-dHyf@JW^!K1nh0~aR`VR*69JcXnsI3nfuHu!96P_eQ~G|* zohhokgguMjoaoXVaN(RNwTksVXoKxG?kl!3$F>#7x~BGu_?Fd0m0T}N)Wv_*^hGVZ z%dLjBcTIeGvfHw~+WGpTZL;c%J`iDzZ_u>Hxnfa4TUoKluZGR)g0S`F*A%2zU!JYg zuX8)O*1#Q%m3HG;wg1Q5L1qmlXFc70&=(jYs_J@I8lR5$C#aQlJphEDILpwkB#rxSCultK?9g|KQV(q^6UVXm9M*H_%cK~g84kUEX02Y^y)v@x&8@->&JN98bS5q zoLv8APG-2?y%t#z`sg}8$!DXF$GbIl8&4|s$SM!|$XdrlA&vnx!b**|YItLGQwWT1 z$N)y~ifsSQ3XQ5mVDyU&VD!Gg=xGI`D?(s2Cj%HI^U;zJ7+tFoBbMhc2^qcv+oA9# zwg;H<{Iz0P{q-IEOVwYK<@vT^x9YE3JmvYbz7l&Ye(QY`0@r_C*pVW%e?>fFP=&KQ z$@oId@hhDSs5U-OW_oyjJ5v*@6(2|8y%?D}Wy0%no51Ho1(UV;?)HP5q`1em7I8ZE z!}i3@9LYR4KLpRs)yQ*fpTC&Gnt3_n)(m5^GX*AZWgHW(i!N_;`6A};xqKNL=xK{f zE{W#1bTi{``(uUD17Z6fRGYa6o)LHiR$#jUF2P-qLKxAR*58p>kupI)Uu`P!`VASp)<8Fi>U|fw)-Zy#_8gPd}_mkxqC*V5HHU3d*Ks)2v4pPpH z!W;0Y8sWz|EnshBmvLlSOPFEYZMGd{P+NqA z`c#on_k@rKYc5L1eA}vjayMh@x6P~^8D(O&B)8F9g?i|SA^i= zMvYv|>na(e86hy5t`Q^VX7~Fvg7}yE>o2BTp z!PVIKC=nU#Sm+%O&neu`Q?tzlgc*hV$xj#^=9` z>5b2`t7JE^G3V{(P9LX_*qc|rp}FG< z6;)z?`XaGEy(ebfj)d0O#$hVX;~Zl(wgZi=sB>Bw@uECm&0^VC6B9RjsP>g}r!3V@ ztQAR3=Jy+XX?9bFXy!eKjlTG-$Phkkvy|r-rJNb7YEkCy>b@X9jC8y(zhA-%wQhsp zJdkjfxZJhp`Poaz$F?O_OyC#3^HZIn`Eiqv=Lz|EgpYh2S(r&Xmub{b(5SsaqdC4b zx+04-8YXCTst=7$&nS)D<}EI8`pGAA!N@31spR#Ih~FIJ@7NABRttIEC9u5C(`?* zZ>8|LcV^hH68`ky|wXy5@)S1D&woen8K{<;4njb1td9J2RW!4okJ}GG>sWiqDA1jy3 z%A9^Pr?-PTZrKN^=p*xB*$3)^GiN~Gb}hy2rtMlR>8ScZH{mDie$(ZFe4tw+`9OAB zI&D_QAcN ztKe$52CjwcU6UZ3kI`}Qz2lpd2Ho(KUxBeKs46k6m@Eb^TdDE&IiyV$P zwK9r*?2oP))%DEdd5FhuBVXb1dpvo{%4)HAYON+7XMChSEmZJ1&Udfvm<;c=?Gii2 zB?>-kef9f28Pe}epRWWy-4uML`r=cYVSHkOe@Yd6YD4kQR89Qjw#JSTYplD^8tajj zHI}SLR)wO`N=-Ck9!kdNrcn6Ypc$X;f`@u4JX9SDpI>Oghi$a>Y4{d8PxtdY$^1t( z^D$MO;>_k9l!|%krOeY6q2_6hrg>ueB=hl-Q21P{2_NR0-FO$dx2N+%EYn#lOqVud zo_Z_uwAR%hw6Y;+SHaTh_avP_NXJgxh#5N4?om(wtrWQRRdCx@(8VXRNSM)n;;W&v z54`sjnNG?4Gb0rLOxMIe-uTQ8h0iQa_%J_jP2nSM$*_;eI=w$y@#|p#wj1Dl5wCIQ``=f=DCQ;7B$OLN^bobGFz&d88$%6uc` z&c4D2l>YLExo*1$97&LStCk%6ELWeuY{yCUOFzp^*Dw7rH=19{@_7(aNZrTu^Wm=! zgT3<;zdAGsI6U55IQh9PXxd3je$tp+v(CEiHbAKN&5gcijd<7;dO8eK$Xuy~Q%sV-~&R9kssk-jQmMJV08 z{fCl*%x1wd-*ooHA~#D|d=Yb-169^?%)b%7jJZo%va`JIBX+CG#yOpnb_RRRxSTM8SnErSb?yWLJ~$umqhU^bKU#MZ}nhN(54$?`tSr0292 z^WGL;nYA^;GK;ae#21TMS;AtjFBbE&gvCN%EEZ=8i?@8ScqdC(EcL}=S(dQq;47ay zWl27F^Tnbx!&tE8w>R$4))~Vw)6&|v8&=W^_xa?>aH(!uzp)Hn7c!r}xW1%xQi&w&6-<2>l!z+QYSnaDd)?`U*^!KI3fGpACF<)9d zo?%+pebS@z!}+Agn)N$WFFkyAk&Gj!@<~4zK4~k=u^edZD}2%}A$-z2jXr5_U%u&^ zCBAvWmv5fTFyHV>{>m4NZ?c5NN?$BiWeJOSeX)2iOIU37#p3Ay&|KW~#Y|NKW^dPA0^!E9eF=45!*SsLu?D;Wo7i5ATxR?$ARy_bo6 znZC`!=V1P59$dN$*NS=$-+l`J-?&!Fur}L%Fi=!xidH{8Zu-S!<2)p4buulQ_6z{~ zq{;bI!+q+?XR4Z9^PmZ15%ZN|1zD0}-}y@P@3SP)zs_~9?P29TQ-$e9tTDZJVomWm zgFcv1?!IfsXHea8I(Wxnn^F(>-@dfil_gs2@WotqhgcRRtuyLoCo-QoGV>gMpw zHTurniVV*jW3kp3i+i$!#X4Us?#nP1+47fUH1<&!e@RATvGSs4B}%=~*rv4sc|8tj z7Irbqu#rNB9jnN&-5BlKZS*i@*tm95h8?ZQu+uzbSc$I;J0lGl#_RQhkkP>l^L6I% z@XRG=au0K@IP9LAGCW_$X-NA?&2pT#esBTK*g7LQmwQuAj!WhfpVK7UDQsOdFRRJQ z(b$pO&33Mj?)V6LvhVeX8I(+$@Jx?c>q(4t5mPE^R?QEVzP;2PDg7s+D!**;pz@M?*4}ONcJpgXP z6Lt-T`^^_`6z!?(Eq@sB9*ozDI-o6eARGk4;9wXIhrpqjnMC!M9|8Ybdn}E%M&R)+ z5qX?t(FD{YyNy#7URo81m%`tW;LS_kxGV{TOZY1L-nj7G{1{Gc95pei!nmrwN&RuCh+<3B;S>t8aVrCfiz{W98zJa6Zbl7*t?e z4wcxhhjG|$fJ;$3H5gA~yVVi;ijjygWbpf zGM4Tsh%aK%bVGB&Bg~vF6LU7woU;jm=WJ5MIpcLUF~T~FM_gx&!>bWw-Zo7#@8t+M zyr>C>)7zzQSDo4}+S=i{_%YXSm*MN&{W7%6Ko*pJ{T`d2t{gc!KN>Aq{wLc>HwBXa z;qPtomj6627v`tW8y7^R2jg&2i63uNmFVV;4Pfm*dC$rGKywoQhMd%M@@@o~@s1{$ z@j(O}-qVCbO#~e>Iid~;<_}(sR#Nlw2koaw>kvPV#eA6Sev00z14Yr7@OM~x@iVQl z?GVOhSu1Ro0@G$WBe2bKRz#a6*j!I{#ZDs5Tyf$}gj#pkM zeCJCP-?=&ve}%tc(wo16&F!paH@Cs?p55&5=JkBCZ=JUj^D=2C2BY1aW=p&B2tMGk z5q&_rO``4(jqzB!cAF&p4Z~h*SK1`3Hx~$5a)lyG*5GZJ zE>|hIT;V|*J1*hxsrAMsjIH*ru+{c9ZM6de>w|+L+G;EdzKo^sw?>TzGXEsoIx7Or zS@`?ayyuM9mb$-qozT%o6b9W>99gJ4qh>*INh1HP1iAsme|thN*bDe}iXpJSxeH6R zjHt%ya$H&SihJ1V8&Lia-TlO;F|G5J_IokpX-lf9>PC;>2zneEm>wgv(Zda!bpo3% zfw9Tch7GTs)6<-tQ!_FPl0V?L%S}y0J)dyMU_BTw8DCz4ORxd@m2)O zhmhwL(zyl6e^!EVujJce1hy?n>zD$D{N39GS@5o4S;KL z#kDeyz}XvO94>CR+$wIjd?O}rr*E6zLhK+J`Sv;@KgIedb}^%!lalrBKa*>K$%zp|43wO z1YZG@G_QagnjLQyo0*vh;|b^(T#9*^u>Qd#if>)v^3@E-S{slO>e@ALOFP5M&>aYa7#%S!R>4d*tIHWJ$2PEvftzQ zTEQdOPS5x#uPL^V^19+2JU7H+Y=9Xs6E1;EVHQ@dl$JxG=LnN$Et~VzP}EwPuX&hh zJF_U)He=l#cLMQ<@;yhSa$t72uA!)nZ4~pxIPx6hDD@agO!G+6SvL(u?QjG=5-UeW zb!aw%jv`OSSVGmW2DFP}uXnNV0TR*FzBb z>nC3uigJALT`VxpPvU!$+U}CKlPArk21yU!29zO^AK1!fji5#=iMtD2aqZ)Q?SF#? ze9WN%AOAn80iSS;^2w4^8t}hi?lwC{_4NPAxqH?z$}K79j&mX8EdfWMhu9B#;Te~8 z#xC@2b{kuj-MVcBt!#Qv+oCoK_1yCVwj^h*58-dPHhw-cr7JkKHW?bl$5OJZ?H2W1V zqJ`SLJZtt4&o1`cCo9L9;yTjj7Q5YoIshw((s@D|({ryGY1YiAIAh3#N?5BX>$e1L5n z#v*2Oj3=-iXdKj$;^gt7&OUn#@@}??q3(9~nmy}8|L3_ub@s=(nb+ALHoJA^CbK?n zc383n)^xMkd@$HA&77QlBIo2V4cZ6XDe0(vr-U(RIzDh)FP}8K_2P!*r_Bz_rk_p5 zV0eCen-4DQn#FO)aTwOIa#pqE9K+-~W~cf1=NFoHyUQJ0%A+D5J(U(cT4>R)g%&+Q zXwfbKv}oS{87<0@mE;?@+6bBq!MH^$V@rs5#nyu8w`|#Wv1`OG_MrkF-o@VOvx~hW z1H0I6w&5JasFg7$ux)sbHrtTbRbfC)QLJ54xY6TUL67qS)8hhd^x#Nb^4^Ev{(-fB z+<^N4vKp2%GskP+pfJ?F!Q4cIDIA8pBd%f^bL?!;PPi^CJ9_TM_|cKEOx`yNz7G?Y zp5Ah+qmUCP3c0l-gxuPxL2kLNil@Y?7#nz1jMug*+_3pbU^5{wHj}hr<7PAcv)S29 zY%i!g4gW$c%i(L(Lc5LQJJGJgj+_>l0W%aU)>bCSQ%(MpQ^6zC;0r(!r*yIBMQre?6U4gp|iF2-C4hEQ`!UBh;NYh#jCjF z3tUbOfy?PyaN+Eo{c-pCK-j(qRcq^k)s!BA71(ZoOAxO@7}1%smX5%-1V&<83P)pG z1~0|vM&;3%(^L+a8Aq12gc-)&#(RdI3Z-te9wcbpB?PVWw9uO4hF{|Ncfj*GC8pkV z&uewlOUsbjPvvyC=}(In`y}xq=lfVW+HUmNU(lmC1U-VTJZiJf$m{2jSK)lG$zD-& z5Jo(m@`-uEZ9k9XlNFyVa(2Q)fw>-prwWaG6Ws zjhR(LG;?_ITGJrUdk5O& zO=)j;7PRgdg4Q`&Xzj*>rwd$;2!YGUjNx*Iz~v`bY2kiS%+P{Msj16%qaRWVKVVx1 z2A&Wb1bbjR7+PaH6xv~14jr&P4RWzv3NdUOp%~jIp)0meL3eDo!3AUu80Y31u*&!v z+m*&e`39^pdLf^#HeN*Tt1vosm404l{7agw0RNJ;^D_E^3cF_M;p=zn@Lrn7A({xl+rp{M1T{Jn{4duDwyv7pd7D`eTcBBep$YAhu<20JeSLU~H$uA=u7^ z!?2wPbeeNM9Et4$I11ZEzGtR-;YuSfW?%eEC&CWGzZCcG-IY&(4aR@bDTBo@6#pg9 zf<0N1E9}_;A}7>4ACzsL-7&vh7AyO-5q^ldd5W|)!+WZ39PK5&lI7MhNV`FB9JYhu zcx)R@N%oN7=pllmr6l`Sqa?dj;b`*Rg2^$~WvWjoy}{3NNg5U^w_bgi(K^JuUzCr& zC`w?YTMSOZwj4%dyB2U=p@H;TPDJ zK{d9$U<$T-!BlK}LoK#_pdQ=4Fdf@|Faz8Ea0#}1!z^seVK%m-U=Fs^;RP<# z0mgWQf8Y2O#)5N<>qY!`Gsb_9fFpt9z?JP=Ku6o{y(vzq`-f3qz=d9G6vy(C~XDs)U z?{mlreAiwV^L{A19T!gDY)3jt$&xu5%iR%o8n;K<(z-Y|12j%$r92y8bsUU*lYJ{? zOF%1ybyo7q_uHGdEF?NAeW$HFH)ncAEoG zKHGBX=@4?M$XqkYBlEI$ITD{ovC|uhT8h!mPhqk1d0feZsYk+|@qcg+cL?SZ2DRVA`lH_aEbOEGK7S7! zp@e%Rza3gg$u$_B%CVoNckX&xJDktwa6XdzzACNQ1!ytR%A@^M#$ut(Q#5=$#h)^e zBj;VmU?B1j`+}0AGUf9%6zzc=EPb_^MKY@>C^szt?-~YCMi9(fZ76CbWHbAj;j!=H zxvmdD`u8#YZ$E9p(kCd!txauW;ap_edvgDX&SLu6e55

lQ@E+KL5Goe`<|EL^)P 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 z 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�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
0YnEwkq(l<;&vt8amuOGMd=WMEqx#KNH-S#o4%R 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 GBmV`v%>c{* literal 0 HcmV?d00001 diff --git a/packages/language-adapters/grammars/tree-sitter-go.wasm b/packages/language-adapters/grammars/tree-sitter-go.wasm new file mode 100644 index 0000000000000000000000000000000000000000..71a01bd89c77c97c8b1046bacd31dc136bd50f8b GIT binary patch literal 217182 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 E54e{J@c;k- literal 0 HcmV?d00001 diff --git a/packages/language-adapters/grammars/tree-sitter-java.wasm b/packages/language-adapters/grammars/tree-sitter-java.wasm new file mode 100644 index 0000000000000000000000000000000000000000..68a0c1f3b3d348204b0b5bca75788cf342193dbd GIT binary patch literal 414641 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∨VyIle9DfBIW&&Kz*8*G^Jt&N5@z{Of~ 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 X&&jyl6_Bwx>2zGqh|8U-c-;R2#=~E> literal 0 HcmV?d00001 diff --git a/packages/language-adapters/grammars/tree-sitter-rust.wasm b/packages/language-adapters/grammars/tree-sitter-rust.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b7e0c4b3cf90125409e4b61ca08c5548b1e823aa GIT binary patch literal 1102547 zcmeFa51drf|M-8-%v-dUUp6BcJI{*LO zVFPcynKSsWYWm9}-iav3 zE1&3@#nZhvj2xGG{lF0;Zn>U$@y0h~%ndg%hJU8tbnET6jv9FV4a{TQ4jeIR=s^88 z*uVeHH{5*7m^=Cp8hGms-ihLoK>z+@2M!u>L%1we59VQ2F_u&N_rGc6;G4$WaQ)c+ zLv9;+{n(ps8L2=FmGyFir4E+yWCr~fB)OT*#4+u|Le!zGUit1t4Xqf zqehLmqyON6V+Zyha|0M~D@(~93)=U;^`^07Zy3{m%x$-hW&VsHXJ>JLS|BSmEi*kM z^VnAI_cHFEdI|SWJd0_oAA64tgU?0#vW7MHF!*b&F41p_=B-v&>IopuzAW6|;LsCkT^5ur4%m}m6knAH#;o>3# zc7Q}>p+Eo*!FO^#9UMe{@I9ydhG49^szfoE~eLk~@+doSHjrF$RUPpA77 zx}Qb&sdPVA+%v66C*+{_?|&j>!V>!Wt7#$8G7=q@p;nOS=chxVR+4D96s;mrsT8dy z(VH@^wIq67ii$||?Br1N8%VTBiZ+p`NIqChqTi*cghbywIMySUS;L!oc zNw^%Tx~T98%qL7+A$6NfqCX^HDv4f_faxTfJP!dWdTg^uxJf=bmqc&M6qrw<=cH%> ziMHGy(rl6O;Cuv7QC)(<9J*N+ezPL{W@Y%zs_>iD;Wul;Z;HZiHiX}73co21zbOg7 z*%p4YBmAZ`{H84YW*^>w`#+cIdw@irpvbWMAPK*d;mS$$noPMPBswM@_3CMIjD&mT zqsK|~j7)&S1-c@8WT?p`S}a3NB~iI#PAAbjQZ$Q1-%8P36780v`6SvWMGHvur4%h9 z(T`HJghU@n(J~T!FGVXzv{8yylIU|OT1BE_DOydUU!-U)iAtoXh(te2(FPK2kfKc_ z`VB?7RG$}<@DmxXghbnieNnA;y)v}&k zMWTaJiPa=}`N5D9Yf1F1jH`%5?>!z0wSh#-q`x+iXq}9!m_$#@P$eWPmr86S(N`$S zP1QZNgM=$ZtC6M)OG)^-G`);OQ>1SDNL2J_NZkV@`c#Szl4uJ8^yte;^ntYC2#GdH zZyY1h1{v3J5`8Q6DqM)o1C_JMcms9o8X56a5ozfF&q2)Lcd(ev=QaAkh-(-jyW!S}L%LL?20)tTsfl*sUee zgHlvPqNNK$iLil0$E3-dP?STBNU^w~cDIBA@03w)BT=yw?I6)=sc|WZilnHFM6Wy$ z(q$is{*s{%kf=;%n}a0!=st8TX;x0c`6$%0*AWyMJ%(fS{bA|Y<0SfAy1(!#J>$HC zIvG(MBA zkkQLX^uCOK1&L-)4~1GuqQ9kR6^Y)JqSYiiCd1n$A`(4>o;C9M1`_@tHQPj@ zvWG)z6q9I|6qS(ZH<<;tk?1k$#2qA>Ek&gy`a>4VG7>#4qu)oOx25O+i8e~nK@t_o zxXO(OrT34J=rV}I2-$d?L_f$-g^ToDwnm1UOri&+5>rXESlT$9ME6V4EE2sa zADl~~U!`ci5lXhe3rO^)tV0%&=pHFrLZT8G*D?~#lcE(Q`V~9udf{71qB2QbMWUUu z2(Bj42U4__L{H*_x#@arMI`)MHp?4GbX zQ)OW;CDBYNDkITs`QSbht&%1kAkkuBQig8QK@$Ef^)DyULaF}|5~e z(S9i^d|JqOCGv=acAp8Os6^ZIq%# zB>Gv#wS+{E$)s3Dq9>%@D@gQ!tP)m|Xod{6ibOw4y;hUxFD$dhNO&y?Uy!jCk?1q2 z>;@9elA=u{x=)IVN%V&_sf0w!q-NVl^s^N0Akl}i15-+(qtX{;C^9+=`{?^3Y2N`7 zeJ^7IU!`akiT;ts%q7t-8EQU>zMK_OVgZTfOX4CD{UAdvAyFYlZp60Me^!e{i{wN@%HnMCi%xTcb5n#?!TN%Torn@FPn$>`^j=y@5}d=h;m z^TPrXJt7}mWIQOHyo5x%rK-zF^pg~=Akii%T1lc;rDzq3a%dKCHGN+uJ56gzv{QNtt!NKxSuJ!j33qRAxsN9LKSB>Gi0 z?$b&1fUHYrp~x5+%@sE^{+LgJzm?A~AknX~?OsHp-HSps+7c42cq$}XMxwtKhD0k! zbWA?D(uhkwxQaygJQ;d$HHp^95#L%8O_!n~68$Ab8%T6miZ+qxsEodtL~lsFN=UR+ zYQK#{U&{w~kmzwKDkae#DJmn;EE(565`8R*2T1g`40Vu1FUYvcNpwg)c!WeNWvF8$ z`apX1IEl7NPZZ*M5lk>FmT^rc(f{OwQ%SU5Mn9cI-$_+xk!YTLa4w0q$WZf1^q?dz zAkq6We=Z`?uCUsQL~qGZ%SiOR6s;oBFGK8Tuh>wvXLqw(R|ry-bSJ_*>3G1(W7#zqLf50%3)aUWu5uFnE$faWBzjo-;24Qk$qMW^iPp(JU*S?c&payI`N<^uQi`UcD2K)f)5VRk z!a{++l{M#F5DihB#h`4?pNPXIcc|i|6n*uQ#v84%R zJQIP#ia-wt!fJtu_0cxe4JBTU2e@DJ`0JomBKDe9JuC=1)$w{k0v@R2@wAoyAO=1> z%fmg)pW_8r)z2GN$E$hjuz(NZse|6TFdyBa)z1%tnTEmv4}^zD>v#iRzZ7HeydW&~ ziYMU_j~~zsm11=O!8K;MDaYGEM6P?$h?n9LTJs!lkoobUG;#zO1?d7R=YyNzFCSP2 z@p{^N!8S}EkCvMUv6iwt87;=;Ym4CmUL{3@W*)zeU?LTz8mx+6r=??Vz{s;bKEct1 z6ELMoER+OoAUi^S5khSb8xF~teFX&ejn(cg^o{N?CdeU1Qggy+2$JWUsCWdwOUVJ3 z9b#x;n6p58j~4=?jXv$He0b2O<$`;|1Lc5EFvEi$!e5H9;1xcsjt5f0Uk6gm3we}l z=^|VmubzOq)5(=}6h35=Opzy11q{~#jE1-{5%luq0qsIxqNB)GND%ZNeuWtw4GGuT z2z3@13}lZe!QIe{8YrL_s2p8&yk**1knbT+=mCYhHIJ|YGHm!mVHpW^h5Y9?Qq-&G z9}yk+(4>>lfzn!4B3H+D5-M=bE5Lebhk`2740UWYT+6ruDi%y#AA||lOIQKr_ZyZE zP8A_XLk>f)hgpoeL7+y%!CM#>Gj(Pss51PJE5T<>YZ#G3M7-Hv%70K08bUdQr;y_z zj&QLFgWp0Hz@T|hrU@gHjFJeV%o(G72boq;Rj5PioBEM^8bH(HK-%8dQQpU5~b(4bSp%kB38@=+i8%QRUDZOO*GjT)8EZhd;-!*_|LN2J|g?!H;jTxkC9gpU%lcp_5sgs$*P=e*D zP6mWXf&Zt%|I^|BKGgL8{ri6&sMrHgVE_HsJ34Cv6gy8!8thc_2ZC8uva41*srtz^ zPN{intpx)Npz8@BqKNLR?cEO+nhvl;bMx?_o1B~-%Utz@+m?Zwr zgo;_j5qJpiI|T0mycdE#7-{;V&qAheM$_9ww_F$var*Q)0GERZx()Y4aH>c3z`s0j zKT%T+hcDV1PEFNXBQ+KMof__MgPH==X~Hl;rCWu1zd{AK2mXOgnwZMzA?WAf&~)9@ zbcCiygQf!X0STpB1v*8A-scJYO;G3ojLr3eBNlB7hx)WeogfeR5b6^>TFP05rD*`g zyh{G1TLpTb3Z3i;9FK&~`XVl9IzSq29$0U=wB-IPaZfF2`!I+T3A{Qpimzg zP`Xue&M_YNEs|37wQ5@Riv4*KP@n=dD0Hh({@{V~NJ@DG#iCxW4wSzng>Dtf?>z8p zB&BS(YKsNsWS~I(XV^lw3gsvd{1Qni`9`JWRP3=DK!N(tpwO*CIl==!M^YA*sg#OR zKX{0X=!3thx#}WYX|1?U0sz&ZKB?|GmbK6`F{aK9lwHxI-hgPFMCCp@q>Qo%)g zLT=cI?yV?iL8tRfP!P(qp&;EVZup4@_K6TMhgyc{3-g0}dEgr%I}`IAbi=U|zK`#S z_}3Eu+W~p(YshS#w)hX8uRlC1wVd-^;$Nt%eldJ=S$=RQhv^bf3i2WJ!r>1nq1q1o z0}2rYf$5oVd7#wzyNqj7F^fVr)4%+NYtv8w`2z%?>Ta&RiULSVt)4Mv5PCEoo|XP1 zFXQmPGM-w-ePYyb7>Wrz)0iGP7e4g_X_6l-<$>)G&G~vX5Py^5St8Y=8u9O^T21~<_EB$glkRV+phrGEHpiH6sKoO zIp?p5aZd*b<=37@ol&*spfgU|K$x8{RQ&`-hdTLBi0>1wHG*)Enh@qMh9j0X`n}d# zJSS#u;Jf$Oa4i)Ebzkxv-2vaCpd02^-B$hK%iv+Shw)+5r?*EuU2J&gZ-G7?p2nnT z5%u9OA|3|Ed?EDK9~K6KKx-NG>1`2DZ{~q*5cqL$Q;wMN^K^oQ$kC01X~5t|Jn%UL zctQ^Vvwgv>#@FLVYmM@Qn|J_@xoM!Z9zkX&_%!_VnGu%!^r1*atth%*U`(xebt4ZL zX$WyfropEXp+De(Ph;A>B_i+!kqKkC_>+jh@AJSX5c8!`O)QQGyk2B!?UJa0KaL3e z9uIsBF~1kxA285X{81!Ii1uVCvBG_wBj#eqK!T|cy~_h10pfj`fSZgE{YQ(0s?{yH zjt4ejZEIAHx&E9?jgQNP0q?NfG|fA9SZ+o=j}Imq-xKlVq;|>iAr$KF*nUg*|7oLX6Y+MHOj?MAI{(K0Ug^M9$ zXr`rHR`rW;x}hk>OpDQQZv+pDs65c-1wVlKYB}c;+@Q9wkeqJ|=*kFa;l5D&BA_iR zp5yosnHxpf6YZ>Vudv@&*^oQd2=>d7?C(@|tBTp1ko|#V8}|x(y~>8n_LgA36v^JN zvSADsZC1L)KjlxzJZ9Eil2arNGDCek~O~?(%DC@bO>2mJT0x z`n3%BxWlhy!pC^O=7*2l{V*Z#$0ZRl^DS0{cpYr5Tjd3p@xVfeH~`^p!*BspxbUpM z8kV`RLDyu~e@SQtPX^6Tu7u2v4}>-DZ^6{!Gvc4#%0OI~<&6n0;DN=U#xw9h;7xE% zwCErxb}4iXva();2~71L$N!#&Xs}P9bKx26QoIP0ntIqb!zcB2VoJO&QUbac3wdCE zH1sYA1@S-;3XTdafatTpStC)$ER)F)4w~ghxb_=H{R#xG0)a3M1h-7*(1CzZ%S5QAF+x4awcjz+ zbD(ZBaKs>VM6;-Y^MZ4D-~kBN9KsF2aLuEIgYGhf`57YxALvPRAJ_gs0cMvL@N{2% zx<$07FU9W6F$}v%JbWBl^?SMY3re1Xr(43)*ZQ@K;o};Nq*c^N@`Ht3`yW07IS4{s z5+l?^?N1E!1Vr2#V(f*@W?JBCKXjE$%J2X=$ z@8;Jw;AdCA_5prg>DQosPYZNG@J6xd9$6DW>fEaRgXEb)y(po?*Git6$=Q9Nr|4-y zmeHUBPYZPNYfzb{1v>gQsMyj1`3U{U4AmxwDhEsv$f6H&b`Qi-j#^BEKVS_ZEzkiU z-yG%fUm;jXo7V971Ds9tYxiLWp9)XI7&a|%xnC>B&vt(86a3ULwolEmfd;T*IW{oV zua#i9%P?F?jBt=09z@E$B0GTRhG^6AevjHUt-v181~DkVPSB13z&&x!>e;V z!4Z(-F;}MrF7j*t;%5_l_Fwa}qQ68nxLCsVao$f1hnnOC$3c`wAkw8zsA{5K!nJr0q`216?D(v4LW z7#0|7*Hl;p>MKlz@z_|x{igy`Z&gV*1#b0gkD{_;Vi3cu{e?l}CI+9vR9Lmry}SqN z8y{3JA&bE)eZecR(sUjO$BIJl1rq4@E4TydB3vSaI~;9{CXFy{x&?0xjE%M$GsiC8#iLH0Q=+dBNVw(C8LY zRv#JN5V*x=l%qKBO`7Bdp~?)if23mnV7=XrmiI83!qvQm^IoAiq5iEni``5Z%H!7u zZuV=197Prge9{Z>dB9r z+q73O(+-6!)ggEV#se)VL<4`}PBXu@48Oj?uPwpP!7-zS@M01OCJ1pw*FRkI!r-4{ ztev2N5YYi_sU92L=Hv(S{n~SQe|?Nt@nNwu2Z9FjFwg^Li=u;}Ou)0)D7**+k&$zt z;qVR;=?wEh?X;H>JuqghhELlE+QtkM)8zKpte^+MV=Z;#gT8>ei#P9$QKrZ$K|Hwq{5h2jC?b3xy>l{hQc(s2-&BD4a?*3shUY>AV(^<9G5GD0V~l&dV8p0Td(+ZyCS6971&#grkl`4SMbUNmAX1Ur8WqEIij+DFQxkfN zUI>_=as}}z*D0i2C+yKyq#QJ4pxrvm$vqR*u4jDObqs0O5&PK{Y4@$r?k&`=N21#G zh)=uxkaqdl`>#m5y+XTpP`j%V)$XeJw95-=mxp7LinJ438?|>)yY7i<*F8S%I)t?A zfFq@fv^yw#w+6NAmZ)~!;?u5uNW1npeyd13=}i8|YlIb};6Glzkhu>zt@|o#WH)vXFL{;RHiW-zC^`b&5}$HX&`=;55e! z>@30dex}Wd=qb^n0gk;o1uqn8>!Y$f_*EY@aY<2g5^cquNP4JdBzhJ13F)GyB$|X9YIM;>MqExGzK(H6+nu+{vJeE->Pfq6Q>d|7|GL`9>%ys&B-FYdLyc=ZTp=FODkT z!@ketSJ5HMzG1s|t~oE)g(*KnW< zgA$zT^9HKZ^fZh+U_#0ps3wY*7h=(u&a?e6)B|}HzqS}Zv-}z^Fa(0Y?SP|FT=>PK zOLgE>3T&Pn4FMNnfONl>10QLAZ6V&K`n6NxBSrs!O~6n}z@PXP=q;XXC2_|2hKfSUrK64=MR45;snA^9M2#$ zxWM8Jf^zzx?{%j02e*uJ^aR3FHqRiu7WXLx{V>I+yo7(oxAM>VHvR?Q&cB2mNIPM( z%~!A`=WD*3e*;^4zU6!PUcQfi&kt~8$0@Y2V{=nrLSxaRaJ&F(#Jpfba6N37N`Vj9 zQqFTy^ur2R@;FoiVrdt5q@{{wbC}bC?QO7kN~;cEgA59<2UhuDM^HIGEdDXrYO0-F zN9<+PY8atJxPuTbO%Dg54s-aQUps|@)`ZVrpz;-wVqSxYf5lxnB36CJ)B%`}E$2|l z>9N<+AJI;O&!0uTt&h5DhwlFe5B$ub{uJ8=p}v<&qcYxu{8#Xgm?b*~L17XX*mj}3t<^GKe&VA3LmE(ZkVrNQya`i8vFk+T|ecx>c?@P z8$5-QEnM4z64=oO67(Z%UHcRzJB0+}DdxBa$Z0p*FCh7t@KZg6! zc3?Pt3m@z@+`u*1ydd^>K~zoigYR?fOo=UAAUFtdujjZ)(%3ABr<>p7u>1#-PlT#Y-S9`KuENcW#r#w8kKwkkZ!j3_wSve2zm98VD9|??0{$Hic^Cw+RSH6& zW7l#xYz-3F7p3imqm_a8#8>6;)f$cxj(dM_5#ASgSA2!Z4;xJO;a9Ld24WFWL20Xn zdqSXWr@%mj%C;YdLeTS}SdYM?tGKowA1xA*?H7a8@1+2PyvDTyDA9SCAztO$4=7nD z9>OrMaP3Ewyc3eFY{r(BJ7B^gIu&60u;SJjZc4m7!+XnMI2aq9D}cf;D5s(O3qse zdrEDt^TB*%>f9QU{2vR%ZJ&%>cf{Ko)=D{Wlt zaM6pw6JirG$K5QT1(vzTISylZNYVV@V`5)24?HWv?1eD%IWF$-z!D+BM1GXx3JwoE zBP5sv^EfWkh<#HKGnQ}Ib_8<~Jn%HA0ULd!me}*~Jk1$Ir_I6;`c4+ir?C5IHcDV8 z3&eu)&fzeR0TSF61{+p z;uY)+y%z z4~Z~XG7344{J4nsJ0!!-7I+-3o`7q=oCqkm8^@7i;}L|w%zT&j6bfM52?#L#{)+=o zIFBg==+ry4r%^Bkw1pbT7no>7J|4%iJTMu)fO6!6ZGF(}of@sw=!+n*LyptV6Kp{5 z#wA#eTTiea^Wi=~D1|=U5CTdFzPS1Y4%)s@3` zLb|^N*LXR^2kKlHO&yH%Htl%~bSFN9j=34vHMtJO+I$4AYjW6!NZ$|FV4{G-hD0pX zzQ8C$eiJUpa@-dp(t4=&65hhjhFk~*E9rINV+2ki_yWT*4A$I(ajll?aiE8<$H@Q= zTLy6JolmS?i=-ZiYuOxQITOS~@Nq0F{c-0%*Q3Kc(ociwRt}r*;CsBkPFscdunSL5 z(Y|=xh3nB`x%m&Cjp2bC@%x|P{#u-f=McZv5HS4>aUX3piU<2)gS-zH>veDU(qOrW z>@PNZ{)7PrRv0)0e#?9;bgREw56xb?iZ z2CF_Cced#!cf%Dl9uWIi5YiRbT{x}{p9gXFG<55t6`>dy&=UJ#(TH^Fti6YFSa>}d z#NzM?I-(<7md_7%&^DkPR;y})7^aw^*7w0=E_{te zsGar!eho_=um>79jp;hK)i$CSX7iy!^WknV-C=FC4^a-$)CTe8D8_QvTHAzTv9$nG z`4a6Tycf}-vaPhuc%LUKcppr7;x;~C02biu!N;W-4OSt|wU04aJG{rj(o8GHdkyc= zb4|5R@V>2af04EY@5S;ye&0m<6z|*M_xs?!u~vfjm-?~O<_k0z6JI{qt)*3k+os|) ziw`$qLHEpu8?kgX&euM}$6ENYiuMH>p&aw(dD>Q#!)7nhB-YbD$J?gHW9Mqy@E)Rr zHp>@ifTK`f;Cwt@;tSNrP?+V;(!Rh@7vepZpImJ_-Z%7X&}s6)%p%Eiv@cQKz=-`! zZ3o_;kN4>EGqjy}FXBZPpRVn~dzh(&md1zEhtM*_u~uX;B)AsQ?;)!+}U_! z#uqpP-@gN&r~7d;tS?a8kKF@b;4}=5C7`-iiowO>h&f678t>1<@8J|hHElQELNw47 z^5Lcky?x5ozCn3yyhqnn(aP{%M2i_DOZyh@Yx%L$=ff=z(AD$d)FbrpZ~_y1Xud!; zK95>wXnQa`Oj$yA*#}dQActN_nzk3kCmF#~wS9OG(VPOIU`|r^u}}LB#W0Zxy>4G1 z1Lck3g+khX6vKRG4Undx^k*1sLE`}(F%*A~UuXKYli+KwU#kTlFjEO586V8UVow|< zJYgPKsR;ZU9>jw=&okj!cqkV>;Grh)0nZdc9}1uGhGsWm^o%%vP72JN`u+1uG|tXq ze)y@X6m}!yYzn&xuG87MJ`Zcf+whNl)!1D2DD$xtmdesu71o$FW6fC$)|qu@1#BWK zWRut&)+$(^<*+&|7h2fMQZjm{&D+61dJco&xNQX2RvgJlWLbYJDM zPT;SepjmJ5RqJ3~8(KxvXAEdGPH1HK=VW#|_^PwwrR#hgJTeomh3ql7&Sg!~Ik4LX zIfjMn9Cj5*4zmStZN}$jaki7~fa_j18|*><*C)Fk@_8ZkC$dSbeGn!HfPOpc2!H9R z(pam9^1&@E9y_`SJ9-H_h6y{C#kAvm zlO5edb`(UlqpQh|9xmC@N7yk)*fCDnac@jJ8kp?p8?s|SR6DLU+0ic!JN!zH8Ui}{ z*f6*@VPCLt=J{3J>&^21zlJ- zC~t#3i$;~OEzoCE@rLSrK}CRjJ0JNYsW5U9aui=$gW^ms(V7&=>z#MplH^c zb9jEN&}^L0Y&=|hvpeB>H(Lvuoy{jf&OVJdB>lz&t3=gL*A8_X6|5armSgGGKBQe2 z(hs$Z=C^Q<6$(wm{dOVgHNlqO?n>Bi(KM?#MH`W3lWl1>DPhgjI=(Sc-%iPZRPaLH z$P}$j0qX_z);lTnY}6@w-Ps>%b8KS^Zm&WG}#V4*NHQvm$mdle43&)X&)- zRtx$lhgoCM6W<_u;%&&f$DnuTfj&+idlvrEYp&-*J-(TNRQ3V;ij}f&*a7wfdkRv( zy3eiV>dS~!k`c|1TQi*Yqgvm;0v>6`UK2iQOPaiFD<8cWJUy(R7GE!NJoGEVN0#BW zZFtVsNTWAxY4o~7IlCQE7y6^6$RfYfDPqqTmy=d++w#R*3H!pHHtk89cWr6&PQu!# zx%EBBr@h#I7*#K49jI@T$Nz#?UHhOOz_|z<@pp#u-Wx{Eb6BHbu8s1jj`eQ}^-%8! z&4W~K-IGVYjaK7q2-Qc4)jg^|H;d9=EJ}YqQ8(F2(Tz!!ezgYdNaR78(aPK4OsC76 zO7BGUAEVL_I!;$pV5>-hZ6XCalO`p$QeaC`DWGbxOK4Flw77z_*kMbH?MZ3jT)Dc# zMw{M+EQ?mIb|+b`QkC{>A9yl@T}iw>Fz2Dq;;Lh(UZMHhvZO~(D*s2p?@Igwmi+xm z^VKrdjmVpW*~)B>J|BzoQF6Yg7})CEZS>hF^NbJH@;K|0uJ~S`hdL;7ba&F@mtbmW zhItgs;*N>X3&*pnR()U|>J*_@YRvhuNR3nkWr>xILmnYCd z;cWeAhO^PKg;Lo)i2Zwo>?5wQdlLJV2p>mF``40Ad$qTs&+i?Bv`=S$!nJ^X1S6z0 zUO+m%mSQ#g_)1FRvyW;TTuscaHvF(HX+Nm!Uc}yIgI(${yEn1_sW9&ycO~!jA+{&0 zqB6&_;_nq&m$_?*9Z1KO7@Rr9GLB>6EXT*fYHD9gXRIExlb~d$dgPqPj=bn+lV~PM4s+4c^r{vn8>qSCf`ovIVSR4m&xOaJkLa)?=l(p zoZw!Q)GVvnQeT#{drj^na;7CY-C^>7i9F6UXE5IJIfDQ@3D&cs&6VnV_VgLk0IYuB z&7OpPeP{Et;qTMVDJJq%m&x}Kd76nl-DUD5BF`|9 zXSqzim&kKWvU{21cB>wL zkjTqTYElb;~+k0$a#m&pr=+&Lp)+Nau!cB*#Ch<{H)w4JJIU+fIg7kiTU_I86f z*B4tz++R!{FL&AFPZ9Z$iG0Lm@**PtZXzFZnfx@7|1^=0yG&k8~Pg!?7N&PugkvXsc@Sd!~HOn#2YsU~ly zyX@^{M9wsk11^)FCvujFob57sIgzWG$kkmYzd+;~CUQ-e$t#Fl%S5j2GWkU!pJ5{B zxJ-VD$hjtRU6;u(6Zsqyxt`19l|-&@A~$fE{0fm9n#he@CcjGLCMI%Im&vaYxw(nl z(q-~0BDXS;Tf0ntoycuWJKkRKHH?$--NSJKQiPeg7-upf{`8k$d52wBd&`EFobhm!4yAh0b zIco~neyllM2eJVW@@w{Q8lLff7vAo3lm+3OSZDquT(`4-;e^P#C}+Q)4SK{ID%O&< zx4}tMJR>@a$&=qz(!FrZjxo^%(pr&Zz;y*?@;{qPKY=+E?-C7VWylr!sVR% zE|EKDSdA3BWH>ugEF$t4lg(pYw)s6Gk28_SyG&kB>Uy!wO1ko|eczf%wDaHt*jja)c+6rx_m@iAU+MS@KM($4V$9UhTy}hbm z5_y{`1-Cn%f~w6sh+O&av)D=G9VVN1xoq<;BJVbl%UmXZMdUpu@;;Zzr9|FuA|G&> z{56q(G?5RwOx{i8Urgk3m&xA{d4lQ0N1@9nKFWxE$Yk>omu>!*$iJJ&$6O}wA@ZLl z@^Qz>>N}qFQyx2@B|DApB`vyI&f|5-3ZHk1{gyv-+ktQ9QS0x0ME%EPJIi!;wf;LI zdooR{^)8e56S-+H_THZ+3A_s>+TI`4+usv8)ns$J%Qhb%a;AwKaGV_N&GoaPpVpYY z0M|nH8eHeHzA)2!J?jpAGw9{P753`G72eDOZ~r{ZszGnC8NUD|J6RjJ?qx5g>hIyd z7G{F+{ntN`MbD=i@8jcMoNH z5_zjXvQ%#KyIUXpOyo06Hs?5QvpVyCt;l`95dRU&b7l`add}=u;^vy{uIsYheTCiS zm1eipqqZbs+q}Eom{xvd!-&+I(kDHXb2r zeUt4C9JgKd`cWb`G?5#*O#Yq7O-$sbE|dQt^3e3i8g*E@yEW=DB9AnYN4ZS?ACa4z zyxr1eZ~sZ;Rwi<5m&tz-xs8e3)@AZ>BDXV<+q+Euo5*=4az~fR{}6eIi9FP0^1nnL zW+IPpnaoo36JJ9tTZ_R7@AQbi%a{{+m?e2=!enEQiM`Q7cQJa<#||MZ4UTWb^9lvBj4uWBi4A!lpL3EN*Z}6_FVrGG1q^mNVmJ->SKj)EnxV&RQ=dw zxDI5~;5vt00sW+->>9X!%^rs99%Z-C#Sms4>j&4vY!qDgvT<!bK=;=gU__qQCKJE=2oFLK%LrJ{tLO#CI5C2X;yC9DQ<7n|%};q8wK zUmH_P*r`NbYV!Cp$33o+YZ<;akykiQR_6v^g0vpT-iMJx6@D6NG12n(5$;Y&bUhG% zt3$QDHc@+-(z}n#>3uqpuQieTx=cQU$o)*@0WOozG`wxfX?+~eX=*y>7~VFK`?^f7 zV|d#{9^f)Lm&j90yDFx-ysP3YB4?*Z&H-0TcXtlBE|II7$TeIhpH1YNCUPy8$>$Kc zwuyX(%j9#3T-QWC$7OOoA`dW;2f0i>kH~{fl1m5i9FV2^7%xbU?LZ~Om0Br z%J@A{wZ*uA$S;}d?UgRq+YO2Qs%77IWx}&J#_Y3d^MwZ4Wb-PQZEi&5H%#Q!E|VJ* zd5wv@)@5=NBCj)%i(DpOMCA1*@&=d5O^LkGMBd~$S)E5%Eyk72i2sIV*;?i3xUxBM zH=FD(cG>QA!tNHtUu$Xink4O3y^gRle-i7922>o%jBzw zT;D`);4--fksF%Gja(-8BytlIxv9(K0wOmzkz2YoR!&kvCb+hHXrEe&5)Wtj z$WqlM)7?@vh{(m3Hg8VY=ICo0*Asc9DV;~ToX&%ZJjO&G>oWNUB6l^Vb9a~1c?glm znQR{KvduRV`A!r0E|2MiTsAi=G89SJf6sFOyspLlkXt%Iup6bW%8Xw9%D-9u`Z|ce~G-_Wb+1> zZN7`h<4iV>ciHB}QXc?yx|naJ~9Cf`rw zA5G+gE|aGcxwGl4LKm0MDm*~st|oGKm&wzJ{J4p{z-97-L_T67|L!t*I+2f=$bY&_ zeu&7&P2_)ECeI);OOLF#J?ZY&+cSymGm%qWCeI>rx`~|WGI=(UH=63OO)l4AbBMgz zL@suj{4kNXn8+oLlcT-m}(&!rxWc({OFh^xyV+4*nj<^k4Y;7k;;^h#iFYE*)j1@Rpf9QGUJaF|zF0pcmfn zGl<<1_N!ep1F7&Hp08Lb{BG9)_5*t=Xy>=P)O`9l#b0WfX1g4nn|y+}WtQCCj&c_e zcb_G9kE7ftiF?43yWdgnLgF5@R+ zZDMI}BS-Chow&^{xlJAAzCqkpmfV((a^EEGmzMpIFC6W2t|o39OM6>8YVTXb{l?PX zuN}2_4RMcJj%EHxax7!j7kQgBX=hPWw{@&9vX+S7Tl)MvM}7VdaeuPp{@^Hg9dQp^ za({D_`z~>VmcM}LPj#}cE+X!mmU;WFB=fe~Cca19Jj*(yy`y!=dg6Arz@&KtYsRENiq%8I&>>>$6Ip8Im-Q< zxOZ7{?{t*AjktxD+zF0yzaZ{pOYS5`x!Z}GV%gvII@;g;lDIEemZRq#Ek`?uJJr(9 zQylg4PU23tByCpf ztWx5BYB`qrEXlEyx;8adtWAxBYXSS3bgFIjR|ILh5e+*d8R zD;?#2N8HLD%k3xb8;CT?sr`_()DJmG{L1Wy{7lRu%QRl+Xd3?#hpkS|CI3p?%Kl}ga^ik$ zS%yDyv<&}7+zpoLyWY|CJw)7-E!TBVadchxFmX3o+Pl$Fdyf#e*pj>1QSMRVmRNGP zILiH1ZiCb#P-Q_6vAL5o-a(6q*{g=4=EV+9e<+4=$*R>B=a`!vR z<-~o@vK+nZXgTr__n@V{KRRl!m$;Q(etpC(x3u>cN9|1^?h#AwAxF8X#64!o{oPS+ z8gZYn%+HTGnxE5&Th($dzKWxB@fpPZ+j742-z4Wt)p^=X;$~Rdo93v!e&T**nZ7$6 zP2T`<-?8Mr?I<@$+~bzz=ubz>Q5JE3wY2wVNA0abTsSyT!AXH`a8}?SNA1lfuFsO| z$#!zQUzND&mfTcFxz&gpu;gYs$~}p=*_Pa_B)RGwR<&$g*{M!+JFS1>D?2J#UsF1n z$nLHw`IWN@`kI!$2jfmy*@Ar+!V7ER7k?e8gb~Q@4iU4z560FiZ-$II3*4} zYKmPTcJ;v1K_@Gkn9nEaXEIvtWoX}au$_mfNLRp4X$%pcgT5A8pS!lK5(7G zvf$+QVO9;^RnUxI0Fs@o4P5uK7eS}V>^@eDbbCJ4%N}JD*(BC0%gbi6S!^~Nn&D&3 zc?;f>U(9=CRcAS@4$Ea{vAXPRb`Cq2)nn(e`s{qxfL*{EvI|)wIs;zAfjpu6x1}xr zo>rlMcU8et_jt+?*X=R=n`dW6%^UW7tb2C^c#*R)!pB8$M*c8+0X!Yu$F)s99u?Kc zBjfOKJi1O7y3P^0`bBR$qn{=HORo5AD=&IJ*Z6Hkx*crrWot+`-oGMWFHG|rr zGrXf<4r`TN$3||uhV_LUHvryPFo+Fix3E!cG#ktAfOOIGZ)NAhGb_x818nC*bv%$m zv0e_j7We2$PvP4p<}l3>U#VyDjzOE2&i)j8Hab9hHDez^%a+FLkS=yw`I@5CrP|&r z6S=1_msp)**q!f)-Kww8BIcDbm{&N$j8=B9gEz}GW;5Yh$R301T-GEV%Sj(d1I`A) zbq*T`lEds?xHjW+p)~JgJK(yP&GzYad0o=}A)ir~4}kY_=w+czx~$9l1?|`6@#xw` z=-Nx@I!x%gET*n!n{+LRs%sCIbZski?JRV?O6a;Ermp9hbnO^b*St7%RqMoVP{w@h zT;gDzXfEf@)QM_8wuj&rh!Wllu8`m0I-cDPy@~y7K3uo5dZg6^cz;W@6XxydjCmJ0 zjozKz1wM$qkGKQ%)UYSlhgEj{d>&a6z3&_C>Nj=vQ%QunQG>)Q88olwuc-u!} z`efPiQTSLsQnw~ibW2IvPgUdAOP^z?3%jc-Dwh|Tv<;t2$gOg+jeKU5&1wniNb?{T znl`o2w0fAP(ckN0=&9DdR(YO9Dn&Q%i3n~|lvrAe2%ReVX-fljo)k$M_)hC^Y_5X=9?CcVSceMq+5_P4V8 ztF0>3dxGu$s(Kzme^=Nr$bAJgs=tId_D1zM2NBN<^0m=Lpb&v(`i(6U>e} zzR=q=99#5Zqk^Z1n$G^Lf;z9Ek90-?H=T_V9{3W*IBERSI6M&VNlCQ_r1!b?QPvot zLHJm!4e2q{RzLTlIQqHjc(WSJ8>F+#h_*Sx^EeL|{`N5ReQ{7<8?bvq6h@LT-x~hz zvdtpRi{V`YlxYzSZsAvIX;5>ir~H`xEgU^w#9uhDef-8Efw5$#NAI)`<6T&a4h@T}ePtiRt@O;`P`gZeCCdt%$GNpM!)eo2nZPx>01zV6n6xOUb6 z<6q-a{hLRutu{){wqWx9)$8lAqOQn~%fIo~)T*5wiS>#NJ6}u4PPJ|huNfzb`KQOl z{8J~=<851I=dC#EMAhET#Mx!T-clFsy@K?3*OtBS#9^=622>YqK$o~uIsP_4Wu76J zSH|V(_?hrB#i7h*~#M$<#wi@TDdJxmjd8&B(bEhi3n%lk5e@t)|PG8*~2Q|BgjfX4Dp2M{# z`wy(vU(I8UYVM?+5IxDp=(E|e*0>}6g}t$YIJ}i?>v=V?DkmR?zaOO+k?r&m;>{Ck zOVXQ2ZuP5GS|6g>Yp3Hc*)^iP)`2C}nDC5l%{~@Xy zHIQmwUn1H0T??Z(8fzpK`37hl#i_LGh*sb7ZAJzao zo{}_4l%&a~k~Be-q}QQkU8npWN3@bOfb2=UB&n_X6wqcIYXonYs=^0S+!HN#G2fjM zZ*8hl^*NiVz%F2eh-zni880=m93$^~;@K(1@wbd>PvXX;dlGsdVj6hL!=}TvC(F0h zlNd}^#@CZjwSUne?Pmz>X9?{`+0y=ogtS*vdk5@pI*kvZn7UflHeIrkP3_)cZ*hyY z3NsJ9(3H)GYjgHETwAaOaBayJ!u4Xd1g?2(Ib6H5V`2M_=Rp4uchD|^PuxMf3_fuO z?F#BQ-bhx?4eg*^8n%OWag4o@YHB;H{q{JtAL@YiHv-RigI@B!FN2gko3DqS%xT=p z_cxtz+8>HT`(X}fAO7~j}`iuz8`+VX@5x^+K)&`d$pF+=Spv;nCy&$;;-dY z;!99F6|j*+w9{(GPmHHmwG#B<>{Ym`b13GcG7OrXuYbr`u_zXb!h-JT+4KQW^#*!_G zmoRnAdK<-O=S|Fd{bP50Y<|<_gU~KBQgN)i4&fxBEojSyFNDaUG;kcNVM7 zETX>R?PN{#zT%+lAgth}M?Fi^8&>whSAW+7uYirG`0Tt#E#6#eZj1kv`Y}KDe6QN%5Ch=8!E}@%li`_x~l*cuUf_IP;=;Ug$1jHMC?kh?9l+ zUbX9PV$HK;&5e^~wrc{hhFP+P#>q0LW4(Tz zOhh~HF-)#*xsOP8e#tc1HgyWI?7Uq*S=Rl;vhxP+WLZ;*W#^45@w1%Rt=JMuZXT^o zTCGPuK-S3q_$HWP!c(_Bl{4D0RwmW5GmT<9$Fl6yO`z=9+jVO0D}>L#8M{j(YZYU@ z?Lo3Y)-K`mY(wBJ4YB%8xL3P3%;AOipX`hbBQ=?B(x7e?bvJ%Ib(>n>=)XDf5E1Om zCB$3b*xU7QP9tO2f222zbeUoDN_e{DR;gNH|4vUEC-RSRYABYTGb_~dA#Rm_)UiUv zr-jU34A1HI#tO44)c0y`f2^=sj1^{6e0F|^Gv2(V`X*M{(%(zrgm30l=$jgGkE0%@ z`0TvPHeTPj6V7;?tE?FmAlJNcdvDy!NCvak= zrd6%+NQEhwTP0i68nMsb^tO50HI{ziYd-eM<2=%MR~4_&tv8F_62)5aQS-sO4$bqG zh0S4u}+>P-iOi0ObdwQMmwYC#U0?|0`?^F z?5u{wTX)-Q*YwkJ71uQO>X?P5R0{7)^{cR5Q_sc3YJ;CL5h^+v98X@bcOrN`q*-&* zJn5n+T1B1+jz^bjQTEvF0y1Z%a7|~s;hMq9;97<4gKJN=AFc)LN4U;m9`XL6X;4>u z!aBfA`d-!pt~=S&q~!q^hv{zt`OEKPTiBLWZQoWh&nb~O!2yNibiEUL#$UV zYowKNjstO?O0BzNor91bDeM=KLRZ+TyO)rC@%44=jqNKg;rjj&d*%FD(sDq8 zeF?Q5EC>Hw&6ZM}Z&;@6s<_)4HC_GiKAq(DXzOkAA(5_=ZKdmT38ky*rz5~CV9O{b zH`3W{m1rI*&kUFPiNCHr-$)qLZNCa)ZiYrfH*zRuO5FOj|-6U_Ve z`gVOGo%2}5THCAhUnYHJ4?MhYcWs4zJGCDBN94Vg6yJKwyjK)=-cxz3D%P8?5YLT% zy}h((>R4L5T47o=sW2_nwJ{I)2F~xpHJb(C+KpwwwGZ=E)pw0%!YA$;eT|5zRgL$o zMq3-J4)t%QtzQg2#o<|{Y|uJ`RfB8KnD5UrPD-sJTjJ|usT!XNdwVh*7}r+^jXjnc zzn+lBYR~x%io;He81Fb!CA~=`JHHN`9BDO?j#<_rzsFsNs5ZStBsY3pDrt?2BsCA$ zsnk6DHrW+lsZ)Kkmg2DU&idqX);mP9^Q#)kk=7B(&hLfAOH$MOBG~8d#9U+zTea-F z4y1Px#bM|7+~f6)nzP;`lAT|0PmZ*nNOpe1JYJHzhuGY8y{*3OVYk2|e(1=wtV0 z;p4AZt9EKS7gKC^S>~ua z>Q|M&rtuKZ60Jh4chahPt%TyLZJF0<#huqw(q}|+e`K%knn}#}4Iu@(o5t0K=Nmx^ z;9jDw6{f(|JP+91o9Q0{%s4N zIFHj2KCz^CflthD+ezc5p?RIWuoB;{YV==5QS;iD6h}YHyw*4Fyrz!8)I*tLOoh2k6V z?635wIbt`F23guPAW56PA(H#M_REOm{;bxwL>gl0y}?O(Zx4~&*bAxVh`mIz^Gm|< z=Dn&GJ3#ckAK|+`xp|N7kdU_acC`IyO1p}7wBZUHj{c+XEH-}k5PNp^_Ot1I$;kZmQxu&d_p{m8L|t)= zRT?67I2c6-^JzT$TG%^36J8o4HTpSKM2od+*nY~{tK0QGwXwXU zkJs$g?Z2692v5;|71ZtaG}Ye@;Dn}!D%5mP1)ADBt8doPNM~bod)TCbdRE_lDyy?? zvFa?dM&aXe<3wPjmPT1UV$wD|Wrt+rY+LkJ8%u({)OBJG`Y7os=b#Icn1lYEVk@;= zv)`5En*AR{DzhZ*PLgztNS!T5Hyx84-TaS8<(4-6lB7+45~;eSP1TaL=`SL=F$%TU zzpc0&htI3+vN>)zPBz6iZg6@Hr5B6|Q&=CkTJMVbn>3EEN3M>D|Dib2Eq`-9H9OuB zu}b=vNcAmqXT2nICri`Min;NQ8mH6yT1aUR>kC)wH8W0jC6nGBiX+D|70yU96}&`h zV@YbAB*{mlO_rpMNs>~CwA_-kEN+t1_1*-V^*FlnjD^=VEb(wCO+ zQ2!$Ccc`oNUUedUZ%O(tNz%zg`pJ^?Lz1K#L^^Cq`YlP)DMSid<_Le>Il}24p?8#w({Lq^(*GYEc}oTGk>fldMHfBhp^W-1%+X zxzp(sz_l?uDNsA16j0}_^ffRy_vD;TT1MZ~rmv0J+2wKu#q&SQ6#OIZ6jXENnM8We zlJstpq#Pn;Sk`1||K~MX4Ka%`0In&PHCY|9E54dcO@&;F{1tCc}}XYbUN!C3TM@N{$2e#N>`bc(hzXipP$O)i!u;d@#mcdnitMIZB;oIP#S zH90%l=sRqUHLpnBjJ=)bm~;%^RjaSb#n#ZgCTCwWeebW8e&<@~hih_~F;<+-YjUx) zGrUvJM5|~`F1BC7*Sgg1>=FKHsE)c}>nLO z#zgwulJr@Uq$WiA%96A*Nzz3`3Run?WhOaq)RagEEyrO$COHmkMx?haz4vC4-fK>z z4=hRVCrN5Sq+cybKgUgSy7c2Zf}PUel59$*^j}PIykVKERwbFMS`q1E%M|!1?i5gK z`b&tEVmV^-#yw(FNv() zR@^qJWiqjTklxQ73}d`JIxCcE8tWN-BI9gYTe3-xN5lI@gKV7@(kPC%E&cM&|G8iE zJ>u4WY3G1nE~hyDw#=D-C7CnZ6X~dB3j7gw3aB+m2O_;=Y17+r+vIc^(D(INr*&RJ zY3;PO`f9wjw)qKZo1wg$DOUZ`k>ajvan2*R3huhJH^Ni%PbVUr?z3uv&h#bM0(BM9kR^g{$>0v@Q;4e0HV2*XYWG zG*)wZSBj&nWlyzB+&xu$scB~iIAWR055=9!)l}$3q~n&PKjS7@oek|x?0`j|Aw90Mp=#PEUna&t4d-EF;cC5$ zwogK7uWEc=rPe#wIH2+6mHH;RYaP%y`CKthaj62#xi02#u$Jt{H49T&>3s15OByrwJcV zx8>u34rqKqrM4i064F>*y^U2LS3C|e-d`4L+;Kf=7Ja;-zrW1xiOPz9A+KUR?Vao$ zT%or5yS}1ptM(rf^JRO;oq05xn*o2Pv#%i+S&!*%s8H)zZ;Vp+J;c&jf0vjOz8zAb zmijxxqWjjKruw_YoY3^f3N_W=85UhrH5Xh}sdd0m(mI)$rN))2@l6hB94p`2p9|Cb zWV4{WS@+3?IiPW~O7-z@2Q-f5$e(Td2zfbZQ@lU*Z zw8)nK9#6=BPS>OBL09WK|A`Yq*A2G(x*#E46U~?3nDXV5Cv3jlXe+H3CgeY-^W`Sc z)q3yVQwiy+?$?QRS}g}OP=6Ow|3%EfAkSl);cEVE#+uOo#&c`NIoM*j$G3beB0b|f z2b*Y~G|vt^eZuC+E#OD%`e*S8md-}{7EpQ{>HJJW>FjjbDY50#B?mJb6x_w%CLg>2BmS0~vA#~ku%dfAV5V{_)rR!@agswl@(sk7d zq3c0g`StaLbd9zaT)PTqW7sc1Ppw@AEDKC zLaQ5M`0A}n*NRocJl0ca)gy*hYbsqUkI-s>&}vc)t=_J5t$aeO!9uI4F|=A+=~|@< zt%eA#rp3_e9S5~iS6$ap%$e1^tTWV8b69${({0o**RZ}&GYt@R(%Zm5yf6D6nl13u?M595;sZ5+Pk_)qgrsC!}2n)-Y$WZTEXUudV7bc!`~xq zYJxVpFKSe)Zo`v${T>hdQsAlV^_9l{%4GNZmB!Y+y---M`+P&CvAdXj{z0X&hnm{TEOaxy5(+Y1rD?DT_>A~nj5NB z&WNK{iAL3V=LmKKLH*H0{g|lrL)3b4P}MfzO)svs6jO|Ed82bIy)-j`Gn&6BaV1dm3VeQuJW_epocXBzi*-V zwg;<%UcQiKS)^G{I9b()4TRqOI5wWCF>Mkt6;n)~QcN3d#iafcMk7cEA8P{Fbk-EE ze%2hW%~(sgUddX)wL5DA*8I7qnNf*OfTAsN&P((-B#VQc3_{6wHLPPRyKwfcq{vy;-3@@ zhUK5|RKgTeHQWrk`N4DB=-G`yFZg#L_^&va6-w<4@H6H@TlJ6=WL%+7k)!ez8F;Vv_C9Yhu429-zZ;Y6icxUzWT1& z@G_rgD)Zk`ybo3A*DRO=;ZX9z+luSpeSnSGOt==Z$KX1bT?Oy2OlKW|!Py${{b_u* z&%-9O``8|$3{Um4N7+O+iGAbuvKG80znEVGIr?nglsD(9k8NYtUFu>upV$7$_n5*ob`h12-XL#H?wQuI+FE;>n*GwTt~41 za2?GC!F4Pvg8Fqk3&N)o3UYV?aoHR zwSXNEEz<~Unf6l*gQK=gsy(CrKi0kjOv+;Ex@OsB6FDall_Vk}l0-yBTv#OUl0mX4 zNhE`01rbDYMlup4DM_**83iRu6cI@xK@brU|1(uRL-$V2hWq{Zc}{!TI#pfWU0vO8 zzhR)?gu0+?M%_?0ryeNZqFyN5Qy-Kas4vQn)E{Lh8i?{88jP|teSq>^8j7+TUAEfO z*lEv2GGO`}&ymQF6Khbl0nq>9IFnE)&KQ8gZ1WG+SJaz$MtP0 z`*y`>O-_byuKq;U|IO%+PlmqxMMrynUg44TUJoCntH$EEL}zC5Z2fL*t^5CA>zc8( z`u~Hi>&DimL~Xe%>ssCu4d;=+;rGS6*9eR#Z(jB8S=@|#(`fw@X2)T|eC*XrxWo7u zwT99kM!y_>!$tPf%`lVR!VKzwnbQd~rZZ-W_q@hk=VS+J?>%ML`3bkhx6{03tm`{X zEl=1PVze?NZX1iOaitNi&WH@oY%2yEWs=w_OVp0#{us}7+B->KTmCdP_eG8m!+IB& zU?lDs`J(RRlXfkqOCdx^F89Ng*rNyayX39cYDH~;{9F&W4QyyFw=A}my z>|7^Uadg+{kK;X6a^vW4qgB+I^L8B7<=txFu6cu1_dR1}T@rP>Vn42 zrlSm}nE|8I7kkPOj7Bl^o;N@GM(ZEri91{Fo4;;I#%ysl|23MqlF>h|<^!X-A{m-) zTx_v=_CI4~QxZMv)=d#1RL)bulRX(R>1uk6=H3*0EwMP8M=HcvNh%iIUsmjkc6&!O zxifbzn4vU3AU1rlFdebs{Y{}%#v8Y#q2{k|{f{kO!1abDv!&Wzpf$HNaEG*rExS9U z)TW+<`vA91;f6I2@8vyQOYGUKuO<;jZ$%3AB8}b&ydRm8`l5{9nH1_p8@<9Q^fQgo zdnL)$&h5{%M(;uj{Y+={)}>8Zzoa*Mn^LHk!RUpiuwOD7y=*De%VhLYqd!wJ?wO5V zj^vb4C?@^;yDTR9Zj9%Up>OE%k z(xq@NJ#O@dr?9>!jNbSZ>g6|jxo*X77-wWz4kUWzLX$=(U?umoN;Zs5BrPaDlm zsgkdGfHjL5%^wogbWZ|gXJnrm`Ob@;G1m0+BDc+7pv`ruxY3xN&gZ#%CSRYgv0crT ztof|boRb30)vQ^n)?&g z40o>2w?H$LeCMNOd=}D%VaM)$qAd=0Uk>A6-jiwX9hZ1q1==UKCvdG$i?(5h9|}oX zqklAQC?eXc-wSu{Qv0>N_iJ4Jy{x~(=s$1tcUt=2CaV7h>+d%D<&6GPOMhje`n$RP zzSG?o{Q7qLS32!?uMy?c#doDs-sl(06qR5`%e_6f?K`+`->LkI{9Z(pV~3F?$PWZoR&*1L`C_1%ql$><+-#{861udDCtt(T3a+}HAs^=_OBdGE=_ zk=tjkzOUw2{55;;^Lh2R`Sla4-xsYFjlSFu^XhN$>n9eo2RUZ8n3#FhZ{=ak9!?N5 zX`PstbCCnwi$9=@phGB2(Gir@=@`mdbP{E}x$k=%HF?LPlBuZ}yo|zpYK0T|%s6|B zz`2t5THBsiz2IYgIt?rR=q#kUJX7%HlmeatI3dpMdCgc#copjQvoEq@3|sD}di!aI zzn|Rra_@2nyU+U*yo#ouQO1}SzKy#P2dN64OW01{6QOiCEBytnjzuI?HnqEbcpp#J z)}sd~>(j5W{MeoNN_V4Q5jHLXrJ-Nxg1^QDpz@L;@y%ogj>;EUKe+IEyEx>A&iN3(N zllwM*!BT6QWyM`}Vw(<^!`;N&DE3avmdi00yD9W(L9_s0x=uqUn%2}9o*~7IK%ujEIL7+_s%kJ zmUqv#0%w>+bSii}mR`f$it$K9%iM}L_J8ruE!SRuWF+5nF7|yUdG;d=R%1x=!28Gs z7pShW=RL1a$C<$Ghe&8dQ#AKqJ;M#ptUVFq`Vp*MX}Mj}qJ~z^sBdgH^ta3PBP08f znf+*Bxat27eq?1o0{ge2v0Vdqt0i}7?aB^q59LG|Nx4zhqDN51(W58_n2dNA{Tt(H zWb8$tT@jv0Pn5@Pm$c{!=tWaw!+lI`mv$d0@HAArKib6D_1+DV`=hQ8vb)=9V!f$h zf2+j0>qD@WrvO^h!mK&+oY5P`W?%n~uS);ZoITLR+EaC zQqc6p%UecAix+qN#sBA_8%=K;tukuAyLz&Uh+exy_1t#9m1s_uyQq?r+Z(H`F;65L zH-L}!${%dby%5lc9gHoz50hu>#Q<9!|7Tk-1=#AO*mC<>t`?V?eDsdtul%3$(JKKy zbXI&wUf;YLVC&ug+16_Twz?>`+`f@3`J<+9x*Gl|rEj#H5tzFw!w26UzBjMOnRyT2 z%~+o1UkBa(NqnDS$8>kAO}?0R+a&W!b{ahlTi;{2dXm9qKK3+v$(hG8|E0cOiPo3A zK8)o)4BSifHn!{f_cU(a?PKJNg63WKN>SFx*HN1<=e=hvXgSZVtFK|s4qBHxz8@qz zXZ16d2U|HSGUzo+b$IWgY1Y+Bf1_VBv-`|e^7=k7er2CLz*v14zgl0`w)%3Q(a`!b zExiV>-*z&w>~Q0_J#|q=Qhk(o-kxpBZs0!8sPnjfUPE7^M~~4UQ;Rz~gUw$XXVy=o zT=x5h9iA-q2Zr4=S?nQ(-7Hz`p@!WeS?muDyH&E-!wkDkve+LPcH1EA;7`cDjq!>g z`#HSf#@0BTuE~ji;B!nP45xjN`rHxw*swb$i#^h?-$@qx6T^NtS?p1U-8EV4(T3eU zS?n=}-7{J2v4-6{S?qC!{az5ZdoQFD=2|amgj2Y9>WA?yMWOhu7l)fv2jC^%k6`5%j9YjAJqshj$+lndXucLyr!d*2a zCk9@bjN$qvC(3p4RAaZ6_w5G0E>51MaRHX51z2)hFx|-i4RYG=vOhKK2|?QH#+i(o zJdG(&ILUKJGmMplapu-F)38p5=~>^cs{!tu_M*Lf|8x?1p%lG`r|&P&tRQtIFEXZZ ze@;W`i;PH)j15*~%r-T+-p?_A{WM5Vx$L=yJu?V9d80o&VD#r1yAR{Yt#`hW&ka(q z%l^!;=LcaY&&ve?UM@(&%Y{Z>CP=-mmx~O0QL@;J4g2$Cu|GHLrO9G1G3@2ZVlOr9 zVE5hJc(-%7%rME}%Z!zTbIaAXXNzddY*`*e+s($op4GI^AB9_jlwj)=cbG3wY!$o>j(5!ajEE zT5VWsgVg1+*BJJ?Anf4zO7_^Yo^9Z{wF#v!UuEHZRma+6uQfHf_hIE!;VUE4P7{Lf z5x1be7S0}Vov|~{I?;6d*4{tJ?y?O$JxJ?){ea!2_gPc#eSroEPD8h%z7YBbWdz;D zJ%Hu3!DuBM5%;P_>f8Z6-_BuU5IwhVnk-9=4sw{b0X$Bt?XZ8r9k*H2pvds8C)Bt7&4Y7L<$QR{NNcO}nqC+sJ8 zY~`-7+z*yJ!G~ZYo_zO!w;C%C?*Y60EV=0j>qu7G7Np*A<*xBD==Gz^*q7z|WrpYlu0umeyeex6ls1 zt;DZ{#k@~LBc_?>c_8FOW2gZ$KJIDNn z`rI7#t+8Y0sO0s-@0Ra@{qS9i`r*1|E3hB-8(YcC2?zWwvU6wh+H}+MBd|^1r>IT0 zEL(wX`XNPaI%wFdojm964aQ+srz86f2-zXX-9F!Qet+UB(fd@-A!E_aS+XO#3(w=t zmBV4fOa5H3SK@n#_Q4Tj+l}uB(DBakRQ$e8HP8Kk`K{%IU7Qn+8H=7Q33Gz0lPZh1 z4$=8BsE*se!LD2FE7s%2*261};Bja7QyBd5<>M2P*Y-$wgYQ3}jG!FIxT~omuN5tMo&S*6`O`_ZDQ!TT z&M0ki`^4T8|A{yXr*XIo;(dy#HJ)MezSZWN2S54S5^Sxq*UGDyP!#pv5an3SP7xD zJjT!S7}w%4ZpvePUTurL9%YBV8@IpuTjG0$uM2wKzPoAb=M2!lkfeTY=!8-}l&R?n zlo3=NXIt}V56U@|H;cCi!%^o&lYw6G1h2nfK>e4L`rRBWJCVZB459qIAGvIF66V<8 z^%e=J_li=ln^)zo;BSVf-3@eeWM*Ck5D(pqB0GC&Ur~4%O~p`Fr3bi^vz*#- zd<@5(!|fEs@$tK{>RNdN5riij!KiPp6^e6Tl|UImX|VS!;5i6eTWBjrEVt*H-%7BV zY-d`@)`2 zt=K&x`sG-^Jj%M%l&u`Gto)HoD;3zv%WS18TZzIL`Fi)3-%7CFwezHXf3q@r#CMf( z+i%70-C+Gvkv(dRYuW;yV^)j)Op%pJY^5z*Ic{0GlOiiIY^4iZIcZt>%UE&ejNE;d zXOr$4Mxg}vEZu0AtJAY6E?UcTW)9+P3;k`Zx_gr<@Dei(Wh7NYS&M3* zjH6m8yHg#MedwOi>=zwEMLkb@qJv&N+VjO8(fRPecYXGcv6gZxB`hoVjTQG4=wI{K z`{t>xbk?<<%Y2Y*=6{JW-TYi1z15r=qU=VWqW_N)Mao{ZswX~6sCjR(bAo4X0%N%e zEQHV-C?jYc@_YeLUY=K*Ics?$Wd(j1DUAn@)bXBBz=N1jxrg|r_=cIza3@4X8dZjV>xZ%k$>~|y0R~>hWiwXX6(+m+>*y?jPZ$T!-7-(d zay*RZczA}R>VXwiIs9HHr|r49?VY&olMq$gX#uxAr)niI^GbwHWRJe#*nHNC&0NMx z@}g=otVGgOlyQ{XXuhPbBlb)a52mvRGf>v0OYFyf?h~0KdDPYfTA9UG=CGB2*~<5p zl}A)7fqf#QG>>g{;qeKxa!1}2S^12u{L9a*WwWe2s#>vIBwj3J{l(m(&)An}%St}g zO0X6!VOwX}N+!$7W5$X*%FDnGr4=Z{=u4ETX%)%{Dvlm~#giXVHpg5cKW_BhY;NBx z_zIdav?fak;vcjn%kI;9k$3!cz(n=Buh3p_iUsMP@lbKcmJAv>rA*_|=8{ ziTG@LyBQX|*X&-Ob6Y+aNT&YRtY4ekJk8QCX!PAZ;`_KZ_C0;$d+w%?VLp8BCRjg* zJN^7D*ICf2vv4wf-Ugq;s08a5vh<%!fqpnW$NGgW{UUz-z_%IOVh4z~oxrY7+fl#o zoyPMV`P+DJ`;^gl$2-^>wUc|ksL|PGR;MWCp4e_MJ+v2PL;4nFciNA#4}Fi)=f~42 zs{0@`BdJ(G-F8NnbCAPehSE`#sp&_Q;dBCJ1f4<|L;KMmH|QB-M;muLR?k2u%*1MW ztKW;KKtJ5*zi8<{n@s()R{a$${SqnA_tpQBrT?7Kck_dsH=akG(R2aj!@c)8%yI9% zh>}U_T~hT*89jGyN`0VCj=znY+K_w1OmdcXc!$#4>0 zeY@Nca6R;z;U;`y-<<;RW42e$?I%PilLg8(ND@SimzFF`U~I zZ}i-y`pb5Y<}7KL^gHQ_j%Z1qt+qwn@nF|e_NG_r(! zl)RWL4jYlwz}QG`%z6C`r)KQuXO^E0liAJ^Tx(<2_gMOklBr*k^(E%3So)2Vsb3oU zzI;*I(r;q)-F_|$wuhP;S;Br!DwfJY+qbW_W9f|)`0C3oFIc`dQ}yMIyX33|&Heg; z*C+N|D9`@?7cduE7=5>|Du7*=S{m8E6((PndDGZ&>xe-ean#n_(RkfcDXZLPkHPhv z%am^ty=AQI%M`|MlX$;=(<%Womi>O)Fy|!j+s+$-CwsN9ds$B9aZ0hB1|mkb;6Aao z(htYln2w5KuM$nKqrOC zvx~ZL-*#3t1M95Mb-u=R&f_}YO{Qi;)~w8$3s|#DGBq2sW;NDa$eLaKnt@So&vS|W zJJ9s4cHR7%cJ$dj)RcQD2Xt0a4UEbzYRx^=-DtY&q+MGxXtp9*RcD9cIVVp6PY<=e zzbdtD%XZNd6$2RJ)Oax_A;7oZfb)X;%EWZr`J8b4WpGc$6a== zblzv9>QXa273lp%sJ3R+@1uGZ*q(OWo?*CRTu$%un7x-w%?_;Di+f@PYxYg1W+&Es zk2Sww&3?($?97@Y+1swH**_6Ydk%MD&2Bu0tFY#PL^SPO(~ULfa-DrybD*ke>qwSc z%sLsNvz^9qtPD~$WmIf$dvKj?+1qto=U}7hj=uaxMK7>p=zYT&pU(GHiFoX;?Aa4o zPam$QEZ38fJ^VoR(9Yd`p%Y8}QO40kZrdc3ah@TnW?-EIxz0XZ=bPNNp=#S?jh1H! zKQs(`jn>*`kHKKBrx8b4O|EB{-^0YS(Mev3?QHasU(@bS88I2_54g6WC}SucdU87* zjs+xh`e!|{P<1y^Y?ffK}nxk2>2WvLrc8)TdZoalpsmDU670Jo;uO7+Q zqm7n3ALK0$-}@b74Cmqd9c~@L&K|}ZJ>M0Hc52|BH2SW!#u?3|HO8AfJw6eQOV}#~ zUe8T18tz`tm;WakX)a^|`DKo}NoIkGJSJOtOzQDyPEzZb3|?KDY-Fnv*(KWZQ0B)# zo`y9Bi#8XIlBnrwgt^Kd^=~mzRLHL=NaB6#{+zE z4O!Uz4yV0`yAqJ2=Nmij7}!~F9{MnrK0}G8r_hJnDHLU#=QE?}wq+sn+VVbZfnjVn z?*V$RwcK1X$vVMV49!*~cMeM9w@SSG%Y~|Ufp66nKy0k0cAU-oaW-G1Y6eEg64V+( zM|hqL-PE3(s@snz58{SE&V0W!ml*kl=Rm+_WfJ- zeJuOF%2?6nk-fIcmDhDXb&wTywb9f(EXXr^O)@>S$7KV1c#_AZ1CPsEzlV0r+4~#0 zZh8bdt7$*ah@w0rzEU*SeQzBZa}FSLbsIJ-5oVyofg3NkBJm}^_#_^dH| zrfsTMf!S&+kADVUGxM`o-x$q^pkJ=~20E=s&fmtHz2;1$+5>hh?L!$y)xfUq@xBw~{jT#aqvei|J?~`qHIHkWgYnr; zIe27utD1qHe#f4^&ieJ)(>+Gh9a+g>@^&=(rjCJM-5NjFI;}<7n*hx+GY?#a0RAw+Q-yeW}TI<*By)sxQ*F z!LEl7s5*8%hq#_*Rz2Sv9d~Cd_qmUOot~aY-yEPLm94~{>YQesHkQs2qvMX%qlj;9Ow%g0Hds6i!(Epp3|EH3vbHUO% zZFJn&y9|HA=qk!M+Ju#%rpNp1g5K5gjN!X^;3k;ybPHtz`pGb^XZ7xSyw4N5TzTKw zXYWsw-Om~=Hx7O_f4!SXKc>Ols89D$w}}*AU09+rH3j z-tkL~GLC+6#_y8RcH1X?7y&+hHSjO`vSpN!mp4ev z;FatjM#t@wTjsA7oNo`fc5PpBu`d}dUv8_u%*V42Whf7`^P-HVd?;h+ag;siPt}(@ z=CApAe7xWM@P6^b_4hBsDd=!qf8|~N!l=nZMNkfKzM_9ut^05D*FVq?5BC9XTuMGD z28-!wE#mS370o7V?LF1zKjyE+6Nxw3$J=|Bq1HbBzOmr8&mNBw@Fs-LSmW_;k~$?> zr?aK=K=uDW^Vdq8SAFB*_DN%&tEFKvj-Eu0eYgftl-%ic$IoN_TGr_kcRtAqQ4Tia zDa7y}t`n}kR7PIjvFFY?->*i58t(7@Zzl%t*9zQ68>~JGGum$ZUj{FXDsubVI=L#f z;k$JNj`#D{c!#TX$S=6a?3Ukd@%?5?gj$DvC0Yrd#ZV`V%r5!?&kAj!NL9z)zr=9c zhgkcJs6=!mM^#~+t5$zS8y$CSr>FPc>Gx&9s+d3CXN1$J_GRsmRYQKuM!qWj7uJsL zl-B6D@sQ5^wYn1zE+@U=9L1jB`&%Am5NE9t?D^Lre}z#^v?`ivqr^!K$~d}+F>d6^ zU@W+?5d3+ojE3*Vf<2Gxa{r~p^{6k$XHx5sDEJOu)bdotTD6_(qYu4b5X-FAA!~L+ zSoct4l(E#5+fe})PEr=5;8`4-YkS$4_7OXSH(#dXg z+%d~x{#w`>GnbRoaPBxcJb0hC;=2Fg^DS9dbE$RbHh+EK*me7?Dr|+*bo@Sz_v+gl z-`=ymJVw*?p$*sD7A1at0A(3!k1~cjqU=GBs5*8(zXM(f-Lm>DuhDViu`cK4cfpRM z5l(J;)bQQ@%V+-D)tNi4?}7PiJNCG~XW<`H?LKb)+C34wcK+$f?b~YQpC^n3*B9x# z-e8B(dnlu+AGdW1+Sv1;2`GEeQ>sp29PG8?ps3Mt*J0o9eLZcY$ytXdu~*Mpv0lt*yYo->3{$|4 zr)Lb~;hw=AFNvFJZ241^(KHif49!N_gNhq%SH~W&xvZHHv&(m;@vN#7?AoU!-eWsR zC5(<6pY}be;+)^-oBaME~m8NEOIz*f5{-1ss;|-? zpQHEUX(>wIFTRvbguNc8Zlh^A*vPMl;S2P<%C_%YoU`s&l=HI#&(P&7j9+PNC+5L(1DwSvlC z3q~ldLz$X3pp2lh$Qn23C6z66R3bO8waa`tNp=fsF2AC(We#nE4`H+gWgN}ntXolK z+n(gJJbBfy-MPFK_6E`GIFWwC^9`bZ9KBDKRJ(!w@htbpYbx80k&9N0#HehE)*bK# zduNoR@jHdy_^X^ub}eRCNrWv{_izpJUTkbK*)kKV8n&Bd_i^uiXZr2+DEYd{8y+`G zzXvOV4x(&9hf%&sM^SdAYN`kJ_?586ue!>X`6Bngsvt|Qq@Q`d)KJ;>s9d#1rKZZZ z=gW`qIE1e8J&Rg?w)|43J%42eEM(hq_olXCyK#2{_6E@`C+_O_?FQzLQ{XqGGbnw} z(Z~7Of%VJ%gGls*Z`Fub*>+!#w)(oRpB?DQS@z@{dm?X#)H7_ig>r@Bp5fQ`+qHeR z`}sWVhR{sTOAQR$jX7aAG_ngg`_g`8?h@<_qLxnoHd1T1@4XK|1TCizIf5FiY`e!Q zSUuLn&kpRdE8JsOxyR(4&Zd60-4C|yY?kdeRJLTrYp@zdH&DjWyYRcQrntgK(^$}HxpsYx@zalw#j5m&V0+y4wfh8Sb5@YKiiH8 zxyLP8ZU~}tHBIH{Y^SpA-9shbJrv`N)m~-W^NzB6=iO~)cQ9;sw5127WxJ5^y{lBm zMC=A${d7{<5}6^WKb%5Q;=USM*u?XW%C3lKz(Pr`Jks&Ger@=?i#n@5r-r>j)Xm8P z?;55%KO(@4rY=S{KeI2Z1dq8WX!v5Tt6F;+uHD^RbTdrNuIyIRLCd#W?Vbo*B0mFr zAuD>1WU^%pd#Y@SiA=B>Mp;nCk@qjPJ-rfPXJd8_X8(YlS*)kG%9it?T;O>q56W07 zgRwhFeN?vnn+otiPQ-k#qJtG+w&eUoHI^Zrxb!sw^6CGsWm|p1315~!1m-2GYNEREI2wSdDWc+0;2N|{-)A?X8o(3D)Q;2E#6(243B-h!|^nM~9 z*lh9O1C?!$%4WWXm3|(QBwKh>u@5NV8LG17Zh*wAeNW&+mHjySB9!u@Oicw*M$k=O zfrhDU85Nn2g~9gC$B$IDopoz+*6ql7bhw`#EdM`l<^K_etz})A-$k-Z*8MmUri_M< zInwWey{6c^;7ja*JaP9)lI#N(dz9*h?E2iN(nqUyrH}1cmR62Y+4fph6eEH&N$%sZ zDqGf+V&H{Qag=e?lCK!YCBiPj?2^oG&Ft|i+g^cg@##t)c(RKosBGKs(y$#uRe5ha zQDxhaw2vccJ+JnY4BMUGWnr%;O*XP}*;COdtjS{%?CI<|_?ML#rx-mq-pa#f!adzo z)z=DO;;Tz2TTn%mZ&D?cU1^%iwqx#$6-Cokw)9%y{jN_FVN2h|z=sez%ds&d5q1^k zRYe&?)ll}JnTGB5M-9jl_Qx#MZeWJF&lzU6%C<-PB9HWJ_IZxVmbI`Je8KksP>!ZL ze9kjh^*LVgd7jFYlQs7&Z+7+C{E<{Q+K-bwJ>O(XVmp0hh! zsMcPD+uVe$zJanAJq@i3v?!VEP-ZVy+4lU9Rc8UOI-jd-iOlBkA&gq0jH9E-6}3G} z3_HyEGDvGM($Z2RdlUVT4)^mjK-d0$$Xm=>W?1d~EO(u@&-yw*!$T*qqF$ios-Je2 z%D}soa-5}BsBCFfCs+-k&M5I*BFY~0g<-pAwqKgR{+`PF#BsWu;oX zeFZ)x)O!W~31_`kD%;Me-Pq%MJabkXwi}5(z=)$iaJ}O7bB#HnYLeiD%JyIpdoY$g zSgU$q?_+zzzHcA3@YZ-i8Nz>TJ4XVA3 z=CA#-2OA^%%5oL#t)^LQZKGsD%a1O4cqPY0qB)z+G1o6uclnqAh6=;Yr`s& zjQy!xbICqotLmpcnN-aFvi{r2pc z{1G^5X@`-G2r`rHXZKdXM?9N`mEr>J^xL#|Ya?MZj&^5|2;OBPxNd?7wr9m?XoS!w zywBKeY`UXq_fiSYc9Qw_sO+(@7fRz%rlyG~BWNsE@Ef#OW!ttlS$qC{hVAyP#FdPw z?}^866Jg5!*2nx#^+0BdytQ!yYwKz{!jZjSW!stZ5zdscoGA~eY`b+^tk!*R*lvXT z=Kf?e_kU1rN*~BIl|;C-@}Qp`?D}B=@1*3M`H*3|{W}%oHHfAKS37oX_63W5Ol8ZiUGA~lch`SZ*>*;fUXzS;TxHw)&uiBH z^MuNl*)$715=L`S#!*FH6FS2_A7{|Rkj_S`8YcBade(BY&YKI zivK4gdn`yswMS*06~kv$oAc2Ac>3AM{`Ei4=4O<@95I)3#5tqqvTY9zTXFGAlI$NX z_IZ^paUs7zWdBO;uZHdRn6&PKkp)|W?Ckm(`XhuM;p}=*^+2A55gq%9m`f^Kc!AGH zUsnBHh}wJ76(d`WS(?-}U!;}ae^Wh>9+PVUS&8l-(zer8KRa0dnQG;q-~H@h8K98m z$u*U2@2r-frM{ij^(5KLEcOkRE&FHrm2Qa+`7OnpDqBWn1+3y*#wg=xHZnl0=MR-_ zpH+%&`Tf^hD%+mZ(LAS1@tnTxX9wOxS_K~((i)WgNWMe$r(wJKUd~_Kx6kkR?b;(F zSxdg%&~B_<{af|mE3_tp)}w4e8&SSVn^AV9 zd#VRAQ~&W<@_XR=`86!W)BPk^vhVxXu(tX4eQuVLdGQ*a&TK()7AVhzKJZyrzG|`^ z^@q?-lrgj$We@t#ur)sk-?J{~so;5-RkhK~gl8llet*GZbX;EpuMV&B)nSOA9c&IS zvgU9qKiiI!y=X@SeT%XM?ML}0eUGv$g{o{jx67{bD9`&aKRcKwGb~S1``NZ9GAj?F z_7FOZGKP+#>_OowTlNz_f)Pe1P{z>#%;CnK2$e0iWmcR5JA{^Uj*m2Kcl^$Pfj3i( z>?|TkPB>haT;W6;*27VD$4>k_2aDl!p8YI@nb^dW#^|{*A>S6c0N%r2kWH)lD7B|E zvT*;5acj5ReF;|aOewcJy-!bxa_OZj%udhj3@Y2cu0GG#)t5QPWK`MW$yHblqiZPR zs0i4xo=hs+&NaVVxhAt=yCWfaA&ZeEXPv*nt-FuRyoIu=9!P$8F(5x=Q`vvOUMSs0 znVRmPjG&F!l`o|1D%&2FyX?uw+|M~ww%yP7xSvDV@0=>zUJ3ib`%)w;VJ?+z&*#n7 z?kl&-w*9`xem`JO@~CX-LCLN6!S>x}c|>K~o@}u^$*ZyhzyJ6bGU5$-RAsk-ER64U zrgPo~%crt!zaLnBKc=$nT@B@UxT|?QNp^_EenMs2eR9v*%jZv$T?_H#yLv02vhAp9 z0Ncyy6&}liD%|Shv`VP#z>6 zDmj<$xn$yaE^XLuf5`Qa`&@Jx)vo;>XIVtP?>w)p%ASO^%J-x~R-F6!-e-6|Np^ON zUCyxG=zPKawF15m6pecg-jhnVRhbY6gYbl_{k&^=wPySJpe|n@^y0PqMZmDKw3qo!CY$n~}3zIaXL6=q%$ z=Cx;DjLMTX76mVailL05$|_GHyEyYUaeP-%c`~vkn0JV0K&;9u2}UH9Mu}fLhJTek zRaM^HRNnr*i#O8aXcr=@uIF{bbNjcN`D@u6zWZQq|6atiU9nV->x;seRrgd^>$7>C z;a7D}4V5SBS9xyd2;LRd^z#C*u;mH;%h=WD^3?M40;7vyt(xa)z%*P7EWzo z#Wx?Csl0wzv0|w$^FBoX#(A12$@`mmEmU4<&U0_Gy)~GJO*}1Cp8Uo_d*+2er>Uov z$}7wEI$HKxtGqlopNOP)EPHKKo{Yu2;Dyi*9*Z|sp8YOiF8EN>(>6(-ymR=L%9Anc z%Jp_f8AETYJUMaf$?d3wdh2-FsXRGr>}~PdtGtUmf8JwWTiC1Y>5wFEB*wS0r=!Y~ zQ>%Wk7fSYLF||0+0JTxk|*8=FNF4To_JTSuZ#I> z#~}5Iogr-Jd$!ZnXt?wKBQT=rL$j85Q|sz({`zi^x@4?Ja9tx&#!wH{PEYgK?m_Ha z=CKfhtex zoyok}T<;*2w~zDtTrhk&bg;^kdgrsfU7SC!*j=L zsQK&X*vn|&6dJ<0eJR%`Ir~GS;l{k2{Vhk#d!G#%rurn;MDk5DxhDEZ<$ZzLB55Vp zSseMMhG)3SYlUl+Fj~z#$*&_+-Dn=XtW8Ig;Z>s&#Gz!$X@< zcBijV_MuNyp2Yb!FhVE`pE-<5gtwh}Ihi+FZG*(yPSd|*60xW{?P8SaC(c`Rop!aK{n_RO25^3H(~M(4TS;~1k@&uo=fgZuOX z^Q2Gbs66rS64%?6>z$hj?+Wv}GjE>ClbF29ylW_9XujdO{rj2u>kZ_!aWn{T!@B(| ze*M9A#&UfN)cS;Xn|W7xy;`X9 zKdmqtuHV87V_rw*eWCIK-@5wJ@La!En!kqU^j(X)@>NFuj^A%rzS_vU29d8Z@<`a1 z_0iQ|Yvj>E;5{U;qv55I_beHW4@=eUgc#31HX)fGLCLy z{#N#EPhRsGp!{`#ra?}29}kD{i2B;P*&My*f2p|k@lTs+CsB-_>cc9_4;^w;P1 z&rTzs8$`a#$QK2X?>6$!gUI(7`BJ}J>)*%F-Vk~MWjO6M8m^!F%wLxWu_Jc{3cx}v zWye|1N&41kxb+F65O{G^6l+B-&vzhs|G~ z_s!C-c|;Qt8i858{1n9rpb<_#WputJY`pWFPyp z;ko@94@;3$kL{f^{aPhKzsh}G`M#&*;a}7`8?vp&Z0lL{e-+Ppm1oTKfrhT*t*BRyX$bYs8e+V!UD(;w!qtAqGt+i8z+tn9g^ z*4G0y#ZoV>?+DM`+bU1aAo_q8LI?T2z@I9wCy!5GwkP9r$MD>KmpR_wT*T45xd>mOIw}n7=;!c9tu@Z{%x( z^t(KDd6(BfdEWA0)#nlLA(}oivG73U$T`eN!}-r}Tz?3^#O*yvTj%#j>*rCh;k`HD zF>IGJ2EIhnIF#P&9qGTO3Ht9{9@mM?2}eA|c~Ti$Zv5Ij8UIj~CwXBq>|r(Lybz}P zHXV#;nriwWwQ8$7`!<7plRCpy-YhU8X%6$MqYd>v5r*gXX{7n<=`i2h>280`g9ZFn z4%>+`{Z&0dfBnhl*^3Ovdp|JR?^9rme-2(hlHajNJejA< znU|N(3ey>$+lEeHl%X$B#v#wkm^VsrotVLBuJT_GxnnIpt>L=*vrid~hTET+%wHcq z?dSUP6)cpci5b1$9j;HARe$Bz9(=!9mBnyee)h6<=WiNjyHMmZZVsPbwd2jLf_!HdINpx%3EoS`5_KKR= zt(72l??M_$_n5N?bvE@pZEU&mR?PhMzCYgFIsO0^LJ5yUVC+LsM$j{=@AEQx>k9=V zjxM0S8lK`R?=)sfB&BAa>^q-Ll6M96s(4Bmp6mZ}=C2XCd}mCq|52zZl+vI~P3cfZ zP)W5uIa|vBMhNBOGtE+dUf}wX3A}!|e)m2nQd;$^jQMM0e~xnfE^FjXgUFvZ@+|&# zx%%adyjc+a7mU1B5P5kcZxclRqLH@^BClZN+5G;wF)Fz(M=rUhe95rgvB`yA#8-e& zHln;J2hhug=eG3~^VfVq>XNnUan$9#e^ybo@v8Z2{vb9AqW)Maj53ZYnK@NQea_7H z9_MRnJu&95Px{4EG~E7s8lJ?^GiZ}{A6dn4Tw8(PeT!9jl2>wJ z#ls$i&z-8Oyl9*$htnUHZ?CJoTfEnLmitPc9jK=A7Vunuj(PIzP<53jdA<~QxGF>$ zPBm1Xd4R4Jq=Z!@`+-GPZGSFAa}v z6O||9Ru??qcr;acKca8Ls6Mwt&I8|2c~Wmft~Y|~ZKm?1Uioc8*^4w+d5vKylA3b8 z_0fOzJuOt8)Z2{f{hH4KTBYr}JMZX5I0HbL^3*lBCo zdDCdPbL?#}BB?#fIBIM1YUKob6=`E9aAIgR_w8G%tuD;yZ076RhU4Z$@v9q{zV@|K zdB-_7^)P;U&uiMNJegm;zzd-$#OQMBpz`{F;i0}LyHkIZeW;_#leP{7BZmIw@$6)H zZvVey{_6d1hJ3NjZRZyF5>DS+^QE&|Ur|2$AB_6qNY4J>Re5!IZ~OuCWN+L>?R+ghOk^M4QyKET%Dou3UDQ`)h>gi?qo2yC z#cOySl%uJ?VYpuUzWO#m)t?I69-5AFG!0Z4Gng@p8G}@YJb@U6$cv`ID#Ly&{2Wgnf5F3-( z#z!hccDnL=5X1e9z}UKqp3mhOVHobHEksW9j>*TWbe@rp^jo(hPdq%%9)6-SCl9s6qvGEGqSgta*p^YPHJ4)}b%}4~h?eIOt`h{OVurKA_ z(wBaQ-Ip?AJGn1csx{OxUqD@@>hFdoo>WJPy`;*Jwe4H3VU5bLzrwUuWys29qElta z3|hf6Xr0QCom55ML#jKCiMoAcf#Kf~_vgV0V*hf$WI z%_>7YeU&}kVi@kIA4T+f&tAS(r9Yb3-l|H+n5?=@ty}tWCHLbuD&qt^51~^i8_;%@ zAtQbU3=i#4eenIR;!eMQU?0j?`*-;nb|1dhF!}!wtpVwXxeWW?nqxSV|hT;mo;<` ze~JHll_9zO64&#C%D4hq2wg=PLkIngz;@i?-a6!G*zJ&rJ;f1wSY=4Ai{)H*L}keJ z#5MSV=bu%EjL8jd%Q2N9W3qyO+UJFYS$djH^BPN)p&^}Kv-a8hMRuis`H zr&NYqxkzhIs|>k@dKx|E{YsFwd$|MqA#@jI82w}zZuI!>$(>d8WrZ5ZE7Z>_!@kpY zPOae{;?q0Neo^)Ba}PW~IhxL^49U5a+nXzXRT(lKAGHk??jMx=FBXFL`m!f|2GwgXHt(B~DRb@zPWe4@U%8=Dk=KM94 zA*-d#`Rgh}W>RYIj~gn({#~S-DnnvCf^GbvGNhI$X53O4GLz(&L~g4LsU;2D_)}#_ zE$NtXM`cJY88|-vQW;W92DWimWyr`$Eq|*F85gPLp30DMky`#S40pczzOi{<)jx#$ z0Hr7zCu#BYZz2p2Gajf6xmPWBssB?M6;VqlP3CW;5w24M-~TVk@19Eb@u&=$P4##- zg(SkL&x}+mLwYL{k4dP?kn5@}V8m0H$`Bv3fq{FVhT-;jj@)t`5U%RWuhh%;>mm|i zG{GrqJVmMuSsQEc+8CuWa>2h+l!x09tukcwoXx9e8kHgY_`I-zFNzw5+tPfdrRh}t z$5}H!%084{Wk@^ba62-nHTa%h$(V@#udJU*)h`GSC*iJSW>sJ2d13Z5i>hA)`rch} zR#jTmv_G3Fy=C@`+10wG?HAbh94bRj64D`_4^mE*A$t?=d+NI=m&%Z6Eru3GQf`$Y zb2EhJW*)WsEjjsk~EBjm)|hlzL;hDqCimnaHC&PWt_EYC=`_8vr$;} zp@fOaC;j??JBE|Ivo7Li*gFPkUrCOMr&NaIhU=UgimE=8h7VJ5j_|aqFR?wGW4oBj zD9dxM9LhfQj9No^)ZpC(7FYFUWt4ByKdb8dzI{|e)t8l^0(;BRcj zsx{Ox@my8aw|~Fqb(JCadt_HzO=ZYRa3#HWC8(}4#LLYblQj&(9qA)kWv!{HO6!?- zlWQenJw02mtuo|FU7ql$qcUVg{e@T5IF%uprvvZ&<5h;dBQI~q*Hsy^vX|nOy`IXD zz1IxB)~&BH;t>s@R1al5H82dfFB_NZ|aK6Eec0mhT}-cjJ5To{CvH=Y`+jM9Ad zAiK;aDnnM1FL@ckS(Y{`Lt6O;S{Xxcstma{Y0e|w zR%Nt=%tNhFj;6O%#+#6pqPN(_+bToOh&o`zR#H2aF`7>;+QCK`wO1M59`o&CI;afU zA&li6LPwR6%eo@$q%x#GI&fRwQ5h1S(%Q~`MquRJ=H1e}euh2z(jW2MA6-;NCwP#W zI-@K_T@AyHzAlI_4~?a6s=l0$_d)cmrtYeKH|TrsEcNi~2ev_e!?&lOVYfk6$o{Bd zIrUN*5`8_;hMv@0W%Pn9g!-V2p+1J;wz98j<$J2WWHdR!@2fJTA3orI=%+FySNz4f zqJJWcyUZA%G9>cGapVm&47VNqO*;mu`ZAN{>9E17{#RzDe_z!f$o)7NWdr&^Wk}S1 z07g6wQEM1#JRGX(OU|v27OtibRfe=do*)~h)-cS}@KGZA^5ocXoq=bO($Nau3ye@} zXlm{meXQ%F^&a{dVEsFdRbS$HH1vDYD3u|5k=DFh7_Bnod`?aW#;6SG z$8N}nEoiLD7z+7*m-sF%iaeW=v8UrL9$NvdWMi zE6#h&DTd+BoEc_JrmFh+tc*TQWylkF{n4L&Xu8VS%

2e)v6j|J$MyZF%C6!XJdBR3vis1(ub!x~2atu+NmWL9yfJY~m4!eSLZ?+(Pwbq->5M81 zWxbzNS!$M@Rb?Bo3&byvsj>*@dFY%fi(=U?sw@rHcV3mHgDjkWRb?4i?}94phSQAZ zbWxRMVqY$)vRXX0msMF7=ta{NRVLr~{7seZ;QOstRarLn<#$ze2zv39OO<_(XA~nSw<>D_y-3QV%HCjK9#Lh@S(aCowS+919#v(nA*)LHRGECw z|1nkeCfE14Dtn7%PpC3^n>D{GYsY>TP-Pt;^H4!m)`{yYq{=$8tgtHU0@(z5Qk8Xs zES!p{vP~GjFnUUr-RAoeMOB&n2H4Z8Oupq-OqJ!qx)MpxsIngLvlkUtWxXJar)O1J zAIL(egevO`nTMWJW&K%JQk4y4St(UE7_w+8t;#-ttQVD0WyLt}mQ`g#q1T+AS7pN> zi=uL>Y&c}`^nxn;7%~r)S7o0-hP%b8Y&6@fpvuNV7DX?qGVk4j5PDga$+z}iQDySg zsfwy>Jp1yhDw_ydbE>4uCbQmas%$D`5fr1!rb8AXb%WA8#iF_}rjw)LQ zy?BaKWh)?yqRrWPx)2OK`+s3}Up~|*H7D3Ha*-pqJsktiK4H-_zRoPz1!lyzCxalpiZhxerxm{Rd$B!>#WM;cVpjGWoKEhiz<^}FYcRLsi*bw)vqdyT^LNRM~yj`$(0Q$3D_S!&TV>)*GS9=n-#!eyqwu zST<6Xg|h4uRhAmEi8M-;ML>poovLgZ?}f*xvMA_<(O6ZMhU*)r%09CHcOR#%jdhZRoUavi=sKIOul72SC!?5UNp^9Wd+%n`Kqii zWbyQwDl5Wz3sjkWpKGBiE6RF{R9P{|!f3H7D-Kxt83EZeNgYR)=kFRb}xk+osCuvFsaF)&R12+OEoK@qL6Hs;m+8yuX^LjcpUi!f2N& zJIQ;S-KtEUhS;OZyw6ME{+}v)1NBX$eX6WEWFGofm9>Oy8hxkATC?7MRrV&!4ydxX zAZt$FtFm^G#n2C`tOMITsLDFA?2sxe#(S{Cs;o2X9Z_XnAPb?Rs;nF99aCjJAj6kj zRar0AJFdzy@!EevmGxo0ld7yQ%TB4X{wzDK$_BFRj4B(Hn(AK4HBJs%$jZchSi3ye9sQ4@}c|^WTZ)zmv^> zr<(sxH~*c%|Ak6||GkcXj|WZyFTvzoAUuR99+(T<0A5T*)DPGM{0qE@54H{hwgS=k zaiZ6O5x_nmIyF%pU<_~vC>2iB3)liY0A7nA`WQF>l#C?m39JGB1jKQB=$U>0y1$n_{uePBHB1CTBs#taw+>;OU@!`K6Tfpx$g;JL?% zIs;3AD?p(qh*|@)fipnv{6r0a3BW-heF36sz(>Fh;F*F%9e_o^1>lK77*F6+-~^Dp zFxm->0rmsYPokZ`5MUedA5gvs+6k-yZUM!gLOX%QK*pj(HGmPoZXoPwqKd!(U?cE1 zP`VgVS6~J3J5b~qqV~W-;8)=B;zZ4W>A>GW>1V+QRsg>PMN1I94J-sM0{NdKY6Hvx zegg88Bx(pu1P%ciN)c5Dh6B5R(9%S&0R4dtK#npP7ho0;UY4j5FdH}n3`SO@Az*oSZK#3ROKd=J$9Vk+Ps4XxL_!-Fi5>aDd zGH?XQ^fFOR;A3D9kopy(SAl`RCg2`WrXo={;0xdy@YJh_Utj@n9(bY>QA=PZa0RONf!n~djfpw|`+=w? zL@~f%U^8$JDBTqK2UrGN0Sdl>@dD-mXMkMIFkZl9;4qM(Ir;$@25bi+S|IL#fxt%K zE>N;1`W9FMTmtg9!rTU?180C-tzi=w3+xA?+Q2VhFt8c82b6yk>jJO}xB(Pxi*^I^ zfU`iJw=h1y9N-L)>uuNs#sd3+sCKXk3_kgnP(U-sq;092l1NsJ73|s&n?}%Ir zOa+btnL1&P0mFfvK*&3YO`tFE6>u9U-WhoeSO}a4^1X}k044*6fec;HU%)V6J3w90 zHlP=<3b+9j?S{4i^MJEJp6+NHFdq0GNYewk5BLE18n_RX?TNMkD}bv&;a-SeU>0y1 z$kiKb74R8=M|7zXumVW)9>y2=3b+l_>WlUP-vX)oA*O+ez*V4Pf8-`$JCJVx%m7~l zsRyEsz#8BlP-zfi82Aw=G8j6*b|CNjXeY1}$nydIKd=_K1C$v8d%!B-22gY;`T&>( zoC0!u2;YE@f$c!(F!USH7gz(_0E&NvI0F^~7l22Hqi$d=a1D5J1mX^u1l#}$eT;tt zlYsp|*hts}CIH_9(Vw6#z+50?6wwR7RN!x*!D!e8vW+3?4lDyM0xyq6ZUY_wO~+x} zftx^~@%T5e68H@$H34fAFc&xuq@Rer4)7lE1#lU7dJ^&)Fb((t2%n7o1JD)N2Y99s z#R1cRL%?HGAp`aRo@vN|z$oB1;DzbPvA}hp(5F}zfDOREK&ct<1^5O?H4}RlU~l~b@HvobE^-<01#lU7Y##P%z3{0>xHiZ%iJfmF*-AJ7q)0~`a=EXUdl^Z-5w&H`CiU@ZbB0SAF6zd$?zM}VSV zVs8Mf0B!;0R$|Qpjsn?Np}oLXAZj)G1y}+63glXY91nZ|tOKqAudT%%5;z1ze1$Ov zCIb5aT8Hrg+5uaEJHS)x5x2kuU@!0=P;vwI9>5IX5D>8uc7QIx0^k&oaT9VNFcY`~ zJhd5ifVDuHEoeW`1Na;W{hH``pck+S2;E9l8<++B43yr6y#{a?DDVyP2`~z{0Oa0| zxe5#c)&tjp{5!Ds0X_kK1#;~~KL8&9>ws&(6T2|4faSn>;Dz0o&%k`(1n}%0?g&z;9!2KWhh?pL${I0O{B zfd3C10-n5x{W5R_c=QtHFR%}I>@wy$@E!2P73{%*13-b_kk5c0fI?T%N5Cc^;&;qd zU+!0O6|&g@H;y2Vgwl{UYX3;13`N-qtJ))BxH6-rtg51{?*v-%5?bJ5D6j-L2;2qo;tLk#fabtZUEU*~Z4V(p1;O&yw}2@8M$ltGS)eA+8Tb&G0jvhT1%3hU0U7b_$HKr%z#G6IU^1`)I1l^- zGr z{es73APvrkp8@IsZGqvyQo#Fu(oG->?j4r_8Ug(P?=x860KWkL0gvD;@I|00&=Z&h ztObq%e*szZ;*C%s4(JMu16BfufLlQNM=@W4*MMfg0AMDt1^5a04|p^mVijl#^adsY zYk?!cZ-D19^bzn9&7l2ADnK)!4=@f`0_*@z0Dl2#iXhg37@!%@7Z?RB0rmiAfLlPsQy3SZBv2dZ1PlRY z0h@pmz;z%^QN%a!GSC$01B?Xb0ULlHfj@yXPorKS251HJ0ww@UfIYw&;2$7IG4uxz z1GEDA1LJ@dz&_v-5cUjysR?)$CHVu8j$cVGlC6Icfv0)7Sl19Cox zIRLx})Cb-M1_9%MrNA!WXW$kPT@to|=YZFMhCo+f1TY`i1RMiy0@0-~FMt<->OeD~ zH!ueH9QXz}4cr3KmPTv?&jYUmZGfJ@NMHf56*vz3285MCzX8tzuLG@s?!YKu5wHO` z0$c|o%ferv3{V|t3k(9L0V{!hz-iz*5c#}^@&RRl8bBMMFE9>R3~U8{1g-;O;vuEa&o&a71-U7A&{{cev@&6jA16%}j0`3Av0#5^r zfp>vzz;8g=v+(~EXaHOebOY`OCIBx0D}l|xZXkL#&IxcT&w#|p zy#e?R)B?^2+5@)(LxCrO`M^8CR^T_FY(umIXaHOebOY`K#sYJIH-Jxpoq*j4dgB6|e_5_yUY`KtrGna0@U97!S+?UI#V;{|2lJ zasGi5fOCMhz|Ft_;BjCs@FuVc_!)>a)3qu6W>4&DN104;#)fquZFz%1Z3U<2?I5WE=v2I>Ik1MPv^ zfuX<@U?H#;_!{^hP_Bip9S<}BE(f{+_XA^qXMyFwhro7VFHq(Z{7(UD15JQ-KzCpu zFcz2vECbd9TY+DINK5b?s0}m$+5z2xfxuW`7O)Ih4{QT|1!9+?&p;iZ3D6Gc4h#gw z0<(Z+zp93T*>U2buvLfS$l$U@R~TSO%;EwgS5W>oWWg0BQhd0WE=!Ko4LL zFbCvaNNk8c-Lw0B8?%2L=LTfmy&(;631L;8!4aIs5?B2ATlvfbPIR zU@R~TSO&ZYd=2adtTt#LP!nhbv<7Yj`T-+>X~2A7HLwZT30PNP?g!KW>H*Dx_COC{ z5HJpy2`mCu0~>(tz^_28E&LAD0WJXA1Kogrz(`;kFdtYAYyy4&_5!gh@mU0F0*!!{ zKxd#2FdUc+%m-Ej8-X3bKA>DX{O<$m0WE-zKrdhjFcFvwtN_*n+kibl>?*Vor~_O8 zv;(>W1A(!?EMOV19{3vA4TRcb&Ii;28UU?;E0^b39fHGI3E}%Bh z7-$W20r~KqsIlFbEh2%m$VN9|GHfy+GNH;37~LXbyA)dI5uh3BW918L%GM2J8VM*Mf^c zZJ-Iz2IvCx1_lFTff>L;U?s2t_yO1pl<9=Bz$rjupcT*s=mQJ~CIj<<)xaiTCtzI% z9s?%;4S-fa7oaaN0+I*EOafj6RstJ=?}5EQybJmSoD4JoE&)0Mw*dozQNUE-CEyLDotOvdV zb_0QKI8VTFKwaQMpdD~C&<}VRm;^izEC=2Pz5xCW7`NbmIZzci6*v#L9Owev2@CZuo3tk*bBsO1y6vJfkwck zKquffU?A`)Fb!A$tOPy*wgLYILOn320BQhd02csP09}APfWg4yz)av3;BDYj;5*=d zKj^|1X=>u06l>FfYHDd;6>nd;6vamU^fuxiT??}u|OT*e4sUOJU z2G4-wfV#kiKs(@Opf4~Cm;gKnECtpATYw*deZWC?V*CgG0W=0K1v&w@0Rw?YfvLbt zz#G5^z}LWk0ILt??m#u*G@uD^1#ly97cdlf0+M zHUQgz-GI>_J_afQHGz7-1wb31Gtd(l0E_@80<(Zcz)IjlU@Nc_*ayV!#peU40h|t; z2ebk@0^Narz))ZuFawwmtN`8vwg5i>dw|dY@D->A)CL*>Er9kwSD+6t7#IUg1?BHfet`7pf4~47z<1T zUIdl{>wrzbcfhYea1hQvP!%`@XaF<^+5tBLy@5f%Xkaoh7g!3s4Qv3m0lNX?0i1uJ z5>OMU2V4NO0XhRcfdRk>U?MOJSOlyDJ_NP`JAr*bY%tD0Py;v}I1gwAbOgEs{eYps zIA8`aA6Nmr2W$a;0QLZ(2XX#^YCvtE5zqo?4|E0k0E2-sz*Jx!unbrOYy`FgzW~+{ zoPVG)PzyKIOIVt z4u)Pi;Qw5dM>@qx5)MW9Frb2q!;wZf5;zKJl^`nvRS_l}gYdDC)gdXb2ExY!Cm>Av zTyIUpYXPSyY5zdm>LBfO7j<17YBTkz9zgko`Un%KPKuuedA6J05aC9^IY48io#%qC z{}GxZej#uXthRt`33(aN24O;5pdI2@LtX>@j*y)YzaH`i;3nW^;1)&R3O!0E*#o!@ z`n@3U0D2>x+TRDb3*oyV3AFV?&b6K%HMB{4dDw5&sckmOByt8TbYG4f!l7?RV&E zy3hn*0s$SL3&;=<0jLcz-Na+A;HYkBhX56TBY{dtuZr|)E~+E#c%+>KNj6RaY9o9a zP#58PkYw*{$VP}a2F^pcDbNhz<|x}zx3tS4uS6Q5J#Y=;EU!bDa0Al20=ED?fZI|2 z4uJfAC*pk(?x)Cm5gv$gEC(Yz6c~Z@QIL;8|8ayT08avwkv0u!GZ20j;W?1=fR~WA z0CEx9`6|*0uOa>hunKq^SPPwZAqne&kD$ZyQ-ledfiGcW8{~J;{{ebGA^bD&UxfES z?gI>AXaQk52n$OqgK#;>!yu0Yjz)e}#A%BI<$+4z35_R~i*iV#u_*>gX@@|D;iovR z!j}hFmP6X1PI;k~fjk_#M?zL~B$dPeCZ{|}vL&3fgWWLI83b&kQ=OE5B;qudQJC6Q z7NE~1#YvaiRMF9slG3Se8XIZMlkE^%6yZupr!kOZC0LPd!<%~C^a#pO{vm)4P(FpJ z&D4JjWhhQk`bWy6kVbJekHR#9aDM{Gr#_K=8dJ$e;V|`6+97+CA8_L=xs0q|z!%cr z)K>C4`QHF2pUzPQH+&G{|bfgWcTZV&>2RU}-`K7+mxgIJU8TH z`ovM4QG|#y@*I#o@;Uj4&QD^T^Q4saytJbno5X+VGdh11CSOteXq=*UALgXv|CCdY z9$pr9IgW zubk>TX~*-M^qH*3%ad{Xlrx{C?_~QbA>G1%-SG zd??SIJkm*Yv=fdpy&$n5`UeNpMkcKqtxuX>%tVKst_3ITu)2uHifOH=S_#@Leoti| z5*nj=l3KMtH?``5dT3^BU{s<1DnX1YA$)I%U``Rkcb77lo0Y})_j35IP#*tV4#ikh z0pA&pz_?uzV^}5a=#2X*+CQ|~+NoI0I1MWxXJ~b`GqK`PA1fPYYYnu9SkX8Ks~P8F zHRF7&Vl>4ss$Hlx!x~0&?P9EAT!K}MOYu8RmuaoF%dv`a1y(Vx#45&BT6?Txbig`B zN9|gyVqAwips&}uU>)N|tXFi!Iz~6FV|2%N`yN=c=&9X~Rf{{YVsRl>EAG7w1N0eI|yqNgYllzA!zA8v|)Ht$HRF0*CX0UtWS)_^V*~FZiKN|qZo%Z ziV0Ykn20rsN!n9brI?~k)t=U-VQpdt)+T0Z&ti4rIc>H!2dfj$YxA%^@gmkI=4%VE zLh&+IC|Z)1&OjkXpm6z^*9VQpeP z)+Rp0+Qi4&Cs>jA6i<$Srft$TV^!jFtV(>TZPmWQ%EUL?Hmpr-*S^)h!@9%|SfAK| z_UzRDt?klwWB(6UCH|}ZiuH*-+W)k@SeL*}nG?Z>NWL~^jiAK`YHN9^xFEVdL8{V{dD~dy{>+yUJs95J&rYs26{uik$#TeSU*=k zPd{I8qBqqq&@a@R=@;qE^^5fu`Xzcx{ZhS^ewp4{zg%ylU!k|vuhiS=SLyBbtMv~0 zHF`(=TIFN26>Q!LkHqkOKZe`_nimA*I@tx#`?Epc!_$GjQ=~(>vc<`h-(u*SOm2`f zKd&suiz`#rtCp8DN}5%s2HR0}vMm>b{bV3Jl%6Oljq2mNIiGDLrmJz*Wyxh&QaamK z)7S>5kyLGPnDscW>L&}69@R&As-$o-Bvy zYP>l5st)>$ivHe#nL+9g`~ zm;YzyrSpNGm!2cOfBt^{QRij+-GtKUb549v^KHaK07(Mn7&$*g|a}us+9Ga=O~KKO@ZTrMjtYs!VK8vV2ZU)J=^4pKCiYU5%4ZlG)>P zM!J-rOh>hoZJ6v)`_%f?I#byzj!t4(s)O!{q4aFZt9>RLY?nR*9A?S7B-JqI7gthQ z@(b0$wzzIJO|?gT<8#e*Q$B||k0qDoe2(WL`7@npTeZb`Bsr|+m!>fLB-eK4T5f;& zfVo5Vxo?z4;R6lf1F%o~>m1SlZ?et*$C(qVq%h}`qz(jO_rR_Whu^iEGdt|iAYROj3??R##x^vhZA);o++R85+$EM zt|M2OXqV$`kK-hhwKZ9qTBf++#QKuiO_o+1`^70&9G&9SMLJ}Q!Eu&c4@~TDm?Zk9>FSb`UF`u4YV7sJC_T|0OGM)8FkJ`w(q{DgKCYEeR zjdM9J!;)-reWcInY(JOtlB^83h4R>!6sCT0-zZLcEU7INX1!!#PGiaS$b0WSd#Wu8 z^Le3i6sPZxYP(p6(kYw{Y>Rc+CdDaCZAoT_&pqj|?^&O1QCR}pqWq=+NlxQ-vpq^z z!)!~Hbbd)ElOEer^|(E%JvBcuo%2|7KF3*dx+qH&^w|bUHIKveR1!h; zCza#!tVe0=W7Q_NiS#IaCP22h9H+BPv`ulUpYkc3tet8dtf!u53e)#z(qqoi_k7l& zbc(YbRdP8sjlyc##5}f@*cR3!n`(JAOghv?>L>f2B!`LVpKWkmB&mNS)wEP`u7f4pw^5$LoX(QcDXhj> zkLut&4zoSh;W)R4WMUr0>0Gc4mXyxrs2*-3=~A5g&26Le!TPMjwkVJEIL@|NQXWCJ z!*KK{O!-_+<`qs$^bhM(I)Un=Gy=s*HU+qyUf3*1Cp{I1;_fmk$F@|d=5adt#jB@i zS*nvkZh`mU64N8B1v(!%jp!SesY{8=~6oP zn{2Zl*{6Kg<$BfrlU>T^a->gTYCn~iVX4D;iT0SsB-s{~qw_>*T!&hY+Q_!KucS{p zEGeD2$8}H|g$ZQC1~`q+A=#xg)jrqFx)djUZXcx+D4oi2I@wptGWSTA@<^BR2^42L zYTXo8^(oA0tk3ymgKe=6_mgc(-^tG*=_Z2Oo|r~)sv}u?Vjj0i)lHU`svfmmrZCx6 z?Qod>UvZcv*`lx-r?gc4N=&z*o7kR2oy7daIJJw?lC>jIm*PAwsCkL)PmCwCpG=2s zQXcmsF-&n4Y@4`5VcV5#D;G(8%(Wb~O>G0k*%tSS;%b=UTuwb7Tuzmo&t*7|?Xl!^ zva9;WcH5KKF0~x%vkg^pc{MGazN$xIs)y?4`Z>&!_0{%pS~8hRkJ8Ckwu@AHY?Jay zm*R(rlLumx=8>M9nw!xCP$l+wRn5(Le$`LL@`5Y#h7*CbP>8!8TLt#5b z`wqo_BPyG!Jljjm=Q5nmajuukshs09E|aLsHdwO0s>f-plPD8)6ZMnjXPcH-ry5u5 zQ^ScmT&J4e6i-KR8J30fz4JtTVon7SCa`Y0vZTZ3ob^aD*al0|wH4c(o=oz&PGyVJ zx!n|JI~-;mO6N4zNtA{214V2V$3`lfs%;LFh`KbrvpT7u3PF*_LO+YX{{q2QEOEb=7f>?WpBhFH;)jtF{vL6YZ#V zspUL9*?-FO(!Bmi`<@Tf`Y6oy)v{_hQ9oInZFqS$p88DJ97dNkR;ojM{zozq(@=a=QNHd=2M*PB(~Elm%3fjraV7vpWD|IqaCM_RNK@P zSJF5yRl2Ify2&KBlk9LGI4x11`^j}uoXe496fS2cw7oFbxK3_wVjZe2ZkJcaJ5Q=! zvM}4F&n}m@l`xgzbnX+!Igf2noODPMxLq>N{S6lQgLPH^sA;M_)=4H=Pc2K~efv@a z+0K*LV-lXkrgU#B`aCPk3!Dlcp6^HH}FKee4c$Ft}48v(UbBoDbKU7My~ff`^V1n z?4P(P^pyM8NZE!b-9HAt#`Emk@Z9?jJoCO2q3^M8K?7g%}ew= zyF8i*iz3gnmrMFQJ3aG$G@g1_pJ$KZdG?sI)AQ^#mFL+b2{z8s)#usI#`E#=dG;ev zik_B_LLLlD2SYE})AUh1&rZ+WcZBSuU#EB0uSe`)96RAT{9~OmXW>ctj(8@&9GHNmXIUMmL5IYj#A$Tq5P<@y_Tz^;}p+BOJ)JN%~^+)wF z`eXW7{c(MqK3<=oKcP?5pVTMmPeEgfK2?8Oe@C0H&(NRIXCmbTyu)v{K1ZLcKd;Zj zPI3+~SAQA%EBa!6iM|wAhJA?>UWWKm#8&C60ovDKui_lv*WX85-bb6LW$&Y98?lc@ zZClW~FVGrl)uT>}rl5_~Dr(1gwDK{1r#@ZZrT^^U7yZBbuljHL9{qp%Uj27{A3prL z5W*0qutY!vg)KrNEFvN*Vj?ceh=W8~aj+;S{!f$_hloSPVWNUKTpS^e6cxo$qLMgT zR2Ef4RdI}{CXN-=#c`sBI9{9}P82o8NuriGS)3yNA!>_LMICXPI9;3}>WVW(JyBnr zCC(NNL_^U?oFf{GbH#b$e9=TS6&HvLMKf`cXf7@mEyN|FrMOhI5|@eA;&RbO4At9; zD@8kTm1r-n79GSjqNBK0bP~h$&f;Oci+BiLx=C~uH;ZoK7SUbYDtd_9L{D+M=q2tD zy~UlPkGMT@@jtOw{4Vz4RVF%K=V%zFVHp7< zXxK)`2pbV2YQ&7VQN}pPC~F*Slr#R%C~q8M9BLe9R4@)VjxdfiDjG*&KN_JbMpf+9 zjAM=J#&Jds<9Og$#7{D6IVt}zYGbcsoMxQv;7sF8qrPz#(7Y4-F-97rjM2uU#u&HkIFy`VJYh_Py-CJX#$?2&IwhtXGf-xx@vJcmrDhv*Q1W@V z)Jw*E*UD7m6=S-w#8_&)YAi!NRAzvn}3%&P^^~MLr zhsH;!XS%TgC8&M#QErRzc|rT`fVB_M%I!`r)xH*`*Q2M@ub&+~Zo{jvN%pqG6ZfF^ z523f?&?o7g6;ACNV4eLl2wovy^h4X1psjDBh3nu2YR^!kidogXMpQG8HLF9`FpoD+ zFi$jVnkSjH%#+Pg7`y0GS;u@wJKda$v2iFyu=?iN;%xIl(a>yU?iG#AbImH|`DPPy z4j6x-+04AiY;Im`wlFU-Tbh@et<1~J*5>7A8}kbDaPf=o@srr8j%mrqvvNkXU^MGv z-euMhCz;2KdrWVXy5BrSJYdo|HN;FDsYaQj&BT%F8Zpu2(W-_sUQIKnn>=QzBbGW| z$qEpR=0nQZ6mdtVttO36RZSY9PBdwZ z3L8&|AI*v4Cv&Iyq}XN3k*XR-Xm7Nl(Mhv(>ja!B(^_KA7ss2n6|xpMqf`wuZoMK7 zvS_R-XDt=wtyjgNRtIOys)EtBi@3=d>1N|U1^+)d+WAj#9F70ha&eNSj%;3gf7L1g8#6brAPdvELe>*uQE-@?N|J+z>yclPVwqxuwUs`a!r&6;k_u%5AITF+XutmmxR)*NfD^}IFDdcpcYd&!z_EwIMvFIyAz zm$bze%^v8#^i$e$>osev{<`&s^`^DbT4k-ahUsrx?^tWBwbn`IaQ!{&eQUk-f%Ty^ z9iOC6tPR$u)<$clw#nLTZLvPLzOcTuwpw3VUt8Z;+pNd+?bf%}ch>jT57v*?4h#SP zt#`Ct*3Z^%>j}(LM(V#>Q}jL7|E#^%@76xN#A>t-cLdCU6$k_#!mME--Y+~JbDmgW zl3pfoP@rt!;6S;+{{_kiP6AI33seXk9ylU!WT0Z;s6eH_(Sgg%DuJp+1E-r0;1k~vpY{jLY1Srd zDUL(T#^ywf219VHkFjB?d7=5e)hh74)!N)-wZKTwHgLK5sWsMm1+U<`#%dd=qECZI zS_L`>wwhf6Hv|~v(dM>@cSg!qlp3awHct=SW1bPX)iSNcV7d;jUu(s!Qv%b>gDe`A zXrvkvm~PfZo6Dos)Q2C@=W^Dg=)ne)BY^f0F|zS|=gDQlO4C z7ImH(*kz6joNmnykSETteljb-2QLNY2iD*$K8^FV$66dH18@IqEep`u{m@#B^I-;v z0lTeVt)14}f%Vp!z*^M*92j&`;1jDt;4sv%8fWaFzz;a@UsyHFw{f1o1ygq5EPfT( zY*Bsx3T#i|_1yvD?Q7N)@N<=QL|`w@>^v|=56-b(wswI#3yBverDhsaB@0W zHWTl)eoCtpn5@+ZOvPtnlzs$!Hy59kceG}~y@BSz*R2-8wbuN=rNJMqWNeF}0$2WJQ81m~jMJd_)c(({4~f(wH$2N&VE0LPbu zuLhR|{~25!e9hTC`Bw0);8XbS*9@PIcY_z=6LK;_#P){xG&D2ES~c;X^%eX-JQ1IW z)6Fk~t?{||I`~cS>!4|E4~8t;s*lf6BYckT!GGN9fnCAv!QH_Rv|oZd@xSLFYj+Ue zY0Q(Xau^$~1w(fSb?ZlSd+-a4BgB$<*3p59VAl?eXS1xbfhvJ1;Nc;5)xb84Y{ZWz zobhZq#yFQF`1(K`Iyg|n-U5c5Xivr&u4Tuq@)kZX7LEM3TGV>_#5XkS+fB@~?PkuW z|3dWY-QamhX<|3EFR(Af@glo97C!`J6ueT}XM*Akarg^j7&A!EM2zd)a&CJ{FTIL;gZ~IP^e^~Ep57SRJ z?}5F(_5k}nd!T*4J;;8*9&A5o53wJzhuXvJ;r7G!2>TIxq&>t6QeCUMGiJ_W6tgzANkgLd6egHXdzBg7hq&JCRxIv=trbWRR6L#algi$g7t zesSp1P%D&c4a;qiay)XY!RDn%s~x%q$J4D&pqA{aXWQkin?hYfH;1}~ZV7b{ z-5Tl?5mL+^#&53LV<5c)9mQRw5)C!r0YPeU6+pM^GsHix!^J`a5n`ZBaN^i}9 zmk57{^dBI1gnmMqb)g#O#?bE2e?q^6{u^p({ubH;`)fnLhxS2J4`Z?zzQne|n_<%q zhr;3TyC@e6$HQZ-gTiIQAB4(hla1QLgC$L-vxF!Tq|5LY=yrH)efH;t`j~jye@P`xNi8&aJ_K-@LA!r!wtd> z!;Qk{gd2y?4WAc2KinkTG<*RxnuRY4HxFMNZV|o&xD@(lhFjyE#mDQ8&`)r zgs*`ODtlc)*@oep!d=5Rhr5Mu33m_Q3hmpFcW(F$$MT)wKHfjKMb3%Lw$F{67dbo9 zB+@i;LFB?nv&cn}=8=mdEh3jhT1GC7w2E97X&t#d(k606q;2F%q(@|!-7|7~AC#JTfgZJu)Nm4BByDr&YHCbA70&!eS-(Ssi%^XwgwpWulX z?QSU33aP(DRz!Y{ycO9KnQyO+{2tjCSzzl?5hW}0B7x}Oh#j4vhoiSbuLpcyCVEh` zXJnvVF8Y7bwUI-jGa?Vz6{3enkBA-_tr$HjS}D32t*8>M8ofMnM`TB&di1#H(8%%8 z6QUk2Z-m zjkbbx9^6(Cqx!SnjpP>^c-+y2wL1WavWlvqlZMh zL~n@R7;P0Dj`Q$vUyIFJ{TGayH>lM8t+B z4h)Rm9~~5ZAUZhuV01|Iq3F=)FzgRUM?@cqj*O0qj*dPW9TR;lIyO2mIxadMR>njp zMxTsMiar&c9Gw!Kit^K7X$CZAMxTw&!tu%I99VolIuA7tKuz;;qHuykUqX6)f; zt=P#i>E%;V;reMcc-xjgeS;w4(#+>WJ1I6T2?fId*+)61)&W_>SnYu~E@m z5Rb%$;yk<>y&d|?;g>sOOK>LoqP7!Jeh|*=?Xej+*At=nKx|R8bF6P{L-Z?aSd9AL zAvOk{yfpSI&Q}MN?0_CtfSp@nt#OfK1-w@Q?Y}-&CiXfQaa`<9*q9l6Ha08vTx@o1 zPHb-M`PjVJ3$YhtFU97^7Q`0DUXCq7XmM;wY-#M(*s|C^W6NW&#a6^#kG&ClGqw_C zSI6E$$`YiljjfBl8+#9S*2g}GeHi;F_Hpc!*oN4rv5m3MVw+-{QOD=8FJOHEY;A%KgV{*{uBEJE%+7TJxJLb`#rWVrp2GbLjOyxwNWVLDhg81)f>$|b$@rz;W1N68iY+V-L6gwr}2C^P3wnO>$PCG7( zcZ^>f|1?$usrBMr;v3O68Lk0)ltxG1=V*7LN8iE|cgNSo?uqx0-y1I%uNEH|{|H_f z7@rxtAU-7iP<&QwSo|LJe_`wq^kfud&G;DXJ7e|Grt$F!*e9Z{it*(*A5-EV#!iD5 zrX%MR`0U#FtoTc?a7KJ{tYLg!{Dt_7@uu-#;R~vn>e~a)e+!Sj7P|~F+Uv!)feW9; zW@)R@riHOO@ip-maqio}*86DF_SlE9<31zgGI4ZIs7*`so?9%v(i8rIH(_CpxO)J_ZeUHfZ>* z!xOZc_*KJG@E-p!x{L}hu>nrWs7?-)6n7vwB_G+5X-q}_z>}AH1#K*D7=CijX#$KPj`)BOs85+qz5$Oh0R&T(*(_%)uXfvzs~050uWCgXwaJB)t;16l2Uh zB`G23vsazfO6SN~t9Mj2!hUW-Y;TQ4N;+OC~z#aad;<c#}fhn#xL7x_+7g_II7$4nvSOcg7`H%co3kw_`4_ywC12`bT9oOxN9E2ZVX6G zl5+FEwdKZMW-Lh#vrkDDf9x$fbExE;Cuz+ed;iK~@8VKA@3md3l1#QZmJfR?`|O2R z<=C5Uy|?tw91bg`^Im2w$&&uoR@GC%HCCOox zS^3O+tNUXwTzMdjy=_bB*z4Th0Uwi0xM{;7aX##=;j{MuVeeI?l)cPYk|jO%p5U|h z0AcU7rIfvNKO=1<4{}0<5BZF}HGTHNnFqqm;f7MmUS=%Gk{)|&`RqMF*xSF9vX|bP zM;pnKX74FJd*RgsVeGxBl(Lt8CxJGSCC%R2K6~NS1A)C=ODTK#`5ltc_56vx0X`& zGGj@W^w?X^XYT>R-X5itz4Xfiw2`D=+)do_8GFz2*$a0b2xISUrIfwQSdt|@_BQa@ zdw{U__EO5;3hrP_@^Ck-ihRc2Mm~Gt$^&8S?Nv(I%Zw#i(qnI9pS=eNd+#Wv?BzEq zkvtMe-0~TF&-2*}cOD31Z|_pdUS=%Gk{)}T`0PDE*n3wgWiP*{j^t55;+D_Ydx6hh zxbr|5d;6AB_A+Bhmh{-$%xCWb!rr?}DSP?7pd^n561RND-sV1g;m!kL?Cn=d*?Y80 zSCSeO==;E4z26%Qu}<@6-^#Fa0a+t~iJ9H#y{KCi9B= z?)0jz0?TCj#Z7Ca_r_W6jU(-CoR}=zNAIJ=lH1G7Ua~@ad*?`XNV~E=^+>gOxm2I0 zS=p(+FUsc5-adab_MWug*ju&W*8*~3?=dcwSh~@iL@T`?&T1L0pI#Pd7aciYU+73po2f5yLW|wF z*O#UGGJUzeLVp7}D}a^y$|S#Av08r{`x@l0b1abNpS`u>m)N-t8GxUDI6BD%*JlG2 zgRi(haB^*6A2b#O1_X=ln&zc(-^ixi)DY|K)|SROJW;X9Ws*s0r+$$36I=zB$@Ghx zCfO_3d?kA+Oq*P7mEly!Ox&H|tnQMfi3RJt-YTxT+Dj|Fsn&a$z3)NCXK&$ik(#~l z2lf|xPbgq~F6=$g?EuTd{mCvS*}EQ$rPT%+dwJDCe&bJXEi-$`3hfgM)*7T;o~w8= z^_l~-w;EOxwz;)&PUWV$@6*V;BXnjU-m`|K??dp|6t?5*XJiDfEo6(`+eFI{D$nFC*K zlUKUZ+sMpbvO@dBf@^HjF0avfGWE4KkG(^E_7q;qmPj)HAGCjl6=SubxV}15| zo|5amf9*Ag(#qabTsO1yyq>DC;Wy+eKWCagK6 zW^bn;KN(cAGlzV~-qTzvu}sda;-yOVGIRGId$*JTdx`h{ytnXqP0ijB`)TaWciwxt z+X0q^`;%Slk7BPs_GWipQfU|eTU%)zd(UvY#xhk;i<2(d%X40my!rFqzxJ9#X`T1h zbqU6j`Id|Pqu9Hp1irP==gFTr6h6zTXAVP4>CE9ww*xE-_b0oUWbgi8bMV=l-FZo+ zUHq9tX=QIcw`(j@^|UzYlD&L?FW=isC5v-^Z{{@zvO@b7=cwMnTlntY^!NA5H3zce zkG+M@YU;7~k^MII*3RpF4)xs*uq@o4>|);7OYf9wqs)6pgK?Sekj%{9E$$tXTl9#? z{tn5QpnEDcjaSS@`|K_DirEYMjlKE3&*3bWpe(cFYhmrw?ClTsX1YVNIP8^oNJ{o* zdxvC9PzjH{{eAWpo4un-DSOX$3COZAAG3@7Q8R}vT%R0i+N)&U$Nlw@|qaOlFQ6vFIl18zgm&pgW0AQ|65yWy;{-G?J~=3 zJ)r7)>@7O)-BSYd-aYQTcaL5shk0+=BJ*B<>{ZX6e9L3<`y8&{Z)0zM^WH{o2Ur&F zPj<1??CpydN-2BKaXY}WaDTFkl@o{H ze!>dkNO2TU88}27BdR0q7)Z)Xx0Mr_cCzB_hd9>BZqZ$)%34{kux6&ZQs=9EC|A&@ z<3&w`j|WZ`CyOqMlDs=z+N+KH)0{G-nQVJP8}IDN^87UNz<9?E3pLssyDm}XFgGn* zQCHN*IcXry5$6I;fcoM>(Hvru1h`yWo`k*9UR&f}<&+`K^xI->ae9TnX|D8&Wbe7I4_Ip2x!NN+`lW;D zh;!0ObQWD8Zv;AuuA&=cS4hfBw{;MicCzB_9br-0rBLCWYEyG%DOD#^U8(ccK6EJP zQ+Lq=;qE|B(K88qrM+Ir@9mT!&19QD_9pX+nx>Au=eZdyn;@R+*vstIv@W8L@YyR} zD`yTqdsPPJ6IR)KzH5kOOT_bKZ(o1xRZfr3Ud0(D5LDSqV=ZkgY5topd;9t9b$luh zK6@2slt55rZ&TME%Zm`tm%TJ|=;zNIT+jOKEdk0ZCRFxb;HI-|j(AD1m%g?2bG|wG z-`dE<{=C;ETHZos?}e^4mKP&lQta*Hvlrg<$KJdNTgZUQ-eztN%S#c@m%aV{d9UJc zpS_ARN+77R_afIG%aZukM)ThO{=C=qtk2#OpsZp-WiQQhX=7PZ?4@~ce}Cox&-(0j z2v%YTmAy32rHy4tu(yvtbC6DTjy`)8XOuutWp4}D9?MG*&v)KCz-O;=mVEXq&M1MP z%3fkCZ7fS-?4^0{0Ds;q9qZ2=TtAeQP}xgYhG}D2QtYL9?*M<^3(xvvuS2jBJE-iX z6*Agb=EL5B;sM+_HAD;(4+A5C2gIXdEYco@q`Y+7K#^%DE8hNqW1Z|4-DRq*mGug1 zW~wW7zS@U@1$`PXCL%l@cuG8#;&sS30lLR_6{NfmH~raqRb<+|dwco5UY6>eyYkLnd6f70$~%2IEOj&0l{#PT z#jEI>+%nzYEA71n{q*fPzB-DH+{HX!G_)0w^R`0VwZ?aq6B z_9`yPE2y&fa@P{ee4ee~nZsJ~9L5-b<{(`wzqR=@hrB4O6jtZGZQOL06wNeqxKgpD z2ARDy?_KN9dtKM~>{U6Ee^_Pj6|Om!6wSomb}5>mvX{o*wazyu|63cm%O87FkS6P7 zmA!4<(kv;OiM>~)sFB(Gu0L~7JminPiZeU(FSHO%^cqKXAZ8H zeDRQB>LfF%{lm%Z=%GY7@{(^)h=u@MjK+hkW)b&M1MP%HC^Sdn_rMiM_4d zGKqrOOKT1v_%jFBJwAIAd6HjTWiQVHSd!(EU@y%aKJaG_@TSk+{MedUT4gWK0$7r6 zuI%NzbUyO$(otM4+3Vk>qqrompn8{1C)W~7O}jqtd(1TLb@7q#?~s(P_1T*jS&I}_ z*?XOv%M#C|l?Z$3{@#zACxiU^d&$NA*jt2#IVPy=?d;lMscARl&E8M^nS*j>{IOSY zMhOH}_FnJWW0}wWy*%%wnZqak%)#}n&)yQCtYSiCFaJIW%aUR*%^W`QXAbbX&t8Rk zB@k5EdxL9_Wj^fX_1;hYs};&wlI->G?^RrqS5RFslfLB#vxlAWhcE>b&=6w=~O=nD^4mVY5GTa6Rjfy;&19Z2@)c z=;QKXZVmeD{Xmm0zs9% z-CcVuDVmABx20%#%}d$=}OQZy5LZ% ze}|;vdC6Y?YK7vGyn^c0ie9cImYOy&@B4e{4#}_lJ0xAt`s~e%tVIf|?7hRyWvOZR z=geN7_kQDlYg2sg&m0tIlt56OIrMhzv7~6GnM21E{H=}Vy>yS+ zSN=U_@RUFAO+l9&lht|eU9Jt5ns#&E^WJ~?^Iql5_+zi)j1mZ{V=vEPS(5ooV{fYz zZBS`g(J9FtY{_IGWtq-ZAg zs=o@WHbG@C%^bey^Y1ZpJ?pbKFR~UXtg`ohHpgMElcapIr^SRC(TIp1}3{Y14UbJyyltNp1DbgGd)iUjDqr6r@J0guG zFRP*#)G9gQA4O%zpF}krJD`O%w2pdBt&`K%&UzR9Mkmx&@8-xRT6afk(CFcWdb)AX za67HN)=TfG(c9-c0-dpYZ{*~8Z#S(w_MXU>cT$sP=B=ukStoamOXG#h&bBmdbEI$@ z#devk0(+20+cfL3sHUy4W+&M-%}bTql#(pOdS7XG#W{Sx$sw-{msO?A4Fza_z|COE zdc!%8h5R?Zt7+P99RDl!h`mm%ptw;GN)a$JZW`M#0!E0#DXhulsG?QI3GWdHLzXuV z!|@2cz4u2J8SnpWLt;DpX`<6gDr8BL95#>GZUN$LpYFyRN335l(P3mpS=ZVwD|1pTuRx?EM>`EOB{_t8?y-iO@2u;i|N#DOd%v$uOGW^WIly#;5q`0RbUl(KiI z+ZUGHwUr#mLiRK|;+tA8!`nNGuA(QtpLB(!ymVVnBhyY+yuG9IfG#-0t#jJNJ zo%iG}G^7 z#oPPAqO?n)!aLQb=E_p4PWqbC<*I$4zR8XHOnuihDqD2yl@?h?YI0d$=IQ|+XIYXR zHJpuIf4%oWUGJSyO2=LvV_7m=b6M{lwmG)RiYI0d$=IVh*+=47An(Nrh^WGt)c+El6 z{HqnrmEzBPhm_K>ccj}DmfW-T9LPd$)Ja+1=a9JGJG5YwN@Z}9o@r+rLyh4^_V+oA za9i+&(@MI}VJkvk>mBuN`gSL+v;LiPpTkIl?{oM;-{ItF+V+(9IqcMT>6!0y*scG9 z{a0Aa=01m1zABmYWbCbsyBHF;U1rZ9-{;UIknMdA<)W3Mt;2=yc;Gu4e$Vqhhf!`* zSthnToA_ws8LWzpF}(d5@q!ow*1P~odFi&%My8#tc>6QXz3*hV=q^)bt*lpAGgDou z^VL3#F8EARpQ-P-#|ix?I&+Zrs4VI5kwX5Ky9fAwGL~fN*&NM{HOAr0jKk5}#~Ndi zMn}p^w~8gF8 zzR8VjQr~4?i?WwnAa(f2rG1&32gbO?SmtI$mYQTt#@U;Uqqk2oCLxWEl$UNJoosfh zL)!If;}F%R=1RMq%X!(<=IN?^puWkCY*OE4UyHJrTOf7#$fbRmn+G0qi?PhjiY&!z z4paR#2gQx@O7UO&?)1{S<}lXvGfQ^6zve)m@Yfv33%l}Ob6CHh)*K$E=3!$gW4Rr9 z?49P1y@~@5gt7Ocf)%sU^<>aE*Uv23?H_U=3)$1X&&s>Ute11&n7r?*SHT=HxyjUb zbtTWCS|~@Yjl(k4%as;5mrEwMn<-Uoy?>9H>Wx1>Jl?I6Wj-xP#@-p=m(O150rn61 zIMZi2pY!ndDLcXKD$9I&KGT>5rq06A+h-axkw!<#OSh3uHapcJ?RvFwh-y=FrCrYD zyliUobk#mk-{eL%sqeC{Mb{j-1yYBPT-ukpdEg1R7|YzO$WlD-rTcqlm(u%t{reoe zGo0*7aq=hPOY54$M7J|6xo^3wIm|WYVeFZQqqomB<|2)bl$UNJoosfhL)!If;}F%R z=1RMq%X!(<=IN?^puWkCY*OE4UyF{t+ybe?M=tHl+&u84Ta0CHR%EFcjrllx^Kta{ z7mXK@Mn}p^w~@C94+ZP%Okw!<#OSh3uHapcJ?RvFwh-y=FrCrYDyliUo zbk#mk-{eL%sqeC{McKt~ki_FTqZW-qPxuJmUPt}A`^?mzZUbA8OR zq}aRKXRps*ct9O-nOh|{_D*+Avg8`_8GGOMXAbN}NPp~=&QN*G{LOdfFvImTOLluc z?4_B*8h`9{UFoxT|FQQO*T*dLVedNQJ$&bW4@YlbXRJdS9Vsu}MmpK-REM`#^n@8`-43%f1#}bKn+89X@htU*_h4nQk$bxml5=`WowT_UMgX zystMta^COt5hUfM+tR%|Oy-dlZ(k3K(k_Jx?^K(bD@&<5nQKd>q4uF~L7%9{ncrhZ zWl4{Z6!N#+J-|=Dvm{GuI2+3wjEy)m8*%jZ4aNqf(UJ1fZKRXUPIXATUTqwr+SFWW zmvcEUo7y~GwGY%cxsgrkyX!=4M5f8sofoW<8D{0%M&R z+uKxdo;f8^PS7*$Y-5wLC5LzEeBriWlG84Fm(FB_rs~u58Tw2oZI(V;pNr5|W1jw^ zlQLgl=t$hPt1ogwi`}@_`lb3ZeYw6ue*-xyfR*}6y(oKE>u+OUgZy=l1=9Spw^s4O zEf^5gw4;-}OXu0ZwBRcNse5f;A2b#O1_X=ln&zdkADzHqZU)(fa@BP|eb5LC7e`}M@*dJ>Svt2*4WVh$C=CIA!j`3|f zj^4h_*oHJZQeL`^bh6p04r$k`jYCwMnk(&cF6U)ao2RSxf%+ylvPpfHeJwinatovm zAGx$IbMwF)w;0RZtjJQ|89(6c{eYvle`kD$G&)jVx{Y+Q*{Kd`*Q<>~RGXSB?Q$;X zWmB7{tM-BVCO5K4eV2VL%3f}P)ZrtS_GNA!nCli}nVS_^YKO5CXKyEt-oC@wfiyZ& zUb>BRve~H)Y1gZbLsXlZEA4VF=Veoyr>pjX`X)EBNqv`nEy`YQfz;t6m-c0D9(dj@ z#xgf6vJ}sI>1xF;|7wNnN`Kxf9kD;=z4Kfjvvi|cF7sah{kU<|2Le`t0R97??k^EqeR35h;AX4r}H6_URYhYFKiuxyaqdFPQiJf}^+Z zHg+S8j+B>fBb{t^szciKYU2>qrshh!oXdIH)aL1`eW1R{jciiiWnYWVd$|QthmTy^ zm$`Z1CAS#M+^on_>b&Pz?|j$CEZt~M^Im4}9{*|uyAjf7uXM)# zVDAFg&n(&PxqNHeYwW{+&V4v~`(9%&(&$Ke={C~IW~Vx&U9UC{QEh6jw9C1imrZS+ zuG$Cco7~7I^W`R zP{N%e>(#~~s!h$6b~%^xvZ>9}Rr^4FlN;HjzRSKAWiPit>hO_E`!Y8Vyy6yP znVS_^YLNSDr`|8U4t9RMRsQ-Z{mN;&E%k4!CeNW-C`YZ0!!p&&l@>UcOD4CQDOK%* z|4Xl`H~#qWVz)|``Lw{lTH#-<;Oh{~BYCx=`hL1vvBa&0CD)pZ^x5mPH#vLj>?igv zb!o~n7uIqapS?bNle71={dAwht1k6eG81!=K6`!kCTH)6{lwm7E=^hH!dfolv)5;D za`ry4pV<3PmwGIjiMdF=T0!^sMoj-|h4i6+rC9o5e_SbE?$VScvo@D2#s1jqkG;vq z-g5itTia_cU0E`FbCEuKefB12Z=?M*b6DZhlw~fg{)p03&l>YLoiCiPwR zwdj>%Zh_R{BbWANZXS5UEygl8E3#B__VO9^*(D)5@Asrn5mh+3Zw@wCmNz zA*xNym3BFo^RlVU(^dOWw!lkdllqR;LbR&r%t4l?vZTXD3i(^^9$4iTWtqDrP4maz z)Zf~=Y2C5+gnN5AE+);)Th)S3M`qpZHHv?C`n=#COWL1iJ%+dNt+DvqnJVeIVcxkl z>MF07##;HlJDu-BXUR3>GWI5aGKim+@t+Km&k;#KWby`|2VbW1z*}x6%XGS#@{+$h z{XN{*OK%P*nQrsmPF}nazX4r+BRYpm>$}sb|I!bcyphgReja<^Z8yM@({qvK%|r2@ z?ob@PU8a>crA%j)bh6p04r$k`jYCwMnk(&cF6U)ao2RSxp?txAcCtx**EG^BI`5U` zsVwR6kwX5Ky9eHJi?Yn!68*lk{H5u_zh=$9JWVp)=KYR!@k0Dt*=lVZF0H?^P5qaC z$mET5p7Qh918dv>OHR*4CjXV~rC=@n#x%)voA*1`#S8IoWvjoP&EeAeE8En6>4!|- zNara(k3F!~4Y1_&T;y)|ZAia3?_rWhnYP=16O{ATD)Op)BUYyOV&&rhzh9YkZkJi+ z8z7ZHapcJ?RvFwh-y=FrCrYDyliUobk#moaOSX-LN@8B zX{1?n-Yd&XP47q{f6Lti@47`<=5EPf@71&eb-i~;DZSSAo=aDj%-&q??;UN7!Q6HX zj@~ZQMjKMH^<nMobirJnY*ODfjWmmny|O%& zB^^Fe$lr4J!251dmbqK<$KC^X?44ao$6g*|Su%Tbxz<+Etb}=AB^14B09n!8>8;7ViHCNi@T+Yj;HcwY=d&PozFWIENYZ_@59eZVYDoZ+iq>#Vm?tu^7 zqAYW_RS>HeMK6I}LY{+(h?n^(-=DXwYOGMD}hey8}& zK<>X&%skp3zf=5)Yn&z5m5bcpGl%x>xL01Qpk+7qo&x4pa=TPntL=`x9bm79Mq_U$ z$8u-Ai(Yu_ZK8E|>+F}{vD*D{a2x!vEJ%ULLXnd0ByTj39#_kLUKv3G;pS(e4` zdr{4FGl!whDreC$UP`8U!zP_=3^j)5@Eh?X+!lP{@R4Q?TM_yiGly+D&m6vU*gMkT znZpnI4wt>DXAV2{U3zBr{F&(o3%#y8_NHR5rupnu39!q2ED!dwrQ);K2ymHXQl0m1bQM@8(=Tq? z{+{341K0!d6qs~pX-E*JMSgW{2k`K=LG-A zdGDUI?3MH9`a#-1bE(O)xJ*r^$MfC>rT$k} z^X9$O^mO0aia+mdWHvVc4&U0|u=ttcl3nl3_gmW*mxU~okh0iGJoeHXQ1{2%NOE5> zqpKC?0kl=t_-chebC4e4W9pehje>7&f5a2<#lKqdx!ZJ>+>>17{$_7^w^7-z_fkQR zy%eLdH-GjvF)uLx4(q+%*!xGYxA^nkFX&WaV<}^~9n;Mm{@g3YbhW~}Qp{H?{42$U z&oi;6GTt?kxa~4ODj0i9cIJ@$N^$Y8R($C;m1Sbfvx)C-_VOnn`}-WI7an^lMq_XO z>}_T?H~$XzIe265AHm+@kG)&zRAOT(W4Rso_sk*pc`uE<-pql=-u!0{z`nS))8 zA?DBm-Qng4gogto&5=p&P9JTK`G5Al1>Ux5-v762uf5jV=X5--Jo1X0(52fANwl-rlM@myjiHatxt`4?>)MHT4A@%g=_AE?&T5*iOpBy`T+>-9S$ImX-;=T8T!h7$Dt}?y%o-})k!|i+TI;X?E_f#j- z_uf;NdG9@K_H@@i;_{c=drw~P_ug->Lc_iHviZFe_ujz*_ugNIyV%gl4S(-Fcy+wr z=I*^e3mm0vQ+6r$-syY47vIu}uY2$2M)<3(zV2;aZQS$HpA_HpYQ6XN|CY|r!vZLq z>nR)YmBaM0_co5N@%z2?(+a(={lDLPv#a%c4*fr^xGWHqvW%}y?+yKq*$^4~GT`mYV|nEh>X@4Y(SG3$Tt{Y4-kWs{F(BfjTw#*$w5F7}SYV`k&) z-lf0iaAtkaVFkVCaCsmoWt*=huY0HW-usEhz4w#hb#J}*Hm~-=pS8_RUO8MH_ufn0 z>+gjReMdrnmHEryM!9g*;ugN=aMqIUy^Fo$aJ;$qmcHk3w&Sb5=WxzO^`66qeZP0( zf6w7pfs~YOj+WeeH}r2Sz8`*>R{q-xtm={weXM`=jQ1QC`fbIJH?6;|usk?U zEKIPAM%<5-tUG~<`+9D_Ui{f>I<^GFTzYVmcY_oKs@f8UJ*?XtK zhWU2-^1k02-|t1~w{g9GTG70S;8*(7id#+Ty_YPcY_4bFQR?2yzuN9Hc!d8yv5j8* zTRI!^ueQ6o>!N?P-EFWjeNv29=6#O--_p6)Dl~jje9Q{?r1*DXb12(;HBEoD9TTo) z`Co1S?%4Y;;lHS3Xa1iX-Nr3+p}*StKM4xEb#3@X{C$`4R~s4C|F5<)d;cQ-%8;Cr zb1g;Y-tXlvDi_YX__K5_4(u&|8VTO-jlas|`@QvPB+aXVR}SglR-CkfK5I+=DzpFl zy}u6&plq(EY_y@@F#aRAkcly3#hF1>p8TY?!A${_1>%3wf|>rJ6^5q?SJq6OCTs^8DE>;WbeJ}>t3@l zE8%tTe_pNZ#s32qKGdq;F}o_bQ7#XZMmL-DwB_Rz_D4&~oY=Qkwd>w)+!o%E*_(KFT%k$vUx ze?d(dy~@#sX7AEJYs0g2B76BPorT!j{|Ttrqie$xP)}F}d9$;H^)|5-YJ56LMx z*HYy4vKPN8j_l=ciYt4YR~h_De^UH`tChX|e^dOAumH;Dddf!A`$_SCx$6?YrSo7n z!YhaREuH4|UHFsY`&_M`6d&Y1v0nJlZ~N%KTOs@o9_7Mei&{1`dzbgipvYb(??!rn(#_L^<1>@}NVVD1U1eV@WN8`w)}(tEfR_CC6@*KA{D zuh|R(*9UtCfxVO_y@yL-?_(-^%{Er{n$0k9eXw^fu$R)L_i!of-J`PCY-44w*$e~M z2YZKsy_6=shf87a<12g3HdgkU%`k9%uy+*LOKH-3xD@v8S=np0v9i}}hJovYz2m@M zN|WBhrLgx&mAz&gD|^jm7`Q&zJ0I9fY0`UG!d`wuazp*Dtv*YqeRY;M?*H40qo?#6 zlB)uHDVMV!xo_$4UkY3}|KiVcV2<)~xIqNpXFCFLojx3x7-J$_?}_o%Fwz z8NZDdYl}#&`rC@tfxVQ`s~qLn%kSncoON;bGRM-s-+Nei0_r7x#b9s!j#=|+EX>~5 zZy@$A_xrt@1@=-l*Hbpiv6uJFg)=VBUgoIx-i3Fu#FBdDkp70`NrS(-Z;Ie3|8}~@ zxzBq;1|YWO-h0;s_EK`LrN|t6dEZ<(@8axbj(YE1co$17{n`86DZTezC$N{YWc6*| z`d8bYZcCox+DdzV@0+LeueR$3_ENSPSu(EdU8(GS*p#yOdV#%^C2Vc`u9R=5*C(Jh zuk6Wlm(G1WJQ?qabN_J9>HFy1%ZJ_O{*~N`mKowV%`KweALNs3h>tNj8J&{$+v(R2 z?4?Zk_tn*V?@GP*K7LB?z5f*0OWBvHDZhH}J;&|l=Vm@P(|z6hg_-kQJKxza@H-CA zYx?N_1k`_C#xH}o$_;Vvy+PPTO3t+uS=qZ%*?Ye!W$)&Jy_8E~En_NsS1NnAno{=O zFtC@BOk9er>|LqsJ$*|5YP(TjFXd8L%b3dEmCD}ROzFM%#(}+*Wa3g}W$#L5?{c2! zKqhU7zuImR*h|T|mLe;AS1NmNJEiyDEdqNfm%>`cRQ9e^_TFwv*?ZH#UP>}?DYCM6 zrLy<-Q_9|(1@=-dg|&>S>|Lqs-DXPJd-K3vN-}XNva)xjviD!6l)bkI?4?`^YZ;UK zelNdSPT#Iv{QJGkv9xceKP7xSI{vnz{xYa}6&C(&#qT%J_j{N7?etp)_EI+2Q#NXT zOK0umyY$GyUsNuf@kX*(V~)+`CUVn-6B*0R4UYff6_mGeeJ@wx?Pc%59py=W7oIuT zXYd?f^}d7syu7dM6ZYpxGcWL({r%abmB+{)@}j|>@+7C+)Ag13{oW@m`CB@AufTp; zbjb|by1`H6j5Yk7#Vco3i!=NeI_&S-whW$>3&r%&*H;cJ^_9aTr}UM>tpa-~`>-_a z^OC`VgO~Uw@)CE40;cDI-o{Z{!l$Gmzvk6h?O7|K74t=`wdqW%SKQ~U{_cCMla(=p zt`@nGr~4f<&8~B!p13y{t^DJy+572I*MIAfm2#f654 z&EEL04WjPbxc+0e_Dg5>ocYa-X^e@vc1BR@pOOIc1d`K(*}{jBX@!quRR zSEU?HH+%d4ORx1=I?Zc;^4zqt_YQ%*l+C)!M$`Se_ulT`iN|p(f5yGHe%9unR)M{%YfUwF_rl{I53VSlau&^&PYJ-uM5jE#7t;JmKu|r@lWqXAs--@6Lg}lx;?q zjHjEu^&67yYuW!Dvv*GE`@R1!u$QvE!jkcW{rA5gI{S*jBf>YqWAr0uAKlSKE6`(R z7i)Wj43D3E)!;SmyU>dte1_!focCH6z4z?v2mAOe`?~WXKF13j+TZmT&Aw#zKqp`B zdOQvb^Bg$4-|Q>AZ~=JkDfQT`3Ozq&%?EwZ9Y27XH%W(MSkcaaD32t z9lS_(^<3<{ZuE#%7cJm4TD5M(=Dzbj!9XHAk9J`T?A;~EcDl_%)op!he2l*$$GY=U z*n9l!VlA@wgxM$cy82}Ae>;Ayo!x78Zx?ln>(7}5d-wA>z}|JPgT1FZ*<>%*d1{iq zulE_?vlx3%n?2pNk2wDl_Udn~Si{1yKYM?;8V&5d$?ClwOFzA;$=<;N?EPin!O+R| z#omS2bMWfO*c^NB9#~7+&RD|U`pRKXw|y(|dk$Zo($~Ga2KG|6*;_JhvbTOiQul5z zFE;LPNPb|+uX`_<{6F2I_4V}W{|MPBOW4}>ZL+t1LvrP?_Z>@S?}q)J!#x6fDcg)J z8CUl1>9%VnzH)fel(P4pfxVO^Y;F7UJ%_i{_Z-aD=qrc%o`cyE57)g5#H^qF4Q#*egFaDci=BQ7Cio3QPlzPASR_VX-%b8%Tfe_4Uhcmcbnn1k z%68=?X&0d={bRy-)Mmoml5zPftvU6{Qa_jk;G zFs09PcyM4ZWnZSI{HB||^_M~IYu5iAv%5{{D~E>!_ENT2STfGNa^Q2%7tXi%_Z*m` zK0AHkT`aMr*qeUk5bwR~_j?Y@eRldo1A8e;R^RsJcg)^ezhh>$rhdoFY=(jB<2z;# z3+$yd={;Ou-!bETvz%BMb#nprQ-+PapymFYXd#}D$6`@?tzSUO_d%EpQe>;8S ze$OF3g>Smp`|xn@rL6454%B~T+w$Pb*>_Fpz4sA;y_B}S? zQpQ^U%HEaA-ZxAsd-=;>O3TJloMSJ4)w6KU#s6w!j{3`>g?F*U(*LivUvD7xF88yx zM}>PYWy$K>zB%^R_Z&9nPm15Nf!Mp;_j?~5*h|@FWXZU)ccs2^IC@IiyL(_SWeHo` zzLmWzmA&trQuaP3u$QvU$dYko?@DFw3#OF4j}7dlEMaTgx3YJovUmR}W$zw=y_9W6 zmW-#Hy@ze8Ytg5{-Np@m?ACti%$_qpo4L&I!c%50pV`Z!`e}u|?pMy9H>K=-TwpJy zt-2IX_ctW#Z;IR3Gxd&H`ZvYX`VGm)2li67S6DKh?tAZD!;_-xy_eTC#oqKcBu|=r zJAJyo=kSEUUP`WPDRR2+z4hDa?Q5E1Z~ESQ{^XUzbUn{u&%j>F_6keJ)BQY$OTz2k zWBrQpy7xGTj-NSU=ERwkyzZ2lbu*`WblS}6UVdce3@=4anmN;>PlR#Ymru@|HFNgN zIWy-v%SwHo!@Gvl`8k{l4e0-0zq@HCzo!T#uz5(|zx)@AtN^YybBg;yY&3^`67pz+TGs z3QNY*eeb<(=l$M#?`>XPJgqeSe(#3*Mf`H_y-y45rEIRJY&6~Mt*;!~S2K0*O|$pG zQ~Jt5U+0NXwpUm(p6*u;_0x*>wM?-${b|L!C+wZBR}N1P_g>2O3QNYhd+#;>+lu-v zo%Xd%u{VA1T|0TtVg3Hqw%p%V>>b!k*KwBk`ydhdNkU@v6} zTid?5d+#;>j#>Syt$n@v-+O}M30vE~mAxyK zy^onv_UfniB9v`LmW(TVS1NlyIHl};Zn*bSmaw($TiLr(+55ODW$(U$y_9W6mW(TV zS1Nl?pHlWdFR+)ggspAg+&gCVv$l=-Ic87WK=1c1_p`SB0(&Xjj4T<~d+$oU_wG5R z_ul6R_EMIxwe4HkyHeTvmMLZL3j%v7+l(w3SN5({_8vKt}5n^XuNdHV}K4`&rw8 zfxVP%MwX1Ho4xhMWYuk6a@4fXG@$Ku?|K9ubDZTd|6xd7IUSY{N$KLvW@5cPP_ct4ey~};a>=l8% zlqGC!`%X7|>-)X!>(&3>`;5sehv|C1_mzRYl(t zlMWYuh)+-uk+CV`lFa8;HHjeck(-z+TEW zBTL3P_SSpv#?0PlY#{b7_ul*3z+TD{wzhqn@As|^Puf?n&D+kM@r`7$#vGf=P2{GX z_>|)2M%jG=>RztG+sodAJBt3BGtV6CGkA`#df&l*Ufx&ul$IyWyufSr_h*w<9wU3m ziw285`G4bnzxUY5Uu~uD_g)+kbr2;ON0ozKI;=W&mdN(cZ>UTEeHKA;0F;S?yUXp%wE*thMP(s#o0Sto}I1 zHE5i!7P&EA8_lwp$Mn*@;n}!VxP%=zIIx#;2`NIzF@s|V$M`04jJt}!%yz7|ag>(u zDQU>Bd39EM)=Fr_d=YDHI+N-Z_c^OS&T$PIr>jM7jJxcmm+lSEF-t{D*@4#w_EIh- zhsGQ?IDT-PZ|+~AbXO6W*^c)%j?xl7B@OvCug+@ES_!R~FJi4tXHvc5K4c36@i)UL~r9LE#XtrkYDra ztoE#x(2DsY*4lI?)hq6ER)3u18Z=H`T=r94e7+$I+Nu70 zn#-tpftn4oMJr~dC+b2+j#C}V&)BxAe{&V;gTI?KH^yD|(o21KZf2^Z(j7P~u$Qtl z-ufTo|3$Q8-T4vW-$skpN6tRFql;Fc<7XFZdxQ*+pFLsrNsDCD+L@Oa(q>nFa4%pT_O zA+8@jd-!aZy{FBd?%GG3{U{#;&-HiwWKA>I=A-5~j?P|%cFb7hHS>GBs86rjeDu7z z%|~b=e;y7t+kAAE&!#%ni~Q0>;21i2@PgUZr{8&9Cd|`tJCQ!I^_Id=ojtu?3i3XL=h)X$hZ_hWwgWXSHXogjUQKvDT(Dsa|oP zv-&sd*En4*a%0?OFTHeccy4B@qtYEXJg}FtG(P%&V(`hqCwvq6gu9Bsw0_dtI7&;vd&6@xQyrD=z!8DHl%?^} z|E$5;gR^`SIm=x|U|P@iHjdH~J|zwLHLuQU&sqtsm@i_jO=nWQ;y!2fZ`QAIx?1GM zxXWI8>E7_%%v49EJMgB!Udqz==zq@O+`&1%iJarEA~3DzdK*V+37?XN{F+y1wP&q_ zR?HW%)}}M5UU8qZ`Zw#>I9)ArW87sgy>xGQZf2^Z(j9nnU@v89y!D^nzuG?MSXKXO z!?oIVGc^3wcJI|2|6gry3GAh`Yy|HASKAi`=MBE#o5&X&TY#DEJa6MDE#XtrkYDra ztoE#x(2DsY*4lI?)hq6ER{v)G8mFs8Zj8J4UV7=?@Z8K)N2NP(WMD64X?*lQe{jLz zeBVUQcUKXZ)(gCiqqKxiNke|ktFzj(RzfT0i&$&ZnN+X1&sqJO^=q827P&F*vX@@E zH#|2p)lumVyfv_wvNS&We|2!-;H$ogeAQh=U|KKqHjdH~J|zwLHLuQU&sqtsm@i_j zO=nWQ;y!2fZ`QAIx?1GMxXWI8>E7_%%v49EJMgx^Udqz==>Ltuw+7$vP2?NyDgx8` zEpOu}E#XtrkYDratoE#x(2DsY*4lI?)hq6ER{v)G8mFs8Zj8I^rI+pv&&^DARJsF4 z1@=;w#z+5)2HzcAa6yxmC%a$BG%e;CeYtxxjuei@y{hRe`oURtRG48UL zUb;6tH#5~y=?=Uju$QtlKKfre_}So6-$X8TR}q-jpLrWcX$hZ_hWwgWXSHXogjUQK zvDT(Dsa|oPv-&sd*En4*a%0?OFTHeccy4B@qtYEXCa{;XG(P%YHn@CnnQtPOxvL0F z>*e0YQCh;Mq#?iN)miOXE1?zhMXa^yOsZGh=dAwC`ZZ2hi`*D@*-J0o8=jk)>Zo)F z-Wk|SSsEYxe>M2c;8(th{K{QLU|N6UZ5*W~d`cSfYhInzp0yHMF<-=5o6e+q#eL4| z->hHbbhXHhahJXH(!JrinW>ISci`B-Udqz==zqoF%E1-BiCp2XA~3C2dK*V+37?XN z{F+y1wP&q_R?HW%)}}M5UU8qZ`Zw#>I9)ArW87sgy>xGQZf2^Z(j9nLU@v89y!D^n z?>YRzv8sO00oUqjtI+U0ho7&2Z>Jv@*h^{I2;BdB4u2Z_W$-88ME>O10?cfG@ivaq z55a%ak^UM#<+X$rI+pv&&^DARJsH24(z2Y zjgS6+9sJ+mufB==)m=qkTK~`6I7&;vd&6@xQyrD=!0~~-l%?^}{~v>yxql4MM6~0q$LY>?+GIp+Q_jpS-tSup<+5Al=evheE%&PNh1;AR{%p5c#i_d92)IU{sTsQo??A0vX8?B<5r;f^Z;5~u8 zl;s&1aiiJIXK&=2$c@}@4uNUg+}k)xOZb#D7{$ab2C#NmF~a^fxVQa@zHIHE1vfkN7Oc@J{7S48TmD@&T7wE39XnXVy#W*;j;*JwD?*5Q+4ZVksDdM z?A6>lH{uuDjpiJ6l-_|81A8gcUVXHy<~EyK<(tSVcNKvdx0$zbl$P)*X~?g6byj=U zN@&G=5o>Kalj;@sIjeuOevQ-BA~(ie_R>rDhUaFcIx5|P_XYM+mc~c_>&#tm?mE7S zT*qBSU|O%|Z5*W~d`cSfYhInzp0yHMF<-=5o6e+q#eL4|->hHbbhXHhahJXH(!Jri znW>ISci^PJUdqyV>p#7pR{WD=RsFOA*Xq($X!x{Z%T*iyuQE>#?4`791n&Q7#Vu!V zK6^{wL~iN+_6BCQn|m8aX$hZ_hWwgWXSHXogjUQKvDT(Dsa|oPv-&sd*En4*a%0@R z_tH!EhUaFcIx5|PQv!P_OXID7`zd_uChzd-Gw`f$7q_2y*B$G-z4a-4-MzcEYTh5% zOSznV*xbL)y^%XVV)iB;$83u~h3}?wi?#R^zMIdLJ%#Ue?!Tk8?!LJ9>@DYRjHZzBi|JDf8`+ZVE;MfG*(PB{hbc%J|MJ6dw=Noj^l$@3wu9eo*J2B?*{^VDYeFUE@AK0_gCA$F8SWOexHEa z|K5w|pH9OQQ1!~<-n-cdf3>ymz0>go)T4T`_td~%%E((qmA$$T>F4+UTkm`C^s#s3 z*}Hq|-a8%a?R)S2U|=uha@c$Ad*#so-g~F1d*!g1f924=_fE$vhrajT(*k=bm&4xr z%33HSP_jT`w1A8f#!`^G(D~G%FX79gG-75$EtF8Tx*~ax( z+eZR>DVM`u`)Nfx&$N76A+kO{t@wYv**kroR*XjYw4#0QosLf{`rdm#8rVzOW?jiU zX4gLU_J7?weeB)Lv$y@8!*sB>?_X_a1ol!chrM^7`ww?7`VV(z6S=#;JKcRwZSCxK z44;yQIW#Y4ixRU%D`v5t9HTbQXmzTk2GVMDCj7kc#c^rTFMT5 zEU=eyDLELUOyyNnIc@AEZ;v zd&4s_UUSFvviGAs+53sWUdrX{<$roc{g*pG*!73{5%c}`+#?!e>Z5$*++vNskDqa zJI&$Af2a7Fb7=cGyMD(Ep6l=U$7ao33;#RC>W6RX+-d%O?%sQ+`OQa9F#k^R+uS!M z&vV)C>i+#=HpDRFtDNnE%)c<)tYh)f$2<3b%$&2_k{wJ`PvK?3Qp2M`U_c@il z?aLX)D}}wE4D6+BFLz^R@4l72?aR5s*!!u#Udr}zH)i(kSJ~UXoGXmIX9f0BwwJpx zv-bs+z3t1n!r1%iz+TGsayMr7?qAv4zMLzJy=MpZQnr`7F|+qYmA&oDxx(1{nZRDk z_Hs97_P(UDw|zNR7<M+m~~NvG;!idnwz?-I&??s>Lx{aj!#WqY|BGke_=@!HFA z*`t2ctwVW`CK5>FhnmfhelU!dnw=VJ9ic{y%PILCteGEJo zKlY!+vspLPu}|ll;RmjHRO@^0oco^P8{=oYZ>Dd(z^{ksyRbZ9_6cj=9cE?5l=mL1 z?m21hw^kDjKnD&E9HbCYHi*F6aP-Ju8ecrz3I-i5;d0vo~_@tT@bQTE+>2Y z-g{=f_qy%e%Wr9Y<$!HCVD{7N_1^oHz+Otf)jdxaw(h-c_I{$W*X?9wZ=}-!vkzad z?EPwBFJ+u*arCuC*t>WJ>rr3#+TBpR^8RYO*?MK~*8+PfyF0kB=8DSR$^TtWs_!{0 zOq7Y`fZ3BbTc7VaTo~9(Ihm*jXtVbe|F_yn?u^be&?$pc2CBm-eZZ$*W4@ET|4A-$ zyJ5CyRe#k%ua#-FuxUqC)O9Pg7F4Mol*kzKo|5>hO;<)AyEomrs;2J_d_Az2vTt0< zul>3=<+HG^zH;d9&B}Y_aNqU%%HbPNXNM|I?q7I4~`$G4x{t| zpMH(`j`RMCRO(eRtqnfxVP{<5GUd`fGZOJEQXqbnM{R zf$A_yAMokdnC}?xe~ioAZkR1v)n9ecYh_w3Y}!#3b=?ZB1y!mCB{Igm$0pdTE2EFy zo9^5=FXeccD_d!xbs(ojxuIFEX-pq&8JU`yvg}2_OEPTIEVHPH_wLn zSGHrlCFq)de((KPU$j8EkDu@NZ^VB$u$OXybiLGM@3*Fyy{{is_VQw0)9ii3s)g7) zTGfxe-wW)eY#c;%og3LKz^7khzM=OYy3Fl{*`ihbRR_IRrq#lx9aT}+tzU6C%&DoE92aDZ@P0; zP2U~(L0~Us-?)_DMV_IW<}zwtpk~8t zu&NjQ6@S-7u|DL%fvUCgDAi)m^k9VAqV~IU%!}H(|89k@jXvBVJ440gJ8*GeFJ*a# z7;&cO!x`?3&NI-NgEI%J!zg{gr(a{fGra#9E_1tKwrEv<)j_Y7X|=FvM^)5yE3}q~ zBeHqVOuTZ?m2qynH{H3artc2?FtC@hZ(Pdn`~Hr5u{)!e-h014w|L{d7oK`|)w^u- z&WpRQTGdPB`|jQge6jCZAMd@WS}TvTyE=Nn5^+Qq&vD(Tt$Xj)wb6$=)SahlN_OCq zz+TFd*tYM*{*L>7cSh$K=;Fb}1Jz-aKH$@@G2i#S|My+ycEfDZs{X2jUMtgTVbhMP zsOwf}EfGg#^In{|_v*?xx80lWTvgL|2YwXTOW8Lr<#(ay>{s0xooAp62Nw=hhf(@~ zPrt@|U-kZ9b(z}@vqh`=s}6dtOsj=WJF23tTcNc?9Ffg?VS>H7GR|%HraM>F^xc6U z2li6-jZ67`%X9V{?u^be(6<>^bg?&NI-tgL4O}!zg{g zr(a{fbG-jKE_1tKwsR&{^;aGATA5Z0n|4%1UAIDOi8vyg_uK?~b!D8}?oD^Ds_DA} zmj?Dy_Ki#V{mgUrQg=q@8R%z&pAA%pQTl*Szs7u*djCsZ=61tu(W?HcgI+7sYGKok zs;KK$Xe|*(Wb^(k!CqY%=eB#(ovUj4?!Zq2dnx(o99r$@*FJ<4jl-~uOv*)`rI?q5C3@#X`4x{t| zpMH(`&iDT3yUgu|*`ihbRR_IRrq#lx9aT}+tzV{Ai-W;8Rxcp)19ko`tAUq z&_mfbF6H+d&)HwOGdj;ezZv{ypgN4w2YmW9=KGcR|CP(!ZkR1v)n9ecYh_w3Y}!#3 zb=?ZBCE|!|-rpqHt1IK&c5k|KRZZU=_(iz)Qud8Y`CaKbdxblr^9*$5;L3sOFiIcr z>DQR=3h#e~%iM05En3xIbL+3UD7I?q7Yo4eke>M%+l z@afl>?>gT9Ixcg&VYX;hf7L;+m1(uGX-8Gmbt|-%h$FIjua{u2u8ecrz3I+XHGOyB zSAo5hedAJo-}SE-E^=pdo`JqQ`0hY;7^M&R^lQv_k@vsIWo|dj7Om>9I_R}Btrj-z zsEWF7h1L>rL^kht6R#X}Wt`jYO?R%U>AM5J4(z4u8<+C?vFGe1?u^be(2oZ{9;gnZ z^Z}oKjrlI|{+GDS?S|Q+RsB^5y;i2x!loTnQP-`|S|X0f=KXPky}B~aZTF@-SJm|0 zf!_r7Qud8Y`JLxE`vrGK=Nag{!FdDKVU#}L)2}h#7rg%$T;_JeY|*Ozs)JrD(`sSU zj;g5ZR%k5|M`ZJ!mte21jC0$)>CRO(eRtrufxVP{<5GT?_*c6>ap#|Tl=4|v_lvp3 z+OH;Ae>->O1TUOX&jU2v# z>st)B7_Nf&geV?4dw=Os>3LKz^7khzD>RVrY>{4VYX;hf7L;+m1(uGX-8Gmbt|-%h$FIj z2Z_JhbY+~|?oD^Ds_DA}zYFZ8>>HQz`=saWS#w(t&+#bbv#@Tlr#YNEw?3Zd;9ea} zYCGSf3*7muK}Q*@Jj}laiXO1k=Q+gvSvp!bI&Hz{IlQ*#FXFEZ?4?|KH6mp1?J9fC zHtLiAFRV`^F?#~IKG^&Fz+TGM6h%X_cbm#yvu~BXW-|<2AME`@U@xUfUku6KJ5=_X zy{qgsn_=MkVDBFTdnrx&Lb&a4yWzIJiEQist_F@NERI@>wsZ0M#vGi*MyD|&U?qk` zts>gAyZC%#KF*TL($p~mT4G4lDxy6YmI}lmtL%c)fmSLi+A8JfxVQ)2_^wM4R;>yJYK&ur#XE3S zU@v8Hf=R$G!(E5F_$IQ8yNbXQqu0by3hnCR^Nsm9ODaoK#|UVNAyKP{_WYbpD`F63 z5B1R1A~(isjf1k6UaW)F7{>~Wci^vqy_CfXCIR;t-fMUd-$d@=t|IWn=rwVaLicj< z`Nn*lC6%SAV+6Fskf>Eedw$NQ6)}jihkEF0ksIT+#zEOjFV?|ojAMnxJMg!_UdrMG zlYsjS?>D@UZzA_`R}pw(^qM$Iq5HY`d}BV&lFHK5F#=j*NYpB#JwIpDiWo%MLp^l0 z$c^z@dA2@t~Zz2zHR}pw(^qM$Ip$EG7d}BV& zlFHK5F#=j*NYpB#JwIpDiWo%MLp^l0$c^z@cd zaZvWsi*>LX<5*$w4*Vmqm$Ep)B;aAghYug-o5;i5RRo?Gy(W%Q=;1Ct-2lyRF%JK{$Vz=R=hP(MD zvYWe#z%iM{QESnoTztMU2WPR-Y0L;%i6K#|i1z%PO)Fv$We@ex)gm{>YmI}lmtL%c z)fmSLi+5lqu$Hno!6ab!;bVup`zErxyNbXQqu0by3O&}v=Nt2JmQUC69_pd1MQ)7O8V6-By;ujUF^&}$@4zO3y_CfXCIOEdK4JJc-$Wkgt|IWn z=rwVaLQin<`Nn*lC6%SAV+6Fskf>Eedw$NQ6)}jihkEF0ksIT+#zEOjFV?|ojAMnx zJFsbBFJ*CpNx&0_PaZzeH<2g0s|Y+XdQBXq(34$!zA+zXNo8s37y&IYBx)7Wo}aU6 zMGT_sp&q(gcdaZvWsi*>LX<5*$w4$KDjQWhte1Uz;4wBb{I6M3q;iog@2*Thi@ zJ@`8k_b#30HZ>Y=MeZj9F&2W2n4SO=>yjujT~z#y=f zvN*vc;OWC>44>|s$kW|b1fCeZCXQ0*87@BGn2)ohvNUy!fR-2%wTfuZ&)Kvh22u7< z4_z&CW4zWlD0}I}I#`Wytgv_o<^p>uixW%&o;7^-@L9fzJj-20;EB;|;wXil?c(!| z`8Z1|OH;=PXo(?FtBCgeoJ}iY5M>Yb(A6S0#%qm(vX@@0gVh+v3X6AO7}!f$oM000 z+~MHCh}5u6@e#4uZg1+dYOyQH|FCksVq$$BcLUQ zM6Dv)^K&+>h(VM+)I(Q`+!(Jl4$5A7u?|*a94jo|fmMOMl*I`q0S66VIXuWWk%Qb- z1fCeZCXQ0*l`cNtn2)ohvNUy!fR-2%wTfuZ&)Kvh22u7<4_z&CW4zWlD0}I}I#`Wy ztgv_oRtNS{7AKelyn6WB;j4WUd9}NWz!Rg_#8C>p*2U)=^Kq6`mZpvo&=NzURuS#_ zIh$6*Aj%%2M^ycJlHppgWXjGo*2C* zj#B6iEcdaZvWsi*>LX<5*$w4qQL5m$Ep433%u5 zxZ!)uwLQ^b_)*7?2_wwQ8!(R`tSTOd8S@)X4_2zNJtm=8T z9z_xiqf~~b&aHQZwY)hz#oSuIozTI~ng71pdSBD{p8|U+wVpWIY}~iP-w*#d z{Jn1?zju2B9AhnxT8sYZ;`5C;IE#%=V@AMA42fFZzYE}de$J*9F^IB9wV}->#aD%{J%Hjl*fIknf8vfZgkw3eu2s|-*O&q1rRW3f?n2)ohvNUy! zfR-2%wTfuZ&)Kvh22u7<4_z&CW4zWlD0}I}I#`Wytgv_oHV^EjEKV>9_}lRB!@v3F z{)H2F6@e#4uZg1+`n!wIH|FCksVq$$BcLUQM6Dv)^K&+>h(VM+)I(Q`+!(Jl4$5A7 zu?|*a94jo|fg1+)QWhtO0i#VuqD`Dc$C-!4)HUQLEJ~^4A;x&t=}?4>M?kN&GiYeuVm6It!9BCxeaoJMP0e7-RsXG!O=T1G%e42fDr zwCCq+S`mXNd#H!57P&F*vX@@0gVoqf6_@V77Jh(VM+)I(Q`+!%M+OE1>JYHX&8OLyR=fxVQa z@zMVVqZ^KH;G6q*Ox;xkw$_N#=!Pyn-h(VM+)I(Q` z+!%M+OE1>JYHX&8OLyRAfxVQa@zMXrqb)`^_D$r*?kWOXYs6`^g^SNO=Ho2sJXXsH z=!hXvtNRy)eb3L?v?2yk_D~O9EplVrWiP#02dlA}DlXlDn+Nt%mc~c_n~iQUx|wex zH*;4J*jgh_qg%N6d}BV&lFnnbjDU_9619qG&(GPkA_h_RP!C-#a%0?OFTGd?tFf6X zF5Q7!1ol#v#z+4xN4Fkr>6^%w?kWOXYs6`EYZsqy%*R>Md90QZ&=EtTRuS#_Ih$6* zAj%%(N%eiEQPrBCxeaoJL!__mTmViNr?LW$$jI-A0cZ?Y>~Fev8bc@DSe`!}q&*<~O}y zrS9KSzGL>-(c?ys_02uQ)?FoF&4#nZQESoTTztMU2WPR-Y0L;% zi6K#|dlsqh`8k_b#30HZ>Y=MeZj8I^r5Ed9H8xYlr8{uzz+TGI_~`$H(Gy2c@J-|i z?kWOXYs6{vL>HfL%*R>Md90QZ&=EtTR`)DY-}7@et%yOCJ=8;2i`*D@*-J0h!D?)# zic5Fkp96a-OXH*elSfY-J=r(+3|n^7%Fl=AL2et|G9tMw~`Z zck%hge4Hhn$7&e?9Wf+obUC69_pd1MQ)6{?4=j$U^O;V#icuNyTD$`()j5A{Lu?X&-cweqt;zT zU~7#yjb7;D^Nsm9OFEC$G6FhcNYv_{wCj6*&ZZSHh_Z)z=xUK0<1TyY#X4Ax%~Wye z4%|Mlm$EcI`X4ZQ@#p~G+%sz3RRp%yh|}oBEYIB;t-FfA)*5jdz0Aeu z8}o6NbRMf^1a!oZsMS4b*Z2IKO)Fv$We@ex)gm{>UG~z8b+8(nsp8Td_?N(5%F_7g zf6(Zaql0{N&!}}*5!hNIPNP@4_4A;x&wCz?4>M?kN&S7y>|3!-`q25-Bkp()`-*SwJtv2n2)oh^H?n- zpd*Gvts>guJ8Fd zn^wdi${y;Wt3_^%yX>VG>tHoDQ^ln_@UMZrl%?^}|A^6>M@RVPzP;zJBCxeaoJMbU z@%hGloF$#dY8e3?F(hhrPoeWYKWEd57)04aJ#@9mjd7Q~^kN;X#%8LxbO*Kz?4>M? zkN!uF-ZnbYH}{NMcNKxHHR3dSn~Tpk=Ho2sJXXsH=!hXvt9#O}@A)~KR>UC69_pd1 zMQ)6{?4=j$U^O;V#icv&Z-Kp(rSZ}K?W1>$-tL=wMyYb(A6S0#$EQ(i*>LXo2lZ`9oRmwm$EcI`oDAZuF*Sv z6M3h*ion(yaT>kL#pfIIah7x*t7Qaq#E_^}M0<4I#`X( zRB`DJ+$pe^vNS&WzkBqa(Yt*UdAGZYz}6aZ8okHG=Nt2JmUJGgWdwA@kf>Eedw$NQ z6)}jihkEF0ksISKd+EhGSdGn8ap?}+Ik1BTx&jm=bX=?>f_u$QtlKKh?L zdjIHT-$YJ!R}t7+BTl3DyZC%#KF*TPW3`Ncju;ZPifGTz*|Z`CQT9*|T`h8B++{Dl zSO=@InJO;bfgJ*SDNEy{{|81N9DTqykq@}52yCqpr_l#pe7-RsXG!O=T1G%e42fDr zwCCq+S`mXNd#H!57P&F*vX@@0gVoqf6_@V7T?2b5OXH*ehejVBeaJWWubQ~42yCqp zr_qO9e7-RsXG!O=T1G%e42fDrwCCq+S`mXNd#H!57P&F*vX@@0gVoqf6_@V7j)A?D zrSZ}Kqoa?FKI)suN8MEfw$_N#=wmKE-h(VM+)I(Q` z+!%M+OE1>JYHX&8OLyRIfxVQa@zMX|qyHIw+&7VryQ>Intr4fu|G4;kV?NH3&SSNV zfQ}dvwTfuZ&)Kvh22u7<4_z&CW87sgy;ujUv6(6^-GQ9~dnrrfqyMKypB{b6H<3@d zs|akZ5vS3oU3|VVA7@GDv06qzM+}KtMYQMVY+4b6D0`@ft`@m5?y{F&tb^6qOcj^z zz`qCfQkKR?|Ids*JNk@oBA;gfxVQa z@zMXAqi>JC>6^$m-Bkp()`-*S+b%xen2)oh^H?n-pd*Gvts>gsiM?W9^)Hjizx~m9mtr4fu&s}`JF&}41 z=doHwKt~LTT1B+y=WJRLgD88bhpra6G48ULUaW)F*i03d?!dhRdnrrfqyH~Pza0I- zH<4ess|akZ5vS2FU3|VVA7@GDv06qzM+}KtMYQMVY+4b6D0`@ft`@m5?y{F&tb^6q zOcj^zzr{ zM}Hpu(KnGlx~m9mtr4fupIv;uF&}41=doHwKt~LTT1B+y=WJRLgD88bhpra6G48UL zUaW)F*i03d?!f&6dnrrfqyJT-zm2Z)P2?(f6@jfa;xzi3i_bUa<1FbsR?7(Jh#^s{ zi1z%PO)Fv$We@ex)gm{>UG~z8b+8(nsp8TdctBt;Wodl$|NBVBe;=WVXvdj{#niRr zSQcr_!C6}Ii6J9kB8GH*>{QwpnYB?BVi08yA0O8Zk1l&POPJe5vl^SI;?f=X&%j>F z()j4V$#{0WiEkpCxGM~7tr4futc%Y#=Ho2sJXXsH=!hXvtBCgeoJ}iY5M>Yb(A6S0 z#$EQ(i*>LXo2lZ`9e7}1FJ)BTx&jm=bX=??r?U@v89eDt3muO83)CNl4?BCxea zoJOl%e7-RsXG!O=T1G%e42fDrwCCq+S`mXNd#H!57P&F*vX@@0gVoqf6_@V7g93Xg zOXH*en(=kVYkU(~4A;x&sdm?4>M?kN(#m-(Y-w-$btOt|G9tMw~`BaPj%Ze4Hhn$7&e? z9Wf+o715rbvuQ;PqU@m_x?1GMxXWI8u?|*aGgVx=0}l!8r7Vq){_6&(4%Yc5vTlHm zGY^ZYYsynye7-RUXKBW#MvQ=s7!tLLXwT2tv?2yk_D~O9EplVrWiP#02dlA}DlXlD zhX(dimc~c_8;);0zM*d-H+1(PU~7#yjc)AX^Nsm9OFEC$G6FhcNYpB#JwIpDiWo%M zLp^l0$c=HAz4T%otj1=lxO4{|7T8N!8Xx_)7~gEXg>NETxT^?ktr4fu&0KuGF&}41 z=doHwKt~LTT1B+y=WJRLgD88bhpra6G48ULUaW)F*i03d?!bQs_EMI{NB>)lw;bQX zH<4Sos|akZ5vS3XE9Q zrix2<;NgM2l%?^}|JLKJ#<%uOL|`vvX?*nGdVIU_*1m~s?XDuQwMLvqw{!9N z#(bP5oyTe!0Ua?UY8BC*pR;L245I9z9=clO#<4A;x&ylf_EMI{NB?cc zcNlNuo5(iqDgs+;#A$Q~7oTs;$63;OtdVG z>tHoDQ^ln_@W{Yk%F_7gf6U<6!7;vx9OK?O0=CwO)96?ipKr{^S<-o|mJ!eqL!wp@ z?fE&IR>UC69_pd1MQ)6{?4=j$U^O;V#icv&sK8#z()j4V?RdNKw!VpM>+V6o)*5jd zZRg_ijrllBI*-*d0y<(y)GDGqKWEd57)04aJ#@9mjd7Q~^kN;X#%8LxbO#fZz9{fs|akZ5vS3eU3|VVA7@GDv06qzM+}KtMYQMVY+4b6D0`@ft`@m5 z?y{F&tb^6qOcj^z!0v&)l%?^}e~0mo;~jhx*}+{!U~7#yjdpbL`Nn*lC7s7=837$J zBx)7Wo}aU6MGT_sp&q(gYb(A6S0#$EQ(i*>LXo2lZ`9e8YD zFJ)v$L6M0Rmk5!hNIPNQ92e7-RsXG!O=T1G%e42fDrwCCq+S`mXNd#H!5 z7P&F*vX@@0gVoqf6_@V79)Z1-rSZ}K9^-qB@8O%sJ=|3Uw$_N#=w2>9-h(VM+)I(Q`+!%M+OE1>JYHX&8OLyRLfxVQa@zMW2g9Qrix2<;0b}fl%?^}|3Tx2j34Bi$b;Nf1h&?Q)94{CKHr#+ zv!wG_EhC^KhD5C*+VgWZt%yOCJ=8;2i`*D@*-J0h!D?)#ic5E3&%j>F()j5Au<^sk z5A#jrVeTpdTWiE=^l%rSZ_LM8(s`_w5zrAsqE->@`8k_b#30HZ>Y=MeZj8I^r5Ed9 zH8xYlr91G%z+TGIciY8BC* zpR;L245I9z9=clO#<4A;x&u!R?4>M?kN&%jA2r_1H<8`k|3QJRHR3dS zl#9Yb(A6S0#$EQ(i*>LXo2lZ`9e7G$FJ)<4I#`X(RB`DJ>=oEcSsEYxA2)u&_;J38JkI?e6xdoLPNOHd_1A8e;sm$4?tS)i;r+x~m9mtr4fu(_DPMF&}41=doHwKt~LTT1B+y=WJRL zgD88bhpra6G48ULUaW)F*i03d?!YqwdnrrfqyN*#&lo@5H<72is|akZ5vS2JTztMU zA7@GDv06qzM+}KtMYQMVY+4b6D0`@ft`@m5?y{F&tb^6qOcj^zz%v7TDNEy{|Fg!= z9zV-Bk!QK92yCqpr_r-re7-RsXG!O=T1G%e42fDrwCCq+S`mXNd#H!57P&F*vX@@0 zgVoqf6_@V7vjTf5OXH*ebH~pcKi4;r=eny1Y^@Qe(eqqgkY#pfIIah7x*t7Qaq#E_^}M0<4I#`X(RB`DJJSVW1vNS&WzjXYv@k@OZd8xaKz}6aZ8okWL=Nt2JmUJGgWdwA@ zkf>Eedw$NQ6)}jihkEF0ksISKd+EhGSdGn8ap?{`H?WtoG(P$tG=AmyAm2m|a#s=9 zS|d)QSGxFoV?NH3&SSNVfQ}dvwTfuZ&)Kvh22u7<4_z&CW87sgy;ujUv6(6^-GO}r zdnrrfqyMYNuN}YIH<4Gns|akZ5vS2>U3|VVA7@GDv06qzM+}KtMYQMVY+4b6D0`@f zt`@m5?y{F&tb^6qOcj^z!1DroDNEy{|H0!oj1TrrVG>tHoDQ^ln_@Pfcz%F_7gf8_XW<0E|&InrH4U~7#yjo#+s^Nsm9 zOFEC$G6FhcNYpB#JwIpDiWo%MLp^l0$c=HAz4T%otj1=lxO4|z7}!f$8Xx`NK7Pme z?Y@b;-CadsYmGRK-r?f&jrllBI*-*d0y<(y)GDGqKWEd57)04aJ#@9mjd7Q~^kN;X z#%8LxbO-hi?4>M?kN)o*zia$X-$dT&t|G9tMw~|Pa`E}be4Hhn$7&e?9Wf+o715rb zvuQ;PqU@m_x?1GMxXWI8u?|*aGgVx=0|x~5QkKR?|96kyGk&*kBJXxr5!hNIPNVm@ z_8R?kWOXYs6{veixr_%*R>Md90QZ&=EtT zRuS#_Ih$6*Aj%%LK72ge`qP2>aaDgs+; z#A)VG>tHoDQ^ln_@Y29u z%F_7g|Do}R#~<=dUC69_pd1 zMQ)6{?4=j$U^O;V#icuNU|=t0X?*nm==fvfkNPI^QFj%Atu^8_`k0H)H|FCk={#1; z2g9Qrix2<;Gn=>%F_7g|C#Y;$Di>{UC69_pd1MQ)6{?4=j$U^O;V#icv&iojmV(s=9t8vhLE z*SYiS!_%CtbuoO{++ywUN!B;by=8)PdHM9|w>s~mTtC|NV_ZMhbson#e0&&F(iWw) zoG^(#ae_{oJH_FXTwgc0Zm!GTQ|Hi5bN17H3_KS<_MhE<13smCpTyIrAGKM!s(Xef zPM__b{=D@9PpD2uwzV$~vod4bj`1F=?m1~95d*pBdrzMG@yftn%2cj}b$4m(?d?X} zjP4Mgv5lDjZQZ37&I8MKqs3Z2K4m3)t!;Z(;hlYz`}yj3aCpbjPNSWj+{N`>NB8j7 zdyVex!tOJ=-{=9O2aX;zddTQuUjJ}^wi&y)%ii5ayNw<-+I_*;BU~-$&Etq!)$?pU zU}HPiGeSqH3{9QLCq|bJ-M8U7>=pTTLWgM1{P$%sw_V3_$FBBTx&jm=bX=?=U)@RYJNKKg%Y{N?eNd=vSSyNbZp8gUwZ*~RA@^Kq7R9;;;pbi|OT zRYZG!&ZZSHh_Z)z=xUK0<1TyY#X4Ax%~Wye4!kC?m$EcI`hR8oweeSc6Zwj}ion(y zaT<4I#`X(RB`DJyf(0x zvNS&We|`MT@z;G5`MSG`z}6aZ8hz8n=Nt2JmUJGgWdwA@kf>Eedw$NQ6)}jihkEF0 zksISKd+EhGSdGn8ap?}cF0hxfG(P%&d;Fd8w|#T3{oPdrw$_N#=sPYx-h(VM+)I(Q`+!%M+OE1>JYHX&8OLySlz+TGIcui0y zc(HdJwp;M;^=>X|>U$1&AA-9PI(lUaJu9@haZf8IR1feB0q4v1&;e= zanxG$Ll>WK%)wb~bQ&`PR$@rhDxy6!|pNxOxo5+vcRRp%yh|}mNE9Qrix2<;E=#x%F_7g|I_i$$3OK=UC69_pd1MQ)6{?4=j$U^O;V#icuNXkag8X?*nm#rT)wU-%~S z3wITPtu^8_`lXA{H|FCk={#1;2<4I#`X(RB`DJ93I$9SsEYx|2Y2h z_>aDc{Lx)SU~7#yjsEQ7^Nsm9OFEC$G6FhcNYpB#JwIpDiWo%MLp^l0$c=HAz4T%o ztj1=lxO4}O2<)XSjgS6UjsG^j$~Td#+*Jg&)`-*SZ!SLHn2)oh^H?n-pd*Gvts>g< zb2hDrL6kkzLsyI37Hdy_BW#(f{vbng9D3O+-7+JS?WJCFf<4 z#vGib6`vR~0w!We*XNx|`y#V8szMB+?BV0%y5Z4fuVx8zyJ%Kp6IEQg18)xOr7Vq) z{+rCt&TrzI$R_Rz16ymvX*BEN^Nsm9OFEC$G6FhcNYpB#JwIpDiWo%MLp^l0$c=HA zz4T%otj1=lxO4~J64*;w8Xx`V=122$zKP7as|akZ5vS3}#pfIIah7x*t7Qaq#E_^} zM0<4I#`X(RB`DJ92wY4SsEYx=jT_?>*4aHTNwMLvq zt6hA)F&}41=doHwKt~LTT1B+y=WJRLgD88bhpra6G48ULUaW)F*i03d?!a3Ednrrf zqyL)u>&~z7O=OL`ion(yaT;CM#pfIIah7x*t7Qaq#E_^}M0<4I#`X(RB`DJye+VovNS&WUw{4v^Vj!HUC69_pd1MQ)6{?4=j$U^O;V#icuNRA4Vh(VM+)I(Q`+!%M+OE1>JYHX&8OLySy zfxVQa@zH;a`J2se;hV@7?kWOXYs6`EGZ&w4%*R>Md90QZ&=EtTRuS#_Ih$6*Aj%%< zp{qr1jJxcm7wcd(HdDo=J8*PhFJ)UG~z8b+8(nsp8Tdct>C_Wodl$zxDi9^SAa* zh(VM+ z)I(Q`+!%M+OE1>JYHX&8OLyS-z+TGI_~^gO{I2u6_~xD@>aHTNwMLvqySn)Q&)&7b z+cwny+2`!D@40)Qdy`yAUJ0p$BuP?9k|e3T63QdWD5GqBI6iJf2@=B6$y%PRj zNkZNvBuSDy{=eVMeAoQux8|&~*SXj2oONf-XYJqbH^0aHX6CzR&t7}&y{il2p_OzT zSql%Y1J9ImrQbTWXLXygmVMYu9?rt`mSeMAMlY<82eOfoGGBKDPV(plt?M7`SMRRT zUELOAR;O8HUTOoM=GGwp>VkM^B^^iB!h`F;Gv!>3ac6a#v6g+G753Qu*$Xa-C9eAdk zt1<4ZZZp=h4|~bOS-9SEY?jODg%$EZHZoG?>yE(59=)J-{e%75-F3Qa+hWYxG>gnj zZQ#?~I^-q=#b-U|z*R{o%b!irvm)gLmx%J4ux*#4}Nym}3@ZdV|OgUF$+*#dbtYshe zl83W!z2(>}m(dF=#lE$G3(PTGB34(Pjeq5|LTHx zXeAv-*2079z%%7sjd5pno3WOC*h?PH!u6J8vs^|mtdIw?k&!ZAcLaXs(Fv&g*E20qPgME=zU@z6>-j;w_T*MVosxfNaC7`>>ZhoQ3Nx$7Z>V zURWUyWFsSGzU~N|>d^~Y*FV^A(%rPXi7m!#LbJ%c)CNAyZA$*t1@X{II*zP`2iJjT z%DEcj&gwQ}E&H&SJe-B=EyrfLj9yqF4`d@FWxnnRoaWIBTGwCN=l^TV|JNq*kmlbt z8~?BEbdO%pbc>_a%KvNIth+^bGh2+=jMgCLgP-I>t>m^K|LTGmXhnLbd3dlEJX6lq z7%X{$Vi#5I|65T^n%v)5B8t#Zq@y?EyjGBW|4WR z4Sbs0iu|h!;-Qsv99atwt^?1Mb2Y}D)osRF_F*r1I1ATXj?Hozy|6+a$VNuWeBBW^ z)1w!(u79xKrn_x-8(WOohGvm@sSSLZ+m`&R3*w=bbR1a=53U2xlyf!4oz-o|TJ~Wt zc{mH#TaL|g8NIMV9>_*U%6#1s__;?fXkGtc|Jm;L-Ot)$%x7s9nU~tYr@8IPzq%kE zT1m%|wea9N@Ju;ZW87KYW~^l&_L7IQaJ}W&ESJ#>E98M}WTed39f7kvdO_>@2m2kn zJ9l@q#h4vw7MYjYz^A#L$-lZF9$HDqk+tyPI`B+6S7Y2+-Da$1ANG=mvv9rT*esXP z3oGP-Y-FU&*BybgJ$gaw`Um@6y1RCFvBj8OXcn25+Q6r|UCF0x=WgqsEhqG|K<=8Bj(F-f&fox=?%-0=(b3A%M>-q=#-Mf2qcellu-Dwt? zm)gLmxjo3gx*#4}Nym}3@ZdV|OgUF$+*#dbtYshel83W!z2(>}m(dF=E98M}WTed39f9*adO_>@2m5`y`*ruV#h86*7MYjYz^A$W$iKQE z9$HDqk+tyPI`B+6S7Y2+-Da$1ANG=mvv9rT*esXP3oGP-Y-FU&*Byahc=UqS^$+$3 zbPwzvV2d#a&@3`9wSiA_2av%1Y#%RcNS4`<;m*7Xne2X_zY9&C#-2h%JvFSUVBbBBAX=1+D8J><{aHy?dA~#vDeo z$h_1BKFxid{HqJ%p_OzTSql%Y1J9ImHO8IQZN^&mVJ~?&3)fqY&2kyNutFZlMn=kf z-4VFJqZhQUf3QEi`>pQbwit6b%_8$s8~8N$E%L7}h=*3vabzt#xDGs1&ea%qR<{{z z*@wO4;VfKlIX25>^uh{xAR8Ge^L0nyS025fb^U|=k=>)ZN7`b{ku;0UOKsrO+)?CT zT@Vkgq~pk1cyJwfrktxW?yPPz*0K+K$-`N=-g0b~%jks_@<28+Qs(Q9z=a;YpmqI& z{n6cHx<}h$%+WN9%u8+H)7&xSUtJInt)%0~T6l0Bc&41IG48BxGuE;Xd&$FDxZZMX zmdogc74kqfGE(O2j=--ydO_>@2m52YKj(flqTkAph!ucxWXZN7llF z>%cSRT#a#Ob(^u4eb`GL&cgMUW3yaFFRYLUvXPN8Uv~s9^5_Mv>mTfo@1D>--WFqy zr&(lPY6G9>n+D-xr|;|ArE9DBW1qs2wd#Z3tHDd*q_`zrF*h1#+*#E$h_1BKFys% z{?!HX&`LUvtc3^HfoICO8spCDHe)UOu$MfXh3hTHX1R=BSRoH&BO_(L?g(7s(F-j;w_T*MVosxfNaC7`>>ZhoQ3Nx z$7Z>VURWUyWFsSGzU~NI>d^~Y*FV^w**&X!rY**tNwdhj)CNAyokjlD1@X{II*zP` z2iJjT%DEcj&gwQ}E&H&SJe-B=EyrfLj9yqF4`d@FWxnnR%=G95t?M7`&*`4mJ;xSf z&Y@XkUTOoM=FTJk>VkM^B^^iB!h`F;Gv!>3ac6a#v6g+%cSRT#a#Ob(^u4eb`GL&cgMUW3yaFFRYLUvXPN8Uv~tq@aP4t z>mTed?q1rx*cM|hrdecOY6G9z04M4E~8mwUTOoM=B^VkM^B^^iB z!h`F;Gv!>3ac6a#v6g+y{>zWEyi3!v&g*E20qPQNB-3X@z6>-j;w_T*MVosxfNaC7`>>ZhoQ3Nx$7Z>VURWUyWFsSGzU~NI?a>Qb*FV@_-@UPWy)DLEPqWCp)CNAy z-AMk`1@X{II*zP`2iJjT%DEcj&gwQ}E&H&SJe-B=EyrfLj9yqF4`d@FWxnnR{LZ5n zw61@!zqxx$_hws+xtV5>d8rM2n!APks|(_xm2@0g3lFXX&y;gD#+}t|##;7aFL^i% z*ISOwav8m_LLSIQM#_BM5xB;q7qqT_u)no?TlZF5jJcI&k$I^Ne44wB{HqJ%p_OzT zSql%Y1J9ImHO8IQZN^&mVJ~?&3)fqY&2kyNutFZlMn=kf-4VFfqZhQUf3Uy3duR7{ zTa3A#W|4WR4Sbrrll-d-;-Qsv99atwt^?1Mb2Y}D)osRF_F*r1I1ATXj?Hozy|6+a z$VNuWeBBYa&Z8H!u79w_*U%6#1s_&<+c(7OJ?{=V)5-TQ1Y=02K5=A}09 zY3>2?uP%s(R?=}~Ej+jmJX6lq7^uh{xAR8Ge^L0nyMvq?5y8glb@$M7d z$89m@ahgTur8e+s?g{d*E{KO#(s5)hJh%=#Q_j^GcUHFkoB-6w4^=1H1G=A}09Y3?cVuP%s(R?=}~Ej+jmJX6lq z7gnjZQ#?~bL3xL5D%@Sck&|+$)iruo*APc23k@6 z2@xKw0?(Ar9#y$>j8>zp*oVF3Vf{nD*`kbI7sav%1Y#%RcNS4`<i1 zW`3GQ=A}09X>I}XuP%s(R?=}~Ej+jmJX6lq7RUeLP!!G6KsLcIlTF=j!UMdqb8@M&%#@~^uh{xAR8Ge^L0ny&mO&? zb^U|=;=Lt$i`!z%;xvoQOKsrO+!EwpT@Vkgq~pk1cyJwfrktxW?yPPz*0K+K$-`N= z-g0b~%jks_@<28+Qs(Q9z+E1_pmqI&{ZhT9drR43%u+Oq%u8+H)7;YJUtJInt)%0~ zT6l0Bc&41IG48BxGuE;Xd&$FDxZZMXmdogc74kqfGE(O2j=y`XjdgZ&$N%k%cSRT#a#Ob(^u4eb`GL&cgMUW3yaFFRYLU zvXPN8Uv~uV@#qDu>mTfw?JeJ1))r%yrCDTNY6G9VkM^B^^iB!h`F;Gv!>3ac6a#v6g+{sfo+*`>OV^*SBWL|0mpXOF3|LTHxXeAv-*2079z%%7sjd5pno3WOC*h?PH z!u6J8vs^|mtdIw?k&!ZAcLeVD=mo9oAM97@t=e0~7GqYSS!7;n1E1zrCI9MzcxWXZ zN7llF>%cSRT#a#Ob(^u4eb`GL&cgMUW3yaFFRYLUvXPN8Uv~r^@aP4t>mTe_>%F_T znk~kxMzhGg)CNAyy_@{23*w=bbR1a=53U2xlyf!4oz-o|TJ~Wtc{mH#TaL|g8NIMV z9>_*U%6#1sc+jI4w61@!U%j_RZ*^OYS)FE)d8rM2np=bXs|(_xm2@0g3lFXX&y;gD z#+}t|##;7aFL^i%*ISOwav8m_LLSIQM#_BM5qQX>7qqT_uwS#cR&PyPj9HUrk$I^N ze41N}{HqJ%p_OzTSql%Y1J9ImHO8IQZN^&mVJ~?&3)fqY&2kyNutFZlMn=kf-4XbU zM=xky|6sp%Z=K%SwivTE%_8$s8~8N04*6FX#6v6TII zE98M}WTed39f3zYdO_>@2m1|r8}&A@#h49f7MYjYz^A#5$iKQE9$HDqk+tyPI`B+6 zS7Y2+-Da$1ANG=mvv9rT*esXP3oGP-Y-FU&*ByaJJ$gaw`Um?>dYkq(vBj88Xcn25 z+Q6r|P07EyARbyt$C0)0;5zV3Iag!cS>0x=WgqsEhqG|K<=8Bj(F-f&fox=?%-0=( z$2@vL>-q=#&3aq(HnYW;&1e>xm)gLmxh=@Qx*#4}Nym}3@ZdV|OgUF$+*#dbtYshe zl83W!z2(>}m(dF=}m(dF=p>r znU~tYr@5WUzq%kET1m%|wea9N@Ju;ZW87KYW~^l&_L7IQaJ}W&ESJ#>E98M}WTed3 z9f5y%^n%v)5B9tCcJ1wAi!r;(flqV0l7DqUJhYOIBWvNob>NwDuEw~ty3JV2 zKI|nAXW@Fwu~{yo7gopv*~mzluR8)ydh~+U^$+&D_x9-RZi_Ly(=0MCwSiA_dys#1 zK|HjQjw5T~!FAx7a<0a>v%1Y#%RcNS4`<VkM^B^^iB!h`F;Gv!>3ac6a#v6g+$4WL|0mpXT->|LTHxXeAv-*2079 zz%%7sjd5pno3WOC*h?PH!u6J8vs^|mtdIw?k&!ZAcLe_B(F-j;w_T*MVosxfNaC7`>>ZhoQ3Nx$7Z>VURWUyWFsSG zzU~M-?a>Qb*FV@F+&iRqur0v%1Y#%RcNS4`<bwNC|l8z&5;lXv_nR2eixU;&=Sj#@_B@bueddsm{E~6J#$OGBP zNSUuY0{`{s1+D8J?2qmJpm(e-#vDtt$h_1BKF$4r{HqJ%p_OzTSql%Y1J9ImHO8IQ zZN^&mVJ~?&3)fqY&2kyNutFZlMn=kf-4S@sqZhQUf3QEkcS7%YTZ}oLW|4WR4SbqA zf&8lr;-Qsv99atwt^?1Mb2Y}D)osRF_F*r1I1ATXj?Hozy|6+a$VNuWeBBXv-lG?^ zu79vUv3FAML|cqGk!F#3sSSLZJBj?O3*w=bbR1a=53U2xlyf!4oz-o|TJ~Wtc{mH# zTaL|g8NIMV9>_*U%6#1sc)_C=w61@!Ke=~G?_^tyIhkgWd8rM2nmdL3s|(_xm2@0g z3lFXX&y;gD#+}t|##;7aFL^i%*ISOwav8m_LLSIQM#_BM5qQy~7qqT_us^kTdhb+Q zj5(ENk$I^Ne40C*{HqJ%p_OzTSql%Y1J9ImHO8IQZN^&mVJ~?&3)fqY&2kyNutFZl zMn=kf?GYIC9-y@Yz~Ri^S-mrDG3HE~MdqP%H9<;oXOVw(K|HjQiW1ksgKNPv@2m6bAm-a5U z#h8m}7MYjYz^A!O$-lZF9$HDqk+tyPI`B+6S7Y2+-Da$1ANG=mvv9rT*esXP3oGP- zY-FU&*ByZ&k6zHa{=xpT-W9#eY%%6CnnmWNHt=cg3i7Wmh=*3vabzt#xDGs1&ea%q zR<{{z*@wO4;VfKlIX25>^uh{xAR8Ge^L0m{VkM^B^^iB!h`F;Gv!>3ac6a#v6g+E98M}WTed39f7GHy`XjdgZ<6DTY5L! zV$97ni_A-H;M3eKG753Qu*$Xa-C9eAdkt1<4ZZZp=h4|~bOS-9SEY?jODg%$EZ zHZoG?>yALzqZhQUf3Ux`cU$jPTa3AtW|4WR4Sbrrjr^+%;-Qsv99atwt^?1Mb2Y}D z)osRF_F*r1I1ATXj?Hozy|6+a$VNuWeBBY~dGvzT^$+&9_wMZ7Zi_Lu(=0MCwSiA_ zcanc~K|HjQjw5T~!FAx7a<0a>v%1Y#%RcNS4`<2?uP%s(R?=}~ zEj+jmJX6lq7;od{G z81oR#BJ)xk_%!!0`BxXjLo4YxvKAg(2c9YCYK%Lp+l;mB!(Q@m7OuA(o8>ZkVTC-9 zjf|A}x+Cy1k6zHa{=xo{-ebK-Y%%5$nnmWNHt=cgG4ii2h=*3vabzt#xDGs1&ea%q zR<{{z*@wO4;VfKlIX25>^uh{xAR8Ge^L0mH9*2@ zpmqI&{gb_?dQaM7%#$>W%u8+H)7(?!UtJInt)%0~T6l0Bc&41IG48BxGuE;Xd&$FD zxZZMXmdogc74kqfGE(O2j=;Pgy`XjdgZG753Qu* z$Xa-C9eAdkt1<4ZZZp=h4|~bOS-9SEY?jODg%$EZHZoG?>yE%HJbFRv`b+y~?Yw@d zW6X!?jE|3YK3=MeEjH|oRban)d*d-;!E#|Rf_{>GpXJdt#cb<`*iauzMwA?RxADABd18Z?@kdB*r;NZN3USlpHwC<|V zdx?!UI(i?Q5+eO?xfve4pvY!%Uq2r7&O3q8YfMJ3F~?0kYw+dOqMMxxtUp7#wCY3*$WdSB^L3W{N$74*)Z(Tics=oKR|``HCNdO^{`te|&+j9v^Q z(Y*GG!I;hLt2}x^5q?(CyI@8yhLLDSuNaKk%r5BB3yScwg5HHPdNGVdGkV2f%x3o0 z9=)IlKOXe{#$FG)q_fD#1x^EN4bhD?Z@U3F=csF_l#i_W579T%&Nny`Ld8lFK8-O zzje6YoBFh3qFnFISIl@ekDGeP;J+Ji#SCjKD3JO-zc$pl-ix(&@d>>4E|J$>OtG1` zYwx%FTzePsYcFWgwQ(>&?@|*Oy-R2G7Bf3>(R*8;=v~yK7qsZwIGDV1z@U})z4_A$ zjLqz%i+S{dA~tps=pQF2$|2LmjtTlo5y%_O{yYJnl&rd6s_2>mf&&EUNBzo8GYi%!oGidgr zcXGaKyU>5LXX2uFo<7mLoJTL{cu)%;pm&|T@5PW1&HG+47=oQ0JBQ^xdO=0_+APq! zZbq*dyNq5j7=oQ0=zX(CFQ^D#n+1C3#P#01bErK%g~P<(IefX#ox=(qy`V)G$H7SS zuGiPTR5tR`ziZ=f#LwP+Z@%UrXRsbWJJ#N}c=UqS%OJLv=v_af*AGtKIm9S|G&|6{ zqDL<%VvmPP^w#&!Yj6EAn>CM#d(Gj<;dhf@5hS$(O7rsY_TzR$Jy?H;|LB7ALj?n7^0 zduxNFaHvA>iGA*SSMlftErO4O$>`1R+WLo06?(Vn6TR>7=mqV+^|EC~Z$@t!6{FQu zq4!@?``h=f>d^~2T3h|pXY^+D_Jb2=Q-$82^m)DaogTfQ{kLAW%;?SNEu&(znkw|Z zvCnsHt9kT-j@DK`^%=bxz5U?C*;JwTYB>&jgfrbd+q~<3@gpGFK8-OzjbpTdVgAAFr&9$l)$bEy=EjJwhF!P@#qCb?D5dN za~OT+uu1-2n}Sr;&f$_i_r0ro^n$7;YKeL6%{zzw0aLa1?$qbn`(BS;(EeL5Th4uJ z@215LFyEz9#zS>Y)!O@uKHs&i;n53P-D0(N?n7_>q_`RpRoW`_Zrv?b>xiRjNbn7Qia}w``kIa-=i0_|JKWv8NC_3 zWmJq-Q-$8|^@-lKJbFP#Ypb97e9a+WbLa;r&Zg>`!_SM)D%dJq`_-RTe88g@wEx!2 zmU->XYi}79qt#Tcy$kpG-HNq6dO=5PtDpM3_U5&>ADlRws->v;5nj@DK`^?B{hYi~a|aW++J?^S)Sy&v-E1?|7}vSnU- z^V(ZR#b`BEYwwGF{%^&)9=)KWwbf63MsG%MKR9tVRp|Y0pP#jT*rOM;|JKWvdFPOK z4rNq~R#UZeSfJ0lbk_6e1s$!ee(Lkuo7dicaN=yL*4{7mx%Pg4ciFKGX*mn}1TGkVLY7_FuX zz2E5*y&v=F1s$!ee(E!NGkW{MiLaNX~U@u?J7_nfPLhtU@H%9LsRJZ5IKJC4U?wgFg_edGN z`;8osv^A!T-UCOt96X9W@*OX|NTK(vq3TGC-s6V0Ca=q;oi(&m=d2+v#{8qb@$|EX zF0-p?dsr`F!>I$s|Jjb-%m%KOr-y)UX?VZcfmk4BIfy^Buc zwfEX-GlsWNYwxu-+URTV4P&hAp`DkS+sLCARJT_Ly@%Vm{1!bPsb=-4k)ubBQFXed zV@Jj+@c6;V@ngh-WeU9~Sl@W_pWVn?;Jki z(F-~&=*8N5{)oQjU`#WwIq1=XJQ>#BGkTN%n!~0Zy`UI>(DCdXF39M`@Dbh4@-OYX zw(;y7PVY{B^nTK#7gP+pW$U1K^ebk@H1mqtg?;ZFCf*gZ2kaHI4F@Ol6|>DedO>Fe zz1TUFKdqP;JBN!b)<(NxHl9x_^k_kz3_FLd8nE_m?$Ha1@dvH5_Fin!k-FYHd(nI8 z$nYp@9y`;|*sh|BG zSbML?`(80*dEYArV>Yv&^5_NC;m3pCt1^1UFiuqTHsPAXr#*T>#jsm;Jm{UM`(D?# z(RU74kJPX$c)}S8t|@dE011K^bd4A=)ETI958%D^UgsG#%yM{_UHxG;p?Dx^iPV7Y34m< zdbA+V>9uz}pA_#%pSA5VeR6+Nyp2aMD8?VO4tjCTA@6(VG+;S4!$&ml9K>MEW_DYTUQiu=Jm|eXqgM>$L`Cl%4S3hKokuUI z7F0qFg#M=$8?K<~|Y?G?i~QPn&N8? z{AtBk{k$qeFY?ae^2A*_*YtIl&UF*!E}b2GFF|#0$Fug{mUj+f81v3S4909`cl785 z)#2-)ckcVN;`YQHm^^}W`g-qpKCSqg{YLyogOm9i@jH3+g3bzhNB>5=G0pr&{GENH zcjA2`enI<<_>BiA^Ecvm_UHwj74%N_&)Vw$64YINqj%zcuWi`AYukj@-pPB9+2=ia zL1zWMbKlP4o(Y29@$4KNdOtC#cMiLF^n%U`da?HAJ0$1yzPEhMLC<3>^EHPieAe~_ zk6zHYm-W6Gbe~;`Ui$B~J&>=Msc9;s_aQ&8%Fv69-Y+Jun4Qtr6|)B?%oVd;eJ??E zZ|huhcxVox_u-6QHBDvoUNR=mo|2gJ$%)kx2b- z#i67A`^aQK?~M(3*S5DuFDOt8S_i%PT^mNNjNXa&uI-Kn>>T#-=mo|2gVsTB-Z@~@ z%IKYVJBJq=@V&NuJ$gYg{-7DXZX}wwb6Bqd=>4)sFDOt8n$g=-^q$&)cWwK5^nwDl zpc%bQMepeiK=1w@y`VrXXhv^S(fjiTp!WceUQnPGG^4kv=v{K8{LBB7?RxK5JbFQa zTF{K%rlR*t4S3gfphqt#Pz##T+f?-avH?4XgFJdcfm+av-ln2=`v$DN2Yd8_0=1xZ z(EG?7`fkNzeSfzi^&j#1?sQ}Ln?b)zti4JejkGN5+wHKo|8P?t-8?g3%)1wy@;}4qA>qeq^SImxX0D8aW z(F+RHg4RLrWZF55&@Q0v&Y@ZF+TPNDcWp;_^nwDlpc%bxB${{4;YGXeo!nQ#VBbyr`O)`{L|~@ z_AZ@kr%mSnh(FGw7gWzf9rWg%14eI7qqqETgUBRJ`5W=iHel^N-lG>(_co)~jY#u$ z4rep~y+8Em1+)quOxf8@~%IxFbS@7geWb9&!9o_B4pwQKL>e%E%QM=vPGAGFTeo6(C= zn+)ik(g5`S*rOK|;}4qA>qa8AbJ%XwUF>8)??Meg?@1oLpg=8XMsHKmJFNle{fS2} zC{PPp2fa_(-#hpatw!UvqH#-s!{Bhi8z_vr~?lK7IIF`ppJoW>AeQPI9Aq z5a}))Bf7Jk6OSi*^n&U(>!3G(T7l7<(>sUpTru0D0oNRU>d^~|@dvGg-pTZ??S-EF zM*OE}&E2xIPn*}?&m>;1Yfm+Zy=*?>{Mr|^zy?<`NcPq~D=mo|2gJ$%)kw~q*hbHevWBbW~-u)YJ zhvbqu9g;VX5gpih>FF;#dO>xIby?5eYw)aa~a@*yd!+|4Q4j$D58IO-%WbeogzGn>uKE?6A_uiqc$?LLd zXASMtIctcEG5=_9JpHVp%j`FUT%D^o1`&ItTXob=$Wv{-ly$%I=mphn)j@B*=77;F zqxYr#UfX!CIee`Fcj;W{(F=<42d#tNXYI=J96hGKl{wbh`@+ar1v$;yw=z>}ub~xX z&yj&?ZKCOG4((~Xwe^2x*11c^t-T$)s-YjVkLtDe(LUDR%ci-tcgFBeokxcr9pZZ< z<{8>}`lEjBO@A|JQ|iHcC(PRWYmZ(~J)(8co7Y~9-eg#Nf7pPv_acv8P>erl9rWg3 z{>P}5(L3>e`G36z{PO>AJbFPf{-AZxo7Y~9S{c0)Z{K@c1J>S)J$gYg{-AZxJ8XA# zqx~Am#$)W3#`-Oi4U2E8cc%^a`QANs&EbUHd-8tPHlBBFhbPecerlMz0%*)F;Jtu9!`{eQ)?J9sO%0WBr!S z#Q8On%RG8Pfm+av-ln3rmDu;XUxFHI-#c;8d$~t1C{PQU(c4t?4mAM1S9tV-0=1wS zy-h{$6%E+;Ug^;b3eZ;zWWC;dwMQ=~#vil}dPnSMZIkyNvwhl4xyS4;HSaO|%g|r! zJ!bpT{k?w~^B%MJjPa={u=CQ>-+AK5yuH?O@Iy~(iley9PTwO!-U3ySdvt%KhD zSsO-ePNR1`pS5k&fNKuddh~)~{6RB%-AFX=v$pRx;CkQ_*{E1JL__ z9=)JIEoeq>Q_*`>1JHZDM=vN)3!2f}RP-*|0QBDA(F+RHf@btK6}<;G0KGSQ^nwDl zpmor@mHoy;{ym4u@p}%}H{kaiZt~~_1!_U-pf_JJ!>CP$D`tx{VC}uxqZbt851P^I zMxuFF%zoH_>%G7C=miC8K{I-rir(uQu=d{K(F+RHf@btK6}?|>0DAx6(F+RHf@btK z6}{hV0D5or=miC8LF=G5|CSC$t^BTS;{BG+ot@q2HzXgNep6@T&P}!$^MlUzBtK|> zkLLl7ewZrHdaAy zv-T@|C)hmVUn7~1az1Hf{%H#kP5%nt0<-uld=9+}+7UuOW*>dK`UTXx$G{i=0_ua) z9eQUBZ``??3jYeJ$lo>!nZT^-~(espMCurE7ENqy`b8@4tnzyGmKt&?VWhv zh`+M|JBL4c^nzmiK{I;YNHp(?+35|qVs^VnFDOt8S_i%Pvo?%cdF`Eezn%Vr27K0b zhet0c#ve4J*NsH;e)<2n2B7y&k6uuq7PJm}7qah3ChxnpecDZV*Jh?*{?b&xYa{z9 z{H|>ede>&AxN8ohziTVMCr`KX(%1gkqZd@SSO>k6Y3HyAJ=1ox-!A0G{{D4kG5hR1 zsQ6Ce{vcKnW3H{o%{td~=^DBJ!c=Uo|{6XuWcQWl9;!i93+d1g} z44T|Khj}}b|Nq+V_2>l!YC$u4-AFX=n#0)*xaM%5M=vN)3!2f}RP+usVC}u%qZbsY z1G54kt4A*= z#ve4J*NsH;?(bb_n14Hca(~wLh(|9dPz##T+f?*UYXEv5_2>l!YC$u4n~L5k4ft-w zV;;SrKrLuSZ&T6x{s!D*_BW4SP@onxqqnK(-Kzob+8+1l1qEtBGkTkf-hCT@-oJbF zf&#Um8NE$K@7WF5_dem#3kuYNX7n}{y&q}7zV{yH}r2YNQ z_&dd)qPo4>`?R+v+6442FviZ5e@o|*>ESM&1%?+G=HJqJV#+bo7Z@Jv8}W}%(J1*} z$^Z7~1=V@fdDoWjki_UshC3veY{1(4j7Kjh#ve4J*NsH;_Pt9r0KNb5=miC8K{I-r zir&{X0KLz8^nwDlpc%bQMel1GaK-Gu9=)JIEoeq>Q_;I%;?s)B_N~n4JbFQaTF{K% zrlR-E2B7zOk6uuq7Br)`spvhc0qA|fqZbsY1%$o`tG| z?{j!r1JFC@(F>~koOcdxM4Gqu&eH(&wmo`5GkWKiwRhhJpm)fl7c`@HZb9z?4M1dOCp?C(L1-Gckc$gYg@ph7c`@HZb9!p4M6X! zJbFPhdgm7O{;L5yhXp-)K{I;i7WAIpfOl=L_UHx8=$%{8`-bFlmK{I;i7W7VO0D2eo=mnh>^e!{W|7~#DX-)aJ!RdYc z3ZMM9!Rf=(?Y|8^OaC@FeawFw{M&^2x533cdO>Fey@!mj_lM~JCO>Tdk5b0^Xy@al zI;l5i!_HU*_M5ji9wQbk7X~BfX#bVDWyk$j=4X24U~xe@Ysskzs9^n&X4>imY} z^0wFi9Wds<16*XRSdtp>%TF7tAVxVlVrU8vu6Ml4YsMhw>Q2`xTf`h{m^z)KRum7; z%f;n3ST3U%Rv`}&VpR6Ees)GRn9CK5`|$zAaA+CzRdfZ5-WBO_#c5omZ7fL*_!Xv& zRS=^b9WgY82iH5^<+UQUWsEyrt85W-sA1}Kj#^PXI4{I?mSyz9D&!$TWOke*fM+-8 zIKx=Cb?7&Zjai!>*PhBn#)>7W0l&`Fu?k|8qa%i<@ZfsKyS&z>wv2J7Yn3fx4mC`j z&QU9h2j_*j&a#YNScN=9h|G?21eWk?FX%YKShtnzYP&K$;tbKarutZE+StWKSa}+k z>S(ZZlrw{e^W_?Mx>ngP=1_wOu6ORy)dkH;J|k{}qmVzb`mfox=?%-0=(B|UmU z>-tOk_u6+c@1sYYLCZDO$9p?t7Z>4u9WK?;VCg7l1`p@UHSTn+vR%xf1`%BE+@q@t zn)mvQxDAd{Mz4#_dY1>Xk&!ZAcLbL5=mo9oKbC#V8~8ugGLVf~%kC_K{JJiiwtPj) z9A`a){xvl7L2pdYzAJ>iF+Yv`jk&=27Xc1d@{p3>WGxGGGefm^ud-jkb}6*KjgpsA z_P@4QWJ3Ilm3%s_%hW&X#SibZ@9cxTgw+IjU!}j_&ScQ9r{sC)3WJQlziMw~m%nX= zANE%M=U7dMznijuo02;{b_n*{ST@MFs`j6p65B7W+Iy42%g>bm?^XX!Q~FiieA=k| z@F6vRKU3`=quSp~*)OT|-&OPZ5rxO83Qwmvy^X>TcUnLOJo)EGF<|lY!x%fuH@z*3){GtfzG=Sx@U%vYytlWIe5C$$DDXlJ&H{CF^OOOV-nRm#n9C zFIi9PU$UOo!DKzHhskv%+lj_2Hc(}C)@?lCoL9O>UD*2B}o}ykqKC0I9 zt(AO;vfo1KH?l()^4m(u+bDTkC9mT42Ywukd54l$Q1V-pe484N+m(EalK-gWgH-p|U?COXzC81k`s4f2>vdrdwbA>>&D4J7p2**rKfC!Y{6C`h zPs_Ue3jIZv3;A5D;%(>hFYG_6^am;VH!9wZPVXCNwfuPacv?1QRkdGuF^bn}#j-K? zMtZtFtorNs&%QllUhnLSe4dW{TP-g`KcMuGp>MsQ{A1aecPhLr8rd7uR{Pm+ID2cw z4{O_&!t-fcwf|gM;b9pSe^WI-Ur_NkQ1VJ@{BBTqx?IJ7yUPDSm#?+rhh>%hCsjV1 zDftRzznqePtMg5PsZ#yO2Mx;=fbv$4^oHUnatzFfO3toUJ5W&b^w zZ()CklkFov+@|C=EBPHNpB;<@V`MY`sdO8-vf|1UM3 zt111XDxV!yyd%_jY5lsce>N&Vd`$J{U8=qLRs8oT{RS%E)s_B>>iKlH(!Wi~_bYj2 zE87<_;#vc%`=LCR1o=9T`YT7NU(42GUJ)nk6X5@WQT*3-^)?$~i#&XLrTXXHzRqVG z?0-2*{7uxp2>JYM6#MUwQoohj7robK@M~p{dOcpK-_qKL@pAQHykNK0C~>!T^~Jcr zUXK^*|ER_b^?JNeug44Zdc06STL0a6`9Y#=30HKW-^NhBkxV#>VG6tKO=c<{krP(_K_c`pLB%yx;^Swq^JI{%n$aUe$Wy8 zDSwvv!5;Mdpd;w%`5(!DP`IJzeWa)7JInTwAL#i^M~J86U#a4qW?h5*Pn3M_P#o_` zCI6h&qP??}{InY13sw8Zz0W8*aEtQ4PRZve|F^q+f8oE9l0Tr@f0=t-E$r`7+Iz?_l}Z>d*4vDckds{ z^-GNs$6b#v+tYZ_2$l16*XPUi?tNalehJsEeIz{j@iNA}4=mfe>-Xh)_dc;)@7^z# z>)rdta=m;1Sgv>PBg^&f{bad*=~4RS-fx!e-TTgRy?g&zu3vJL`0o08+1|ZxEzhI7 z-d?VE*WJr;-1YZzy}M3cu6Nhh%kjOvf0l)LkFT#AbCG)9{#?Dj-mmlnO24>T2Y#gV zKUVA7pWM0tJhpypIjoZ{C6iLMe^9i}w+7a*Jq-PKvfY=EricqWwCm-<4)ra!zbgEc zY|M2kAN~HyzaQ}9Zp^!Fd}7&{4PyHt)jnjz>nJ^B=m*{ww+9*e!IfjZl8yPg z%14dYP%ImBvFpE|4`cqI#^*An|E-dL=Vav9dV8Fom&{k91lCC)vow z_$#@5{l{NFKmfD6^Y{7D^-_n&LVuO(FY+H$?Lmfq;1n0n`?nxNKdAIdHfCBpUW01B zm2Av^)O`Ft&bPIq&7>F~B^z^+vj1tEf6L27{y!n^rm&6-#xi~0uj09R3+;Ou@ml{- z?Rgpc!6#xpWawLNA0Og-8TtX`uViEV^^#(~?|1Eae`79l{VDYBdIj1u<_v`weLZSk zH~vMu)715yYgPPPqV>?2=at@HPbu=bSlK`0@Kfj?Q~4bdJ^zjQh{|ue+NZu=jmL+T z{SB%=+baFx(d!$1KCbrRt2ul7$W2{1l^@0UD*f&%Klh!o!rlB{#s9Rjf0fdosp5ZJ zjpto1A5O|1%cy<-rLO-)0!ygz|E+rce?r+`5WRjIbDtWo<5c_Sx%`oi`Ky}G?=5!sOb4l*Q*uYR#W4Bi+f*Hya@(j@DZmf0geq96pMCA6D%ztJ?pgdOmbi|L#=simJcgQvH3K zYVRB+->&BS7PVgdNzKO#3NK5l_I_>q6JB>W@FPd>ONk4w)2OHSrBsjSYiq#Om+cOA zujf7*?2Mu2lX3O^9%xVB?}7SzM~S2F_kg{=-vjkajS|P-@8NL}^4IruAP&9%HTN2p5A{Z>-Bvdh)?f7llJufGg(jXKa=(J{xexm??03E^!_thzw{_^=>2EXp5A{Z z>*@VxvVO@?>h*mK7$187$#Ll9Bg~h+ZvpoDz6I3l`xa2I?^{5iPdm_4?!f&(5bqBXO6~|3$42mn!{`k}p&1&z5Ta`?y+P_EYQc ze^q;JwI2RT_3zi}_4dpYW-ft ziS#AgK9o6v6>>hSyTD%ZB;@4AEm!k`F}VXzt&)nTwlvi1!t#ZW3Ev1ITHCB zbDnD-0nBo$KWC`%e2v3{Z_k*^)%?Cg<^L`f?-aE^dP3#5P?TS5Xi1kJ`UlzP+Zs@M z$k2C`9y0WUN)H+Ow$ej}zID7CcjO1T(Em;8W0{nyzpo_EeZzbXc^UBr|4uG%3VO(e zejehM7J4s3Kkzckd6Cx5Sf=-WaX#&r$M%pBug&=TSZEJ2^aIKta-m<`a$cl-ybOJN ze&V(h@x2WFzyieCTgKctLxz4(#fJ?2z-uk%MQY#6g`V4!@x2WFpz0rF=m%b7IWJQD zST<(Sc)SNyK9CX5&i8A=ctD1}b%GlQ`$(^gkfEQ#cq+DYrUe=L!5PFYBjS4*`hg`Z z=SAv|m!ThG`(uN@l8t#(t*8H0>-qXFJ{mCRs`ce=wH}?X?5C;MtADEf`cvxl>l_uo zrS6ycfXer5*Pb6=W4@!-ud|f?=Su#*ig%Qf&sFy4DEZsU{+E%yHSlUD+eh9Pc^P;Z zTrk!{hJHZlAs7AqxElYh)a(86N`9I3#QO(hW~%l7$LjTANX6ep#oJuHp3kTDN559` z@oIk8Rr&|r^RMXN$ts_V)c)jdhmXRZe?dY#q0E5F-~HA`=>HaK|FN0s&mYwD;q}q_ zV9c#bf1%26DP_NalK-syjoPoQq4K{Y!izCWsQI|x>5K7roq9gJ!i~4bBYi%g{NJO- z`@L#>|El`8pc=0S6rR4V=J#W2e!r{mu%2#T<+rWs&#EfF6V&r@np!`!{9%Qcht>Fh zOSSiAHDAZ5@xD>%?^N^kxXS0Xs=v#r`Cdcye@Nx~Gqs+sr^e&YYP=tE`4#xsP~lO_ zXGinXYV-BgFBdOZh3w_+sCwwRE z3Fpar!h5owaG$LA*DXrz(({7tOZD{pNXDV(NwS`vFUfj(-X!DG^CwwP&!c2LJ)e^G z?;WMT^!#FbI{9c7<4n)9WE^_FCF|*VmW(r6Jv|S}KCH_-sprW7>Ur@sCBH3NcUr^z zx%w-LaD_~5@X;FP`)6J$^jDbW z(XU%)_V){96_>p>*bI>0hN*n^(u zbOf26-;qqu>qw^Ob0pLAIFjl48_D#%jbwVhMlwAgBblCukxb9ONT%mqB-8UPlIeLC z$@Kh+WO`mjGCe;cnVv^17X#w;UT)d>v|C&@GldNO;F+%8K9U}Cq+g*JZ>J|2`T^w+ z+3Ss2%*}UXZ=d?EU29J=^z9!}y}%=6=!Z^=^MzdKe?|H)hJ1&-484sf#sf0+gXhNa zAwxgJ>(8DdzLyI6g6|BBL+9O(~KdXgjkK}t_@q38Y8=Y-zNk^aj{PjaL` zSm{YF^t>OF`0+CIt#@0_i{$5J=m&p6{$l(gLqDYUkB}q%M?`*XPjaM}_+vfEg`QtO z4i)}hj`Y%>_1gb10f4I_<9O>6mdXgjkHMJ+D_XKQBjm**@!K`+omJwS2TJe#L&s$}&FNlU&4S`MV-NFGqUWKI>)s zJl`_DmkWQErN5U8JkyE@8w8;n$nXT z=}%XBk|X^YN>6g67q8EqnUoL7k^bk(pX5k?meP|P>CaYrk|X^&N>6g6KUe8Vj`ZU7 zy)%>Y7q9PDK2Q0RT=+8{e01p=bPEE%aV4^o*b13B8vKJ==@dZ@a#cTU8s$%N zq38EA5^r9H-r{Sc;13!44zIs*e7s!f8E^D@PLF)FEZ)THyOqW3E9A&u#^-o){24#j ziuhhG{Q31-`g^(1^L$??{Jk9M|4->jj`Y_nJ;{Zh=jR5Y_i~}<`MFW(y$rn_Z}IvJ zInr+&{H>nkLeJ~hCPMFJ=m+`wme?Oaj`Xh&{#H+Nq38LK*OR;q{eW7JAVWXpN8~T| zFOVa>$j|CYhQ7`1iTxAgNH6ynY)^8e7w;dezj*&(WwBmDhW`|PzWgDK4`k?v)cyrB z^!D={nIGd%^-dXgjkSxQfGq`z0` zNsjbl|1)JKjgQ#>SouEXPjcbU&)55f-pi5x0i`E7(m$y5BtviUw`tHrj`R}$j8BrG zpThf6g6|C`d29O)lddXgjk-<6)^NdJV=lN{;)q4Xq2`X`m12mNsjc-C_TxAp2y=qLht2B|E$uJ9O?h7^duL0-Y-5U^jp`dekR2i>#H3Pk|TW&q8}fUBfVH(t-n}btvmvA?@w~%FYa%#_9RF8=@7j? z$&p^%-(vm6{Vi6W2j}%)LL!k-u2qt-V;^tvoNxy+6r?KjVKs zh@|&&q4(=CS@GfSf1>re(6jvvh~A&%LeKkSi61W)ddAcIFeiU6LvQi9nZhT@&|5r- z^&4`e7wfmxi}l;y|0C|tQnE4cSD%OOhst;-RH4||Lw~D z^Mf=XMgQovO|_@L$NV~XUoJb@V-ay z=CjcMTDAWN*M6bDSLwG__D*h2F z{*6lBS;c!=jpqq!JWo*LxtGG%ZL0ktb)WtbO23;L&$C^A#rXeA*`KcReYxt-9m@Ys zWj{mZzk`~u->CI{KIQ)gWq*q5-VyrA-%NBQ5a@V&b7pW^Z<#$y-de}T$(UZ*eY zFID6BbtONl<^>eDy@2vX!D>WX=tM%fI3Ll?R`E8=&|6Jv_nbQAL<@X7t zUq-cey&CWHmAt*`&qb;~pI7={D*f-3e20?vjq=0q&tds%wcPJE;`OtTJziRE^}RdD z(EH!rDB=y=VKqfO$OZmB74@ezupGI*GVEWKY|JOrd~6f>)4ilh|HVk};=e-053(^^ zD*x>wfBKHE(r*yyTdnwa{WTvZ;9>O+~1vo zy_N?yj`R2OfN#I$Wn4b`JiKeR~dv3kSW$Ey;zR$6xB59OezbFH7$i$*1rejK|gW|p+Yc#o-t!25 zB@gg8i0kVmneD~rWdlmK?X9TVmonSGMYS*FmhTT)@!`HFctNnY-y@XrD`+%GcII@y zm-?PzNoM;m7xwf!QZY_j{(mSCZ}7L43*+r&=-W!KWcsXBtzQEU*YF=w{*a;XC_QB8 zTk81^xzM}sI~Mu3Vwu+KsQ+~BL_JSVb49M%>$q`DzV%InuAJ^dv*yekg7aa-moGv}2j>g;1|YkEwO%BBj4A9C~5}MPpG5>Y= zDB6EU;bl$L{&PyN<^7}ap?eh~xz&2ywuJfPdwKZ?`NjIykeXk}-k~)V&!?7+c}Vr| z042|-UWc@Nc+}t4zT`&|GTSrUbdsk z5BIA6-mPS#`X9@#zYD1Tl8o`U{eP9xlU(TUq8wf=^j^kk7xoV% z>=#w`Bp3D%NA||-9$hbM4JiCTM*f4G&j&($$VL1;qWCSV|Ddubxv>9I!hRiPPjX?u zXKde5&j-lJx1;(48TvN&=L?}d$VGemxc11(9rsRQihNpws(r|aKX|uwL%0^?LVqXe z-yhl^^m3v9E9u4OOM_l6^bae&m!ThOTh5ELU+^;YgAc0wybS$->uKQ+xzG<;F6h0C z3iI=Ly%^#h-e*I9A$$9lmBso8xzMZe9P%>s?f+1J-dW6#F>kdRucrN#*8fdiKiVjI z{jGxe)lSVK3M$j80;Y< z-VnF<`Jjg!>E-wHBqFhJJwY(GLEQq4ys(7ygi;ADCjfLJzsncZlnX_+Bpboc}bT z_cHW@gO>9m8`e&95In=m)M+{$7UOKHql@?L#i~i&)N! zv>tjH`T>6ZSTOiQhThK4?m-V3`Zmw!wm}aW`avGwH;3^act-Wd%dnrq@g55CAVY8a zw@c7NF7yh2{#KI$e^V5`A;W))!XISlJDlH7Li>=RxBdTc&_jlPP^}k`p&#J&p%?ri zLqDkUgIwsZr19M__z!v+`XSXmWa!&!d>|Kk<=^&lp;!5}_48Nh2eh739|`#nc)5tL z_5*FbA7DK15d7O-hQD18#Oo1cuczOLRO{okNNx?h7~$8Lm8@ssZr-Nkm6iNgdq=1%YB*1!u<{|dRV|DdzCR{XF|B)3|B zbpD9vWjD*T4tm*`4@U2+TW#eBxoGDa_d4a}))3o&HLNR;BR#k0DxAIe{iY(1W1`nT zzBiW-??&8~O2503uW|iHJA>+faUmD_=P0J!-+8&v|CjVD745eMyMX?h4yZ$KVMPuxk}#BX5!PKNU!5?BHnsVUl{QHhjKh0aQWC; zemF$EzkfvOX>&ve=8^8rSN%Cz<@Z_D{&DOs{C86N6P?~Z^20}+zL4Yp@i6A&O22`U zH&pTWQ}V{jeiNntgwk)S^q*9EEx*HN9>!~$@_%#myffx;HQpPj@qVZBpQ+-v-1V1Y zyjF1YQOG}3?X9Bxmsau5SM47gz2BkxyCS(Y;OE0e;n07JuD8*5AEWp0^glDI{gah^ zR1}}T>&izM&+jPx+g1OTQ+WJQC-y%$dcR56dKCWuuJFCCy1wGxIRd6?3lq2%vI@mhm=evXOsbnm!|&%e`5`Pr!aFrSiVIJq#m-HmTy z|7vCbZWaGGQTwg7|GcD#x30Q=y}|&84)g!INZ)FYkSBfKQuyz$?B5X0cWdZ8ismn> z*qr%ynq`0O?;eZ(FW~e=eBOV`eB#gJ2~R4XmRDeRk?%6feg`G*sN}trypNLib+Ucr zmh|T_Us3i4Df_P~ef)U~?G2S)%WvmKMgQKQ;?EP|p*1*_^xrP*oqUv#_4;|8dOq>> z8rj||YW^3A=AXWstMd7miWl!6__qe*`1h*yg!d1!{p+2*t>uTeS}x#IUH=$lJf2+i z*O+fc_@@6?RqNT!O8p=kp#MD7_L95yA(hYeD*odt z{{N}*+*|F3ZdCg1qI_Dd=}OPnTjcn!80FJyGrq1W#@ETeEoAzgWEF2WHC|iCcy051 z-CFp!to+A9rt5=Iyw*TBl8t#L>JR-EQZzoT!P6-|UC*#y+_RUf@%e@F-${-4W>Np? z^H(MBuH+k3yo1#1bxY}QR_)#9;&H0>c$0k$`M**1|1cH*eihGo2LG3-_J@`K$;yAG zn!nQ`y&K=%#Q0vV#-kJ28}o$f&-Cc^i@po2?4MKl^7Sjir+wsy7u zpv~wuJdAWZ!AhUUyH(kLPVGPcto&oS)mlnD9~M=3 zde%MPF+L@GeSg_ooqv(v8x)?GQqPAkxcMvkf1S$bZ#EL<)0iWa{R#>X8@v7&@%;bP z74j$5{M@PVyO;9+v(oRN#`7Mf|D%#`Q1ZP>UQgw7gj!Fwjn-Q?U-JGuoHfe^B`zs>bJjr9a%wN0HCj%Kk6P{wAegO6k{7`Fu}}&*sti z(0B1wf9_ZDA5r-Elae1&{tqhr?WgR2<@5#Kya}! zK5}32er5kY)z9-)KURqJt%3MDWg!>sJ+0P(|0wxcB~MW}8&>jECBM?j#kkVsXr_}T4cM%?1gRi5W zuTjJ+NBPio!Kgi&-$eX(srV!p z@n2N_&nx)=CI3~)^D4akLFvD*=HugPJ|1@Y7SE4^UH`n?!hNtszIQ}=`ppqF9%rh3 z^^cYPVUc~S9beaMwPQTA+I(H&-Nksd29~#(VEkHbe&6z*pttsG3Yqo6pWd@Y&%f4? zYJW(zKd9OtQu3f`e@M%0FY+0DbDY1mm-)rtBWMlA`5E&rwVn;A=hH%JeZAhzcQL=O zjrvbxqx_#x_+25&*O=d^_*X`9YcL+a@_iMbQ}`H+@nFYWj+dUlwrcM!QGTs~Wh0sH zQIG9AYW_NEzN}ufZ}oD1){55O)<8Tzt%11zt$}#_S_5&ubPt<;{zl_Z|3RYk|5oxr zYCO+X&+pf$`JJKGhhM6F;+K`Yj%sgd74Ot&Jm@oZmH#;^pYv6|hpTvpMEcg?6>9zd zjLLt>$e#XlLdh4a{NJVITUETS%I5>heoLia-Rg^dmi-=&q4h_<|2SEV!;Mj%t$}qc zZi_fxrr+cr~~Q1|4{NaYW~kq`oF7q zbQ2jJp`Y)u{Wj*q)JfS-S6{YU)7q8mKN$Jb^&8dhYgJx*DZSojZm7nkr{?{YY95wQ z`X^QV^^|^7B`>0I_5r1TPQ}|q*>9ud&pX*>$q&1#eZV(W|GuU0`Ka0#ET?2+*X=M5 zYx{Y0|9cYf>gvmO^gs1tzUlLKH9xOVB4W z-dWK)-Wt&R=w(%Vm#g+JQ}KVH=I6>NKHX2E>=#t>|F?H0;89fB-@cWA3Zg_A+#LZ? z0cBHEwm?t>1i`qVf@0Dn9f)Kj3y8uHWK>*19i4GO!4=Sv#SIk@5fD@mMNt`-ppN4* z2;wq`+xOn8>guW=jRxeue9!ms@aFcp>$&Hix>en$yXr@g4;Oi)=<}nj_XAS?s_6TH zl(Qd2>_12RiG3(i&i)gU9mmEWjtZ?`^trNpe?s){A;;fsa{RXv`6bck3AwI&*|WE+ zmHl(NS3i)?^~MY2fpUDGDD`t?y&e&N8RGVo^w*0cvg1609R55mCsNLL{bjwz$^71k z$d0qtYw!NGf2PZN{zL5fmBmPmJ!oA_e zeuJdHSyH}0)@NcwKhM75{i2W9bA=p#jlK4P{r(;4kLx%opDpYEjo9;5DL*!151v&a z;~ydOykTA@V%Y_g<0bM`S0hpS#}4^Qu4i>3Zt8UJ!ApD6RGBlf&X%Iivh7e(IZ^Erjgr!mrDD$ zrF^+t9{642_kr^H5%(0Ae%4DrtE7Ck%<~7SKTqcInAAT(>YpY3_mktTuhd^6@&H+f zi#^%Z!u~l^`aePT*?eh#k<`zR$WGm-=#%fM2Yyu&Dd#te5!p$z^~2}E(QbLLE`EH8 zdz-q)+xGc;MEu5aR!M&!$v*wQyRRqvv2iRrzJ33n)WfM`_2T!6!93Q>`R;r1-yV_k zh1Z_npZM)P`Po3`_o~vqUSxb@PLuKOm38PB8IOCBMA|#)QM-C}3182>CU)r{{p}%s zlp*qP(Z`9bE5FT)=)b`?K7!qbmd-oJq|-jfk~dGk-& zpL@58{-q*&9uch99@c)JhVF*ZNFZ%m7WA2jUexlU>!tF2c)3h3Q z+S`48>FQBGxXa@Hz@BT`|gc0-_dT(gdps=mdrg{$L+P_W{ zy*7#+ACq~l6}#wp)&D%g)y6i}&l_HlePfL5=Ub!eUgu5v7!lHUn(Z_sH<0$LM7~SL z`!3pln*QG8PtyN*k*h_vpARJUanh~6r`eB0{ePXs4^9*NO%?q*$a-`azrDmOPjqkI zlJcG+S4;gK;^*~5zY-aLgZSwIQr!JD|M*PUBvx4%`p?&2IvBTZ29g=!`zeD2t@i<4=KW-5J zIp1xU)bj$72SsEjJvvXGjpga-*0O&ViC(uw+8c9+`13__JX{~Ki!noG{a%jPh3`qp z@i$NUe_Z5svY#C+qgiDB#!Qv| zP7wY7CH4Oy`o1gj53;_8NPp*wKU9f5Mu~ix$luC%1Es%bWW2qletq%Zy+uAm>~WB^ zZzTKYJ2HMl=`Ta%L#6-eVy`Ar-cJ0ji>ya~X`dNUy}ZAmGXN;zF*`! zz4oq__RoV}c_1$p`#m7-XGdfw&HH_K^1R~7JX3D3=y_#P#Ey>R|Blt2tsT6-tn(wT zMu~mKsk0LK(U4!vh?MhvQ?c8z(qHe0pBZzUlpiPMOC$PnUJ|*3jwi=KYmryUx;-f8 zrJ1770I9z+Vt1ao6pZ7vQJ$t`=obYn55r( z?YTdOdxw^U-*Uf8&u*@E_Rm+|^+F&w6nUduPwX#tJs=`Gbxud)@aKu`BjwzCSL7}t zkBQiU>p@xP#ZvBwU$uWV+(zbO&tKu|=^XL<%cA3@o#o0&Kk{VmsVDCzE|GqUM7}RF zu9L=feMk={Z8cJ>(7HSnIX?J4rSx~4l-Gz~tdjCmBJ(oFd%uyi<1pFpE|cTyI*}(x zfB%u|nniLv9xLs?mG)gl-y@~`B=NI@B7Wke+2br67kEy_e?|8Ddm{GddvDVJh)Dm& zTox(!##<2j{-hn>#>kt9U!;p3%|wqhDL*n&?xb6PT^RCgK{T*C3CG#%4tK~{*!umGWVOQ7uDlA(W6dezK*k( zl*dJ0Ao9<$zdjV5S6Y9!eo`+_=5qk?zrK-n#;le7VRS@K*1(mM{d#`Eo*6mboVt1) zF;4nfZ=EKvqcIaAcE|r*IXRB^c?rMw@YdIDZU0R2_RB!NORf`Mk^OXLlpjo7UV_JxOw8$+*ZY6R*kR7Ge!Pb z&Vz48#&go`I)~%+=SllPA`ce%2s!>nM*P4@x7QK5f!{dkYmj3}xsLU_wbms5ziT~x z6QUUqv8yo?BlGd}xBluiaOy)%$ zGT^{a`56(ra-S@b%iM7j{c{gkvD+;1zqt|FNmGA3O8Ofcu{-Dfh`z?WB**JFk^cGK zsmR}n{JpGuADLfF<}*sY6J_1+knzqF{jQhx4I{JnDIN2>ku8vX9><`}jMuk53Uhel6o4 zCFLiI-P*|Y$K9fDLy?>v1c8ze^asV{oee7{;v{!-x2-ZkBsM}d)LSApl%;o zGXJ+D^^IvN`h6<;EfxQHRobr>f4ElsF;ncbQ0&=I#(zQjZxqqTao%uemD~sK7yCUa z{qN_s5A6Ad*MA`Q75femeP8zEz@WoCeS`M>WW3&DkMW}4fztoUBKH!xyNo|q_R$BT z_DT1yPXl$$+0x%ak$Z`MbdvH4kxvo1hsdXj+)?DSWV};Eo+|cySC04jQr=YL==01t zFU$ULsyAL>pj=tclf+-9MC{AG_&xgv>;GEBU!8R8pVLD7`9Ea+pB8<;bbCtpvy-O& z9gFyr<8a+>+>iWx4es#v-$0+K5q+I>@BLgbUDG!*f5*L^nI6*j!)SYVJl>K79W;xS z6HklCP93ZNF+qJN-M&BR8zD^S?kID&<>bzs(kZ92l|J_V*(mE$633GTyfleYqE1#9w&77O@}CgOdI}m-&wn z{U^wEOS<^i9O>^Hk*|^VTjYE^LF&IMa+xQy3f{l&V!!jne*234RU*GA_IX&0I0i+w&8f9NdpYasjiI$6Iz%6M-@ z${i?`9n68)D(=If+Af_?gj#=AVSUdGfDdtD>_ z_Y%2Sj?XhA}Vif9qww zxgwutClS&&Cgpnnb^m-H%x`}g|2^^VJEgzj5!v(C0ip5#5-I0?_Od?RM8019>k+Z< zbJE{R(f59@y=w*g=SyjSTx2}g_z`<`m-Xl*{&JgZsiZ%Yi9VC1eRHY5Lj3V(Y5$AJ zhl>7}ihZi2{(Bet(epO%(msN`LRk{@qRL`|;txpFR-({ZRDxpBE6+?;-Y@ zFa6J#^5&x7^-@22UmKonBlEpg>fa!8GuM-n>%BSRKU{yw{KksBzsUEBz6Z+r><_YD z-^+S!6Zvt`_a3p&KV`h9BJ~}otJL3D*7vnYeV*4K`@z%F{&Ug)&tmV!V$aW|z5brL ziRg2g_|H?K&nD4#KPi7o>~XN@vsLPEmHsBn{C<$~FGb!aa+T}S`Aea;sD zdtT}<6#X}f|D7oMJSydjeoUUw@vrBIVCY|9N7sULrp(_FX39FP8r1h`uePKmYkNfqoB&ej6kG zJL%o1*)W*DQ^(3(l5%=ypeIX^B@{kylzqX;nqslXDm)r=qgFuw)n+mGSae5n`;o(&P*+D$N^_ zlUG_?9A`|_s3bLh-Gmq`A68|{O{BIdDlCa7nwtF5yx?`bxU6!F9icMrHj7_cRvxdY zu=<5Ei@d_ZeA{z)>I`38Y4YO*v8tj<6B`{Xti)jUZ+YRc;gzN+USR*YYF6b{nz9(> zW6I(=2|X)JUQua9Re3z847(J^nQ?_zBP178mE^f5D=y71#E?|U$&VKm7Uxu!j)<33 zm{Ellrl8bXydYj#SRAJdt3=Mw(yEgD3S+J7zhr4*j9FS-W{YxSOm$d^Yfw9L!(y;H zrRBCaGc-oK?UvP43@`~x&{cQ$J%&GhibTvm0y?_ z%BrYBHB(qp!e4ikoX|4n6vxU(B#KiN_|B7}2{ywuQWW@}=_>0kyleUGXK#JNFY%pHhX=r#cvFt+PQ!6lQ-D;$i6pdDTlaELAh@ADo?_+2{%*;+ zuGrtT-Iu=U-PZ|U%yA`m9Pg!jDsnRmi_40!C;Ycel9LjF&Wd=Ri?LKCY7%$)3 z-R#gTY@9N?FL_1w^v7}J_Rhh@0mk{s*l|owyu2JgsIWU;W2xD@`RzKrA6_Wy#(;&?N9oqBtDGsN7>5)uZ}%d+>^R*Fz+?? z^m9Ffdbw346|n-&dG?CI#45&=WBZQ}WiNA2X{NA%ow&dhmyU{?SP^PsT2y8ktKwEm*Ky6LSP^2dAjaJ} z%;@3lcR5^aaGGN$ad(ecMGluooUM&}LFB)V7jYW)Uwf@W1*RZIvDcgNHU~SC#3f0N zE4atG`zkgRzlw2caHW#?C|1aQSypNn%oqHl*ewV=$E#LeSj;}jvbdsm)VVK{8@MYD zWt0(I&E$I(*?&s&3Yn)bkF4TCghR_0-HVfikl2CUemL93ig80%NL(ox^5XtRUS3sX zr_aG|DoU%$Ib{^s*IY@(+^Y!Aqxfs`sxE$MUc9W5%S=v4Y=G8JjCVG(=Ofp*;v=i< znaIQ|IJyeqO9RpGD7S@$J$xhvdbU8P0VdcBKCiQj+S@HeQl%+%3nu ze72XSp1*QoX%9bBRyEX}i^(w;n<3^xlV!S_Zrw~~H`BVC8JlS?&P2>KnVF_**G$tk z)3j-mX3;wOmlRmIV#gMwS~M%=-fGSA?%&L)0QT=N9E-ep7biX|w}lU`8Zo_5@;N8Ubp-t8@E z`{a2isEqRAcU#el?iLzU4R1d|W^xkuuml!Dg-po_By?;d78qv$t zM7cenbB=F!e0$Tjt!dR3r*C6go8!!}rfnX7{kXNw*}c8hc2rw0 z)yTEYOFfRZPG$R4d8vE*eYvX3@9V9$t#@=J)wX@@wANZG*LE~pZ+EXpYF$$2?u?$h zQaAOesd7{0?aGM1)uuMqPNmE5$@?vxe!YBmj{JMhl~&7Cy6h!^$PStm+nyKB=hXVu zUYArgQ{|-|M{{?*rS`Nla_Ui2=k83uyIS{uZsc9lxT*O&AC%w2$K^Niq51iIbRIWH zn@ji{{T4n=@6TuI1Grn&#eBei5g)VPz=!QaO&fEyY0EtT+nL)&0kC= z-yZ8`CJ?B~AzXD8L8~)qbv)s#YMyLJi%Sk=9_Z!BwsT-%Z%k7W#i1*f$~kw zaP+wweWvWBKKY{0#FYA|E~-a#{GPS2N6fcJs`1AL_OQ12t+A~UqT`=ei}4fdk!t+y z*W&dZSD98Q~j{OV$V?UR5Z^p6TM2@v9uuWU{xKH?b;#l{_8<7|e|NiaqynV)wb>t4l zx}4*xdWYkA`^pG+U)j0wnuo@->v6>n#~91A4yI!#{ zw8v!FUJ3m@fA#E@s{hvPrft|Ilk4H>Y}eq|`t$bIgudZpF06B#Us>zz?Vt2f&n}4t zxAr;4B*#eDB;iNV}!g?f*o9H<$ zpYz$dzw>yn&3NJcZ1;^9-4BxIg&4qpUVS168pZbZ|g?)l7!9e94-(1%(jX8 zNb2Ju=_A(fJfGdMzb39{cJ}%zd2ao+>nlB%GKrvHdwd zvF_WS2gB$2-yT1)|66+`_Mq^!X4vMtb`FT@kn}}w{)zDuKAt?^**&|p(J>SA_WV7( zx277W9fNd&9xxbkd}5^b4)wEq>|K&A_UToYXM7fut^@m2yYFBtJfFs|Gr|7itOo3p zPX6s%%`7(IXXASA+unD$62ET$l1njRN z3!wzo!kh3ed;p)q=kO!^;$!cQ-xvDBT(EZq{1&$P*r#^6PwwJZGxnEw_Nh!4LM~ha zWnk}|ZSM+rBiN^&Zh(&3i@2d<37sSMa0H&!iTIUs0t)U8oQCsi7Ir2wH&sl~p@99!`K0!QL^q zBiLVfclGH;dJ6Q0KF|;B6DH2`8AN&!TrSu zcnqF^r(ppsgBQU*Dez^mcOYBiQ$uQ>Q1J=aCk1>DzktK9;L@QkG=PSX0gb@k!L=3G zCmS3O_6|lTLMP}7J)t-Bfqu{*2EzGp5e$JG$b$kXg^@m2kWPdv;aa#6rohc`E8GtD zjso_nRF=Ep9=H$ghZ!&n9)+jDK22o_EQb~F60CwXK5vm)K7mbO_%)b)BG$f;0sDjf zg;*=-1oml1J;DA8tq*V)MbjS!!g+8342B^-xuo_NYz0sX_Aa6m;YzT-B)<`+z|AlN zX2E0d1UwB3z}~TAIjjJCS3~=Rt~X&Fya(??4SWQjfc=HCeaiROVDHAz0QQ9p*dKaA zFX#h(VE~*9=R*$UK>?J)WiTElz(lwbZi72uE<6U$g8fynWic#=mwfEgu-|}nK5vtL z0H44nuy^nI8XSJb*BR{7#s@$)41x)81^n6PD$;A=dbkhl-NY;p!9rLJOJTXs3ewfE z2JD>#-v##$ISsK590UhL6KDx1`kYK^>EzRmv^Sg%MKBWn3|GNl;dWR6%Y94+bs-z3 z!ZcV0FZ!$^wXA_{@FVoupY?$LkPYX-1wMmGhd?e&f@|Rhm;!TP9y|f_VG%6$SwgxD zR=_%V8!{T<2hbP}g26BZa-a}KLN!c=Y49y3dKEpTXV-;mXhu4u&RhDOAHOm;>K};pg^$ zgeGt-w1Y0t3yPr(Dxn%4hB>ej*1&q;7Ut$qXaW~QE{uioa1Bg>+u@3h7<22Hu4YKK~@$3~5b0_9V5`hepuY=OEI!Rau-Czo^*@aDsO3}3+4zy+o`3XbtJn3yP4IYFU@F>iI zCt*G;g2k{LR={dl1MA>zcpqxu7pU8gc|ucY3+>@V=m=e*2iyj?!yPac?t$s>3)F2- zJ7^C#!ZdgeHp4GqIw1Ea9l)M>KYGAVU>;!29%L_oV<8Jlp%TWyc=!qqe28Nhn!zNv z4qk#a@EWZ3d6V=V*aFAQz`Q12ym;_`&BV($+JvH=F~xFczv|F}w=z zKn?s1_JaK+$b$Zm4TB&TM!{vU1pWc?xj!}nkw;e7NKegMniW%vQi_v|~{Xb10r`GIkv5gZ7ILknmHCqYN( z3f+9NNPEDk&=Y#WTv!W3el#W@GJj(JFd1%!7hyAe59Vj~OlSga;RNUa{oza)=~F>! z8SOKM)N;AcI8w`a_z^OGVXK9v&>6b>^dKD!aaaUP;6-=|UWM1;Em#ll0xMykCctHi z!{-_fpCLJXmf`T(k;8jt~)XCvppku0G8)P|-sf3?=s?!{E7fgdSP~&6L z9diVBTzCwghG$^`*vA>4v?ud|fshNspc<}(t6>hzgJ-~Sd+fTfmrs4t z6X9g&2wi=;lMaMj7zNdEH`Kru_y)cOQ_nGtp$T+?YIq73!E?Z)oO%Dln6L*lfJV?5 z4upf@MCb^ep}S8m=~$?SyI?WA2rJ0TxTQ0JXj1{!0dzl zp&fLBYHrgw6CQ>~U=GZMpWv{D)b(jcnhj-eCCq`PPy^qA$#6_BD1a&$56{37pEabP z!e;m$%zlpP04G6r=n1_c8!BLwPc`XMSP8GdYFH2N`k4J4vmZ2qlc5{*fNHo3Ciz@T zdIL;`sc;X>fI09vY=-Z_G-AD=E;N9KkO7UL1+;>8a6Fseb1HVlGXh{G@#4wt}UcTi|an4Q4{k zA2}Yt9D(1!{?Hk^!6}dpgJ6!2X~H~@q<(Y9lt49{dKCS)#V5hEb4=R~%n=5H>B;)^ zA|1}$FCiZ;hFmCwGFSwQVI{1Ajj$QM0W*SmLl&G0*)Rz5U^I+_$&gjTF$|^@zl1a4 zYM2c7Kn-kwkKkk23}1mMbIgCPCY{9j;Cj*hO^8s^!qo5U-8jdsA3l4%qp(z{* z&EaTh1?`|1Ci|ETjyVq6K_+Cu=`g@&%7@q(7Q^?j=3`Q*`4{Iy_!Pc?jqoLGhM&QF z${b-0tON5IdoyIiATVFD-$PwE0-8cIXzp_isih?x4;|oS=;YId)N+bXZ&J(YKK)27 z{ozbF3(kgfeaJqNw0zH;7*th z_rU`&6CQ?VVe=2z6YM=zKX{N2;CYN&r>D|P792i5%`}1OJOW@2)O?XJ0DDKf*gbH^f}a|6Wy(2@=aa7k+TQip4pSg=UznT>k+-L zPn>ISQ)U_vyV}Q8aNnm&K4hvg8D^B(kEc)XZ^jrtMB!h1bBsBGtKF0MCQnDcEs#$n zuYfnD#iq3>F>PqumbSdX+wLEaEb{-MlKr3fM{Y#+^8E^-dgQxOkQKa0^hCyS=``ml-2W5_s$21odLP3B=E{?+g}xF(GonkM}-%$&0`*x%F5v_9!3>#THBHjwlJ z>g|_da&5{#JEo<{85yR@U(&Ix8!ExFTw22(kVSst-_`qMm<#J>@L6Go*_e@G-iLSL zDdZ>Ms5JV4#k~Fw{zch6@D{9xXUY4jeumkWAx|s7+%kWm9%e6+LAW!lm7**fO%l|lN$PY2V!t9yv@Achi7;_2VUWI zDd|910aIWjc{6F-gxAwaZ-yJ;Pq2x()T7+`qV>rQ$eTzn#+M&yh`r%bUcXN|0iW*- z4d8O9fN$X>%8#b}Jzn1dA3_FlKk~bfK8#$>>p7&$kk2J;hWtIRm+(4HdK(OYy~#fn zeFiiCPNXd%@oy`(It$yrjgEG0+K_%l+7O!^#Cq3I_E*x@Dcd%P{1hnCmUn zf1Lgn;U@=@e?D0MwEOP{Y;!pIG33NPVtvi}`UuK)>tp4z|McoOFIGeqY8Z=(pncHikb5Y7@u*t@yph<(qIKv`;{>@%U0035mG8jm`fP zK7lV`6Kn&G&u8pOya(EXjnh8>Hdb$W2|kB!ARM>nk_Nx$?W~V|il?Q8PZsF~kPE5e z_|wR@Pky&|^X&xoDSeh~AN$n57}&UeHCzch6W3ozeT$9dTf%Yt4al1z9LKNA1PCu1!CG1Qbej)WO;kf$-WE*d{>};Gpb8qYk;dpusIT1&xbgvD|MIOq&5BTj}L!&9D5DyOq{s7_3nui*KL=K54YrXdq@=@4#$PJQRhe4 zUGd=~9%Qe9M4Y&U*ET*p6{f)^*p)c3GlTd1P#5-u`p^KHK_YH^1+O22Euit@pUJB~ zlej(DxN$GY1sga1Gt2`UH@4Wg@yGB9Y=Ui&h$FX{#dvTE^n`wp3yCc zCrF=!r(q#1_OUT%jXQr%o{c+y1HUKk{Ncmqcg2})toaD|uZ%bEYCJg+M^40#3y2L* zg=z5L5l7beu}R-PZd^rPHPj|~q>d}JsdJZE1o z4s0539|t~-JR1j|02&8Q&*1ZM7zyQIW5Je*FdGta;Pm~71%QqFCSt#d_-{FRiTLkC zUeAN)!N!4Y>~}};-(!j2c84t3nfUMf)Zf{7ZzeHYOCr8&`N2#-3XiMZ&RxssGdQ)Bo4vo*KVQ#3d8)$didb+IVC*4*7TDk2VhZ1=u*`7dsJ$wDHGN T!Nwph|3Cid#UFQ9-0}YaFE-mZ literal 0 HcmV?d00001 diff --git a/packages/language-adapters/package.json b/packages/language-adapters/package.json new file mode 100644 index 0000000..e1ccf63 --- /dev/null +++ b/packages/language-adapters/package.json @@ -0,0 +1,9 @@ +{ + "name": "@vectora/language-adapters", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MIT", + "exports": { ".": "./src/index.ts" }, + "dependencies": { "@vectora/graph-schema": "*", "typescript": "~5.9.3", "web-tree-sitter": "0.27.2" } +} diff --git a/packages/language-adapters/python/extract.py b/packages/language-adapters/python/extract.py new file mode 100644 index 0000000..5c24bf3 --- /dev/null +++ b/packages/language-adapters/python/extract.py @@ -0,0 +1,390 @@ +"""VECTORA Python source analysis. + +Reads a JSON list of {"path": , "abs": } from +stdin, parses each file with the standard-library ``ast`` module and writes +one JSON object per file to stdout. The analysed code is never imported or +executed. +""" +import ast +import json +import sys + +HTTP_METHODS = {"get", "post", "put", "patch", "delete", "head", "options"} +MODEL_BASES = {"Model", "Base", "DeclarativeBase", "SQLModel", "Document", "EmbeddedDocument", "BaseModel_"} +DB_READ = ("query", "select", "get", "filter", "all", "first", "count", "find", "fetch", "exists", "scalar", "execute") +DB_WRITE = ("add", "delete", "merge", "insert", "update", "save", "create", "remove", "bulk", "commit") + + +def dotted(node): + """Returns a dotted name for Name / Attribute chains, else None.""" + parts = [] + while isinstance(node, ast.Attribute): + parts.append(node.attr) + node = node.value + if isinstance(node, ast.Name): + parts.append(node.id) + return ".".join(reversed(parts)) + if isinstance(node, ast.Call): + inner = dotted(node.func) + if inner: + parts.append(inner + "()") + return ".".join(reversed(parts)) + return None + + +def loc(path, node): + return { + "path": path, + "startLine": getattr(node, "lineno", 1), + "endLine": getattr(node, "end_lineno", None) or getattr(node, "lineno", 1), + "startColumn": getattr(node, "col_offset", 0), + } + + +def first_line(text): + if not text: + return None + para = text.strip().split("\n\n")[0] + para = " ".join(para.split()) + return para[:297] + "..." if len(para) > 300 else para + + +class Extractor: + def __init__(self, path, source): + self.path = path + self.lines = source.splitlines() + self.symbols = [] + self.imports = [] + self.references = [] + self.used = set() + self.seen = set() + + def evidence(self, node): + i = getattr(node, "lineno", 1) - 1 + text = self.lines[i].strip() if 0 <= i < len(self.lines) else "" + return text[:197] + "..." if len(text) > 200 else text + + def unique(self, base): + ident, i = base, 2 + while ident in self.used: + ident = "%s~%d" % (base, i) + i += 1 + self.used.add(ident) + return ident + + def add_symbol(self, node, name, kind, parent, metadata=None, description=None): + local = self.unique("%s.%s" % (parent, name) if parent else name) + sym = { + "localId": local, + "name": name, + "kind": kind, + "parent": parent, + "location": loc(self.path, node), + "exported": not name.startswith("_"), + "metadata": metadata or {}, + } + if description: + sym["description"] = description + self.symbols.append(sym) + return local + + def add_ref(self, kind, frm, name, node, receiver=None, metadata=None): + key = (kind, frm, name, receiver) + if key in self.seen: + return + self.seen.add(key) + target = {"name": name} + if receiver: + target["receiver"] = receiver + ref = { + "kind": kind, + "from": frm, + "target": target, + "location": loc(self.path, node), + "evidence": self.evidence(node), + "method": "python-ast", + "confidence": 0, + "verified": False, + } + if metadata: + ref["metadata"] = metadata + self.references.append(ref) + + def add_resolved(self, kind, frm, local, node, method="pattern", confidence=0.95): + self.references.append({ + "kind": kind, + "from": frm, + "target": {"resolved": {"path": self.path, "localId": local}}, + "location": loc(self.path, node), + "evidence": self.evidence(node), + "method": method, + "confidence": confidence, + "verified": True, + }) + + # -- declarations ----------------------------------------------------- + + def decorators(self, node): + out = [] + for d in getattr(node, "decorator_list", []): + target = d.func if isinstance(d, ast.Call) else d + name = dotted(target) + if name: + out.append(name) + return out + + def route_info(self, node): + """Detects @app.get("/x"), @router.post("/x"), @app.route("/x", methods=[...]).""" + found = [] + for d in getattr(node, "decorator_list", []): + if not isinstance(d, ast.Call) or not isinstance(d.func, ast.Attribute): + continue + attr = d.func.attr + if not d.args or not isinstance(d.args[0], ast.Constant) or not isinstance(d.args[0].value, str): + continue + route = d.args[0].value + if attr in HTTP_METHODS: + found.append((attr.upper(), route, d)) + elif attr in ("route", "api_route", "websocket"): + methods = ["WS"] if attr == "websocket" else ["GET"] + for kw in d.keywords: + if kw.arg == "methods" and isinstance(kw.value, (ast.List, ast.Tuple)): + methods = [e.value.upper() for e in kw.value.elts if isinstance(e, ast.Constant) and isinstance(e.value, str)] or methods + for m in methods: + found.append((m, route, d)) + return found + + def visit_function(self, node, parent, in_class): + kind = "Method" if in_class else "Function" + args = [a.arg for a in node.args.args] + meta = { + "signature": "def %s(%s)" % (node.name, ", ".join(args)), + "decorators": self.decorators(node), + } + if isinstance(node, ast.AsyncFunctionDef): + meta["async"] = True + local = self.add_symbol(node, node.name, kind, parent, meta, first_line(ast.get_docstring(node))) + for method, route, dec in self.route_info(node): + ep = self.unique("route:%s %s" % (method, route)) + self.symbols.append({ + "localId": ep, + "name": "%s %s" % (method, route), + "kind": "ApiEndpoint", + "parent": None, + "location": loc(self.path, dec), + "exported": False, + "metadata": {"httpMethod": method, "routePath": route, "framework": "decorator"}, + }) + self.add_resolved("ROUTES_TO", ep, local, dec) + for d in node.decorator_list: + self.visit_expr(d, local) + for a in list(node.args.args) + list(node.args.kwonlyargs): + if a.annotation is not None: + self.visit_annotation(a.annotation, local) + if node.returns is not None: + self.visit_annotation(node.returns, local) + for stmt in node.body: + self.visit_body(stmt, local) + return local + + def visit_class(self, node, parent): + bases = [dotted(b) for b in node.bases] + bases = [b for b in bases if b] + has_table = any( + isinstance(s, ast.Assign) and any(isinstance(t, ast.Name) and t.id == "__tablename__" for t in s.targets) + for s in node.body + ) + is_model = has_table or any(b.split(".")[-1] in MODEL_BASES for b in bases) + kind = "DatabaseModel" if is_model else "Class" + meta = {"bases": bases, "decorators": self.decorators(node)} + local = self.add_symbol(node, node.name, kind, parent, meta, first_line(ast.get_docstring(node))) + for b in node.bases: + name = dotted(b) + if name: + parts = name.split(".") + self.add_ref("EXTENDS", local, parts[-1], b, ".".join(parts[:-1]) or None) + for d in node.decorator_list: + self.visit_expr(d, local) + for stmt in node.body: + if isinstance(stmt, (ast.FunctionDef, ast.AsyncFunctionDef)): + self.visit_function(stmt, local, True) + elif isinstance(stmt, ast.ClassDef): + self.visit_class(stmt, local) + else: + self.visit_body(stmt, local) + return local + + def visit_module(self, tree): + for stmt in tree.body: + if isinstance(stmt, (ast.FunctionDef, ast.AsyncFunctionDef)): + self.visit_function(stmt, None, False) + elif isinstance(stmt, ast.ClassDef): + self.visit_class(stmt, None) + elif isinstance(stmt, (ast.Assign, ast.AnnAssign)): + targets = stmt.targets if isinstance(stmt, ast.Assign) else [stmt.target] + owner = None + for t in targets: + if isinstance(t, ast.Name) and not (t.id.startswith("__") and t.id.endswith("__")): + kind = "Constant" if t.id.isupper() else "Variable" + owner = self.add_symbol(stmt, t.id, kind, None) + value = stmt.value + if value is not None: + self.visit_expr(value, owner) + # Django: urlpatterns = [path("x/", views.handler), ...] + if any(isinstance(t, ast.Name) and t.id == "urlpatterns" for t in targets) and isinstance(value, (ast.List, ast.Tuple)): + self.django_urls(value) + else: + self.visit_body(stmt, None) + + def django_urls(self, value): + for e in value.elts: + if not isinstance(e, ast.Call) or dotted(e.func) not in ("path", "re_path", "url"): + continue + if len(e.args) < 2 or not isinstance(e.args[0], ast.Constant) or not isinstance(e.args[0].value, str): + continue + route = "/" + e.args[0].value.lstrip("^/").rstrip("$") + ep = self.unique("route:ANY %s" % route) + self.symbols.append({ + "localId": ep, + "name": "ANY %s" % route, + "kind": "ApiEndpoint", + "parent": None, + "location": loc(self.path, e), + "exported": False, + "metadata": {"httpMethod": "ANY", "routePath": route, "framework": "urlpatterns"}, + }) + handler = e.args[1] + if isinstance(handler, ast.Call) and isinstance(handler.func, ast.Attribute) and handler.func.attr == "as_view": + handler = handler.func.value + name = dotted(handler) + if name and not name.endswith("()"): + parts = name.split(".") + self.add_ref("ROUTES_TO", ep, parts[-1], e, ".".join(parts[:-1]) or None) + + # -- bodies ----------------------------------------------------------- + + def visit_body(self, stmt, owner): + if isinstance(stmt, (ast.Import, ast.ImportFrom)): + self.visit_import(stmt) + return + if isinstance(stmt, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)): + # Nested definitions are attributed to the enclosing symbol. + for inner in stmt.body: + self.visit_body(inner, owner) + return + for node in ast.walk(stmt): + if isinstance(node, (ast.Import, ast.ImportFrom)): + self.visit_import(node) + elif isinstance(node, ast.Call): + self.visit_call(node, owner) + elif isinstance(node, ast.AnnAssign) and node.annotation is not None: + self.visit_annotation(node.annotation, owner) + + def visit_expr(self, expr, owner): + for node in ast.walk(expr): + if isinstance(node, ast.Call): + self.visit_call(node, owner) + + def visit_annotation(self, ann, owner): + for node in ast.walk(ann): + if isinstance(node, ast.Name): + self.add_ref("USES", owner, node.id, node, None, {"typeOnly": True}) + elif isinstance(node, ast.Attribute): + name = dotted(node) + if name: + parts = name.split(".") + self.add_ref("USES", owner, parts[-1], node, ".".join(parts[:-1]), {"typeOnly": True}) + + def visit_call(self, node, owner): + name = dotted(node.func) + if not name: + return + parts = name.split(".") + callee = parts[-1] + receiver = ".".join(parts[:-1]) or None + arg_names = [] + plain_args = [] + for a in node.args[:4]: + target = a.func if isinstance(a, ast.Call) else a + n = dotted(target) + if n and not n.endswith("()"): + arg_names.append(n) + if not isinstance(a, ast.Call): + plain_args.append(n) + meta = {} + if arg_names: + meta["args"] = arg_names + if callee.startswith(DB_WRITE): + meta["db"] = "write" + elif callee.startswith(DB_READ): + meta["db"] = "read" + if callee.endswith("()"): + return + self.add_ref("CALLS", owner, callee, node, receiver, meta or None) + # Names passed as arguments are potential references (callbacks, models). + for n in plain_args: + p = n.split(".") + self.add_ref("USES", owner, p[-1], node, ".".join(p[:-1]) or None, {"argument": True}) + + def visit_import(self, node): + if isinstance(node, ast.Import): + for alias in node.names: + self.imports.append({ + "specifier": alias.name, + "names": [{"imported": "*", "local": alias.asname or alias.name.split(".")[0]}], + "kind": "static", + "location": loc(self.path, node), + "evidence": self.evidence(node), + "metadata": {"alias": bool(alias.asname)}, + }) + else: + spec = "." * (node.level or 0) + (node.module or "") + self.imports.append({ + "specifier": spec, + "names": [{"imported": a.name, "local": a.asname or a.name} for a in node.names], + "kind": "static", + "location": loc(self.path, node), + "evidence": self.evidence(node), + }) + + +def analyze(path, abs_path): + result = {"path": path, "symbols": [], "imports": [], "references": [], "errors": [], "lineCount": 0} + try: + with open(abs_path, "rb") as fh: + raw = fh.read() + source = raw.decode("utf-8", errors="replace") + except OSError as exc: + result["errors"].append({"path": path, "message": "File could not be read: %s" % exc, "severity": "error"}) + return result + result["lineCount"] = source.count("\n") + 1 + try: + tree = ast.parse(source, filename=path) + except SyntaxError as exc: + result["errors"].append({"path": path, "message": "Syntax error: %s" % exc.msg, "line": exc.lineno, "severity": "error"}) + return result + except (ValueError, RecursionError) as exc: + result["errors"].append({"path": path, "message": "Parse failed: %s" % exc, "severity": "error"}) + return result + ex = Extractor(path, source) + try: + ex.visit_module(tree) + except RecursionError: + result["errors"].append({"path": path, "message": "File nesting too deep to analyse", "severity": "error"}) + result["symbols"] = ex.symbols + result["imports"] = ex.imports + result["references"] = ex.references + return result + + +def main(): + files = json.load(sys.stdin) + out = sys.stdout + for f in files: + out.write(json.dumps(analyze(f["path"], f["abs"]))) + out.write("\n") + out.flush() + + +if __name__ == "__main__": + main() diff --git a/packages/language-adapters/src/assets.ts b/packages/language-adapters/src/assets.ts new file mode 100644 index 0000000..6e8a8a9 --- /dev/null +++ b/packages/language-adapters/src/assets.ts @@ -0,0 +1,20 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +/** + * Locates a bundled asset (grammar or helper script). Works both when running + * from source (`packages/language-adapters/src`) and from the bundled engine + * (`dist/engine`, with assets copied next to the bundle). + */ +export function assetPath(kind: 'grammars' | 'python', name: string): string { + const here = path.dirname(fileURLToPath(import.meta.url)); + const candidates = [ + process.env.VECTORA_ASSET_DIR ? path.join(process.env.VECTORA_ASSET_DIR, kind, name) : null, + path.join(here, '..', kind, name), + path.join(here, kind, name), + path.join(here, '..', '..', kind, name), + ].filter((c): c is string => !!c); + for (const c of candidates) if (fs.existsSync(c)) return c; + throw new Error(`Bundled asset not found: ${kind}/${name}`); +} diff --git a/packages/language-adapters/src/index.ts b/packages/language-adapters/src/index.ts new file mode 100644 index 0000000..2c9fa93 --- /dev/null +++ b/packages/language-adapters/src/index.ts @@ -0,0 +1,19 @@ +import { createPythonAdapter } from './python-adapter'; +import { createTreeSitterAdapter } from './treesitter-adapter'; +import { createTypeScriptAdapter } from './typescript-adapter'; +import type { LanguageAdapter } from './types'; + +export * from './types'; +export * from './languages'; +export { createTypeScriptAdapter } from './typescript-adapter'; +export { createPythonAdapter, findPython } from './python-adapter'; +export { createTreeSitterAdapter } from './treesitter-adapter'; + +/** All built-in adapters. New languages are added by registering another adapter here. */ +export function createAdapters(): LanguageAdapter[] { + return [createTypeScriptAdapter(), createPythonAdapter(), createTreeSitterAdapter()]; +} + +export function adapterForLanguage(adapters: LanguageAdapter[], language: string): LanguageAdapter | null { + return adapters.find((a) => a.languages.some((l) => l.id === language)) ?? null; +} diff --git a/packages/language-adapters/src/languages.ts b/packages/language-adapters/src/languages.ts new file mode 100644 index 0000000..7e206f4 --- /dev/null +++ b/packages/language-adapters/src/languages.ts @@ -0,0 +1,150 @@ +import type { LanguageMeta } from './types'; + +/** Languages with a symbol-level adapter. */ +export const SUPPORTED_LANGUAGES: LanguageMeta[] = [ + { id: 'typescript', name: 'TypeScript', tier: 1, extensions: ['.ts', '.tsx', '.mts', '.cts'] }, + { id: 'javascript', name: 'JavaScript', tier: 1, extensions: ['.js', '.jsx', '.mjs', '.cjs'] }, + { id: 'python', name: 'Python', tier: 1, extensions: ['.py', '.pyi'] }, + { id: 'java', name: 'Java', tier: 2, extensions: ['.java'] }, + { id: 'go', name: 'Go', tier: 2, extensions: ['.go'] }, + { id: 'rust', name: 'Rust', tier: 2, extensions: ['.rs'] }, + { id: 'c', name: 'C', tier: 2, extensions: ['.c', '.h'] }, + { id: 'cpp', name: 'C++', tier: 2, extensions: ['.cpp', '.cc', '.cxx', '.hpp', '.hh', '.hxx'] }, + { id: 'csharp', name: 'C#', tier: 2, extensions: ['.cs'] }, +]; + +/** Recognised but not analysed at symbol level. Shown in language coverage. */ +const DETECT_ONLY: Record = { + '.rb': 'ruby', + '.php': 'php', + '.kt': 'kotlin', + '.kts': 'kotlin', + '.swift': 'swift', + '.scala': 'scala', + '.dart': 'dart', + '.lua': 'lua', + '.sh': 'shell', + '.bash': 'shell', + '.ps1': 'powershell', + '.sql': 'sql', + '.vue': 'vue', + '.svelte': 'svelte', + '.html': 'html', + '.htm': 'html', + '.css': 'css', + '.scss': 'scss', + '.less': 'less', + '.json': 'json', + '.yaml': 'yaml', + '.yml': 'yaml', + '.toml': 'toml', + '.xml': 'xml', + '.md': 'markdown', + '.mdx': 'markdown', + '.rst': 'restructuredtext', + '.txt': 'text', + '.ini': 'ini', + '.cfg': 'ini', + '.gradle': 'gradle', + '.proto': 'protobuf', + '.graphql': 'graphql', + '.prisma': 'prisma', + '.tf': 'terraform', + '.r': 'r', + '.m': 'objective-c', + '.ex': 'elixir', + '.exs': 'elixir', + '.hs': 'haskell', + '.zig': 'zig', +}; + +const DISPLAY: Record = { + ...Object.fromEntries(SUPPORTED_LANGUAGES.map((l) => [l.id, l.name])), + ruby: 'Ruby', + php: 'PHP', + kotlin: 'Kotlin', + swift: 'Swift', + scala: 'Scala', + dart: 'Dart', + lua: 'Lua', + shell: 'Shell', + powershell: 'PowerShell', + sql: 'SQL', + vue: 'Vue', + svelte: 'Svelte', + html: 'HTML', + css: 'CSS', + scss: 'SCSS', + less: 'Less', + json: 'JSON', + yaml: 'YAML', + toml: 'TOML', + xml: 'XML', + markdown: 'Markdown', + restructuredtext: 'reStructuredText', + text: 'Text', + ini: 'INI', + gradle: 'Gradle', + protobuf: 'Protocol Buffers', + graphql: 'GraphQL', + prisma: 'Prisma schema', + terraform: 'Terraform', + r: 'R', + 'objective-c': 'Objective-C', + elixir: 'Elixir', + haskell: 'Haskell', + zig: 'Zig', + dockerfile: 'Dockerfile', + makefile: 'Makefile', +}; + +const EXT_TO_LANG = new Map(); +for (const l of SUPPORTED_LANGUAGES) for (const e of l.extensions) EXT_TO_LANG.set(e, l.id); + +const FILENAMES: Record = { + dockerfile: 'dockerfile', + makefile: 'makefile', + 'cmakelists.txt': 'cmake', +}; + +export const BINARY_EXTENSIONS = new Set( + ( + 'png jpg jpeg gif bmp ico webp avif tiff psd svgz mp3 mp4 mov avi mkv wav flac ogg webm woff woff2 ttf otf eot ' + + 'zip gz tgz bz2 xz 7z rar tar jar war ear class exe dll so dylib a o obj lib bin dat db sqlite sqlite3 pdf doc docx ' + + 'xls xlsx ppt pptx wasm pyc pyo node iso dmg pkg deb rpm apk ipa keystore jks p12 pfx parquet npy npz h5 onnx pt' + ) + .split(' ') + .map((e) => `.${e}`), +); + +export function extensionOf(path: string): string { + const base = path.slice(path.lastIndexOf('/') + 1); + const dot = base.lastIndexOf('.'); + return dot <= 0 ? '' : base.slice(dot).toLowerCase(); +} + +/** Returns a language id for a path, or null when the file type is unknown. */ +export function detectLanguage(path: string): string | null { + const base = path.slice(path.lastIndexOf('/') + 1).toLowerCase(); + if (FILENAMES[base]) return FILENAMES[base]; + if (base.startsWith('dockerfile')) return 'dockerfile'; + const ext = extensionOf(path); + return EXT_TO_LANG.get(ext) ?? DETECT_ONLY[ext] ?? null; +} + +export const isBinaryPath = (path: string): boolean => BINARY_EXTENSIONS.has(extensionOf(path)); + +export const languageName = (id: string): string => DISPLAY[id] ?? id; + +export const languageTier = (id: string): 0 | 1 | 2 => SUPPORTED_LANGUAGES.find((l) => l.id === id)?.tier ?? 0; + +/** Heuristic check for generated or minified content that would only add noise. */ +export function looksGenerated(path: string, head: string): boolean { + if (/\.(generated|gen|pb|min)\.[a-z]+$/i.test(path) || /_pb2(_grpc)?\.py$/.test(path) || /\.d\.ts$/.test(path)) return true; + const first = head.slice(0, 600); + if (/@generated|DO NOT EDIT|auto-?generated by|This file was automatically generated/i.test(first)) return true; + // Minified: very long first line with little whitespace. + const nl = head.indexOf('\n'); + const line = nl === -1 ? head : head.slice(0, nl); + return line.length > 2000; +} diff --git a/packages/language-adapters/src/python-adapter.ts b/packages/language-adapters/src/python-adapter.ts new file mode 100644 index 0000000..9152b74 --- /dev/null +++ b/packages/language-adapters/src/python-adapter.ts @@ -0,0 +1,122 @@ +/** + * Python adapter. Delegates parsing to the Python standard-library `ast` + * module through a helper script. The analysed code is parsed only — it is + * never imported or executed. + */ +import { spawn, spawnSync } from 'node:child_process'; +import { assetPath } from './assets'; +import { type AnalyzeContext, type FileFacts, type LanguageAdapter, type SourceFileInput, emptyFacts } from './types'; + +const BATCH_SIZE = 200; +let cachedCommand: { cmd: string; args: string[] } | null | undefined; + +/** Finds a Python 3 interpreter. Returns null when none is installed. */ +export function findPython(preferred?: string): { cmd: string; args: string[] } | null { + if (cachedCommand !== undefined && !preferred) return cachedCommand; + const candidates: { cmd: string; args: string[] }[] = []; + if (preferred) candidates.push({ cmd: preferred, args: [] }); + if (process.env.VECTORA_PYTHON) candidates.push({ cmd: process.env.VECTORA_PYTHON, args: [] }); + candidates.push({ cmd: 'python3', args: [] }, { cmd: 'python', args: [] }, { cmd: 'py', args: ['-3'] }); + for (const c of candidates) { + try { + const r = spawnSync(c.cmd, [...c.args, '-c', 'import sys; print(sys.version_info[0])'], { encoding: 'utf8', timeout: 10000, windowsHide: true }); + if (r.status === 0 && r.stdout.trim() === '3') { + if (!preferred) cachedCommand = c; + return c; + } + } catch { + // try next candidate + } + } + if (!preferred) cachedCommand = null; + return null; +} + +function runBatch(py: { cmd: string; args: string[] }, script: string, batch: SourceFileInput[]): Promise>> { + return new Promise((resolve, reject) => { + // -I: isolated mode, so the interpreter does not pick up modules from the analysed repository. + const child = spawn(py.cmd, [...py.args, '-I', script], { stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true }); + const chunks: Buffer[] = []; + let stderr = ''; + child.stdout.on('data', (d: Buffer) => chunks.push(d)); + child.stderr.on('data', (d: Buffer) => (stderr += d.toString('utf8').slice(0, 2000))); + child.on('error', reject); + child.on('close', (code) => { + const out = new Map>(); + for (const line of Buffer.concat(chunks).toString('utf8').split('\n')) { + if (!line.trim()) continue; + try { + const obj = JSON.parse(line) as Partial & { path: string }; + out.set(obj.path, obj); + } catch { + // ignore a malformed line; the file is reported as not analysed below + } + } + if (code !== 0 && out.size === 0) reject(new Error(`Python analysis exited with code ${code}: ${stderr.trim()}`)); + else resolve(out); + }); + child.stdin.on('error', () => undefined); + child.stdin.end(JSON.stringify(batch.map((f) => ({ path: f.path, abs: f.absPath })))); + }); +} + +export function createPythonAdapter(): LanguageAdapter { + return { + id: 'python', + technique: 'Python standard-library ast module', + scope: 'file', + languages: [{ id: 'python', name: 'Python', tier: 1, extensions: ['.py', '.pyi'] }], + async analyze(files: SourceFileInput[], ctx: AnalyzeContext): Promise { + if (files.length === 0) return []; + const py = findPython(ctx.pythonCommand); + if (!py) { + return files.map((f) => { + const facts = emptyFacts(f, 'python'); + facts.errors.push({ path: f.path, message: 'No Python 3 interpreter found; Python files were not analysed', severity: 'error' }); + return facts; + }); + } + const script = assetPath('python', 'extract.py'); + const results: FileFacts[] = []; + let done = 0; + for (let i = 0; i < files.length; i += BATCH_SIZE) { + const batch = files.slice(i, i + BATCH_SIZE); + let parsed: Map>; + try { + parsed = await runBatch(py, script, batch); + } catch (err) { + parsed = new Map(); + for (const f of batch) { + const facts = emptyFacts(f, 'python'); + facts.errors.push({ path: f.path, message: (err as Error).message, severity: 'error' }); + results.push(facts); + } + done += batch.length; + ctx.onProgress?.(done, files.length); + continue; + } + for (const f of batch) { + const p = parsed.get(f.path); + const facts = emptyFacts(f, 'python', p?.lineCount ?? 0); + if (p) { + facts.symbols = p.symbols ?? []; + facts.imports = p.imports ?? []; + facts.references = p.references ?? []; + facts.errors = p.errors ?? []; + } else { + facts.errors.push({ path: f.path, message: 'No analysis result returned', severity: 'error' }); + } + // Dotted module name derived from the path: `pkg/sub/mod.py` -> `pkg.sub.mod`. + facts.moduleName = f.path + .replace(/\.pyi?$/, '') + .replace(/\/__init__$/, '') + .replace(/\//g, '.'); + results.push(facts); + } + done += batch.length; + ctx.onProgress?.(done, files.length); + } + return results; + }, + }; +} diff --git a/packages/language-adapters/src/treesitter-adapter.ts b/packages/language-adapters/src/treesitter-adapter.ts new file mode 100644 index 0000000..0fa1bc1 --- /dev/null +++ b/packages/language-adapters/src/treesitter-adapter.ts @@ -0,0 +1,865 @@ +/** + * Tree-sitter adapter for Java, Go, Rust, C, C++ and C#. + * + * Extracts declarations, imports, inheritance and call sites from the syntax + * tree. References are emitted by name only; the indexer decides whether a + * name can be tied to a definition (same file, imported file or same package) + * and otherwise reports it as unresolved. + */ +import fs from 'node:fs'; +import { Language, type Node, Parser } from 'web-tree-sitter'; +import type { EdgeType, NodeType, SourceLocation } from '@vectora/graph-schema'; +import { assetPath } from './assets'; +import { + type AnalyzeContext, + type FileFacts, + type LanguageAdapter, + type SourceFileInput, + emptyFacts, + evidenceLine, + uniqueLocalId, +} from './types'; + +const GRAMMAR_FILES: Record = { + java: 'tree-sitter-java.wasm', + go: 'tree-sitter-go.wasm', + rust: 'tree-sitter-rust.wasm', + c: 'tree-sitter-c.wasm', + cpp: 'tree-sitter-cpp.wasm', + csharp: 'tree-sitter-c_sharp.wasm', +}; + +let initPromise: Promise | null = null; +const languageCache = new Map>(); + +async function loadLanguage(lang: string): Promise { + initPromise ??= Parser.init(); + await initPromise; + let p = languageCache.get(lang); + if (!p) { + const file = GRAMMAR_FILES[lang]; + if (!file) throw new Error(`No grammar for ${lang}`); + p = Language.load(fs.readFileSync(assetPath('grammars', file))); + languageCache.set(lang, p); + } + return p; +} + +const SPRING_MAPPINGS: Record = { + GetMapping: 'GET', + PostMapping: 'POST', + PutMapping: 'PUT', + DeleteMapping: 'DELETE', + PatchMapping: 'PATCH', + RequestMapping: 'ANY', +}; +const ASPNET_ATTRS: Record = { HttpGet: 'GET', HttpPost: 'POST', HttpPut: 'PUT', HttpDelete: 'DELETE', HttpPatch: 'PATCH' }; +const GO_ROUTE_FUNCS = new Set(['HandleFunc', 'Handle', 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'Get', 'Post', 'Put', 'Delete', 'Patch']); + +class FileExtractor { + facts: FileFacts; + private used = new Set(); + private seen = new Set(); + private lines: string[]; + + constructor( + private file: SourceFileInput, + private source: string, + ) { + this.lines = source.split(/\r?\n/); + this.facts = emptyFacts(file, 'tree-sitter', this.lines.length); + } + + loc(n: Node): SourceLocation { + return { path: this.file.path, startLine: n.startPosition.row + 1, endLine: n.endPosition.row + 1, startColumn: n.startPosition.column }; + } + evidence(n: Node): string { + return evidenceLine(this.lines[n.startPosition.row] ?? ''); + } + /** Leading `//`, `///` or block comment directly above a declaration. */ + doc(n: Node): string | undefined { + const prev = n.previousNamedSibling; + if (!prev || !/comment/.test(prev.type) || n.startPosition.row - prev.endPosition.row > 1) return undefined; + const text = prev.text + .replace(/^\/\*+|\*+\/$/g, '') + .split('\n') + .map((l) => l.replace(/^\s*(\/\/[/!]?|\*|#)\s?/, '').trim()) + .filter(Boolean) + .join(' '); + if (!text) return undefined; + return text.length > 300 ? `${text.slice(0, 297)}...` : text; + } + symbol(n: Node, name: string, kind: NodeType, parent: string | null, exported: boolean, metadata: Record = {}): string { + const localId = uniqueLocalId(this.used, parent ? `${parent}.${name}` : name); + const description = this.doc(n); + this.facts.symbols.push({ localId, name, kind, parent, location: this.loc(n), exported, metadata, ...(description ? { description } : {}) }); + return localId; + } + endpoint(n: Node, method: string, routePath: string, handler: string | null, handlerName?: { name: string; receiver?: string }): void { + const p = routePath.startsWith('/') ? routePath : `/${routePath}`; + const localId = uniqueLocalId(this.used, `route:${method} ${p}`); + this.facts.symbols.push({ + localId, + name: `${method} ${p}`, + kind: 'ApiEndpoint', + parent: null, + location: this.loc(n), + exported: false, + metadata: { httpMethod: method, routePath: p }, + }); + if (handler) { + this.facts.references.push({ + kind: 'ROUTES_TO', + from: localId, + target: { resolved: { path: this.file.path, localId: handler } }, + location: this.loc(n), + evidence: this.evidence(n), + method: 'pattern', + confidence: 0.95, + verified: true, + }); + } else if (handlerName) { + this.ref('ROUTES_TO', localId, handlerName.name, n, handlerName.receiver); + } + } + ref(kind: EdgeType, from: string | null, name: string, n: Node, receiver?: string, metadata?: Record): void { + if (!name) return; + const key = `${kind}|${from}|${receiver ?? ''}|${name}`; + if (this.seen.has(key)) return; + this.seen.add(key); + this.facts.references.push({ + kind, + from, + target: receiver ? { name, receiver } : { name }, + location: this.loc(n), + evidence: this.evidence(n), + method: 'tree-sitter', + confidence: 0, + verified: false, + ...(metadata ? { metadata } : {}), + }); + } + import(n: Node, specifier: string, names: { imported: string; local: string }[], kind: 'static' | 'include' = 'static'): void { + this.facts.imports.push({ specifier, names, kind, location: this.loc(n), evidence: this.evidence(n) }); + } +} + +const field = (n: Node, name: string): Node | null => n.childForFieldName(name); +const named = (n: Node): Node[] => n.namedChildren.filter((c): c is Node => !!c); +const stripQuotes = (s: string): string => s.replace(/^[<"'`]|[>"'`]$/g, ''); +const lastSegment = (s: string, sep: string | RegExp): string => s.split(sep).filter(Boolean).pop() ?? s; +const firstString = (n: Node): string | null => { + const hit = n.descendantsOfType(['string_literal', 'interpreted_string_literal', 'raw_string_literal', 'string_content', 'string_literal_content']).find((x) => !!x); + return hit ? stripQuotes(hit.text) : null; +}; + +type Walker = (ex: FileExtractor, root: Node) => void; + +// --------------------------------------------------------------------------- +// Call collection shared by all languages +// --------------------------------------------------------------------------- + +interface CallSpec { + /** node type -> how to read callee name and receiver */ + calls: Record { name: string; receiver?: string } | null>; + news: Record string | null>; + /** node types that start a nested declaration handled elsewhere */ + stop: Set; +} + +function collectCalls(ex: FileExtractor, body: Node | null, owner: string | null, spec: CallSpec): void { + if (!body) return; + const walk = (n: Node, top: boolean) => { + if (!top && spec.stop.has(n.type)) return; + const call = spec.calls[n.type]; + if (call) { + const c = call(n); + if (c?.name) ex.ref('CALLS', owner, c.name, n, c.receiver); + } + const nw = spec.news[n.type]; + if (nw) { + const t = nw(n); + if (t) ex.ref('INSTANTIATES', owner, t, n); + } + for (const c of n.namedChildren) if (c) walk(c, false); + }; + walk(body, true); +} + +// --------------------------------------------------------------------------- +// Java +// --------------------------------------------------------------------------- + +const javaCalls: CallSpec = { + calls: { + method_invocation: (n) => { + const name = field(n, 'name')?.text ?? ''; + const obj = field(n, 'object'); + return { name, receiver: obj ? obj.text.slice(0, 60) : undefined }; + }, + }, + news: { object_creation_expression: (n) => lastSegment(field(n, 'type')?.text.replace(/<.*$/, '') ?? '', '.') }, + stop: new Set(['class_declaration', 'interface_declaration', 'enum_declaration', 'record_declaration']), +}; + +function javaAnnotations(n: Node): { name: string; node: Node }[] { + const mods = named(n).find((c) => c.type === 'modifiers'); + if (!mods) return []; + return named(mods) + .filter((c) => c.type === 'marker_annotation' || c.type === 'annotation') + .map((c) => ({ name: lastSegment(field(c, 'name')?.text ?? '', '.'), node: c })); +} +const javaIsPublic = (n: Node): boolean => !/\bprivate\b/.test(named(n).find((c) => c.type === 'modifiers')?.text ?? ''); + +const walkJava: Walker = (ex, root) => { + const visitType = (n: Node, parent: string | null) => { + const name = field(n, 'name')?.text; + if (!name) return; + const ann = javaAnnotations(n); + const kindBase: NodeType = n.type === 'interface_declaration' ? 'Interface' : n.type === 'enum_declaration' ? 'Type' : 'Class'; + const kind: NodeType = ann.some((a) => a.name === 'Entity' || a.name === 'Table' || a.name === 'Document') ? 'DatabaseModel' : kindBase; + const id = ex.symbol(n, name, kind, parent, javaIsPublic(n), { annotations: ann.map((a) => a.name) }); + const sup = field(n, 'superclass'); + if (sup) for (const t of sup.descendantsOfType('type_identifier')) if (t) ex.ref('EXTENDS', id, t.text, t); + const ifs = field(n, 'interfaces') ?? named(n).find((c) => c.type === 'extends_interfaces'); + if (ifs) + for (const t of ifs.descendantsOfType('type_identifier')) + if (t && t.parent?.type !== 'type_arguments') ex.ref(n.type === 'interface_declaration' ? 'EXTENDS' : 'IMPLEMENTS', id, t.text, t); + const classMapping = ann.find((a) => a.name === 'RequestMapping'); + const basePath = classMapping ? (firstString(classMapping.node) ?? '') : ''; + const body = field(n, 'body'); + if (!body) return; + for (const m of named(body)) { + if (m.type === 'method_declaration' || m.type === 'constructor_declaration') { + const mname = field(m, 'name')?.text ?? 'constructor'; + const mann = javaAnnotations(m); + const mid = ex.symbol(m, mname, 'Method', id, javaIsPublic(m), { annotations: mann.map((a) => a.name) }); + for (const a of mann) { + const http = SPRING_MAPPINGS[a.name]; + if (http) ex.endpoint(a.node, http, `${basePath}/${firstString(a.node) ?? ''}`.replace(/\/+/g, '/').replace(/(.)\/$/, '$1'), mid); + } + const params = field(m, 'parameters'); + if (params) for (const t of params.descendantsOfType('type_identifier')) if (t) ex.ref('USES', mid, t.text, t, undefined, { typeOnly: true }); + collectCalls(ex, field(m, 'body'), mid, javaCalls); + } else if (m.type === 'field_declaration') { + const t = field(m, 'type'); + if (t) for (const ti of [t, ...t.descendantsOfType('type_identifier')]) if (ti && ti.type === 'type_identifier') ex.ref('USES', id, ti.text, ti, undefined, { typeOnly: true }); + collectCalls(ex, m, id, javaCalls); + } else if (/_declaration$/.test(m.type) && field(m, 'name')) { + visitType(m, id); + } + } + }; + for (const n of named(root)) { + if (n.type === 'package_declaration') { + ex.facts.moduleName = named(n).find((c) => c.type === 'scoped_identifier' || c.type === 'identifier')?.text; + } else if (n.type === 'import_declaration') { + const path = named(n).find((c) => c.type === 'scoped_identifier' || c.type === 'identifier')?.text ?? ''; + const wildcard = n.text.includes('*'); + const name = lastSegment(path, '.'); + ex.import(n, wildcard ? `${path}.*` : path, [{ imported: wildcard ? '*' : name, local: wildcard ? '*' : name }]); + } else if (/_declaration$/.test(n.type)) { + visitType(n, null); + } + } +}; + +// --------------------------------------------------------------------------- +// Go +// --------------------------------------------------------------------------- + +const goCalls: CallSpec = { + calls: { + call_expression: (n) => { + const fn = field(n, 'function'); + if (!fn) return null; + if (fn.type === 'identifier') return { name: fn.text }; + if (fn.type === 'selector_expression') return { name: field(fn, 'field')?.text ?? '', receiver: field(fn, 'operand')?.text }; + return null; + }, + }, + news: { + composite_literal: (n) => { + const t = field(n, 'type'); + return t?.type === 'type_identifier' ? t.text : t?.type === 'qualified_type' ? (field(t, 'name')?.text ?? null) : null; + }, + }, + stop: new Set(), +}; +const goExported = (name: string): boolean => /^[A-Z]/.test(name); + +const walkGo: Walker = (ex, root) => { + const goRoutes = (body: Node | null) => { + if (!body) return; + for (const call of body.descendantsOfType('call_expression')) { + if (!call) continue; + const fn = field(call, 'function'); + if (fn?.type !== 'selector_expression') continue; + const fname = field(fn, 'field')?.text ?? ''; + if (!GO_ROUTE_FUNCS.has(fname)) continue; + const args = named(field(call, 'arguments') ?? call); + const a0 = args[0]; + if (!a0 || !/string_literal/.test(a0.type)) continue; + const route = stripQuotes(a0.text); + if (!route.startsWith('/') && !/^[A-Z]+ \//.test(route)) continue; + const h = args[args.length - 1]; + const method = /^(GET|POST|PUT|DELETE|PATCH)$/i.test(fname) ? fname.toUpperCase() : 'ANY'; + const handlerName = + h && h !== a0 + ? h.type === 'identifier' + ? { name: h.text } + : h.type === 'selector_expression' + ? { name: field(h, 'field')?.text ?? '', receiver: field(h, 'operand')?.text } + : undefined + : undefined; + ex.endpoint(call, method, route, null, handlerName); + } + }; + for (const n of named(root)) { + switch (n.type) { + case 'package_clause': + ex.facts.moduleName = named(n)[0]?.text; + break; + case 'import_declaration': + for (const spec of n.descendantsOfType('import_spec')) { + if (!spec) continue; + const p = stripQuotes(field(spec, 'path')?.text ?? ''); + const alias = field(spec, 'name')?.text; + ex.import(spec, p, [{ imported: '*', local: alias && alias !== '_' && alias !== '.' ? alias : lastSegment(p, '/') }]); + } + break; + case 'function_declaration': { + const name = field(n, 'name')?.text; + if (!name) break; + const id = ex.symbol(n, name, 'Function', null, goExported(name)); + collectCalls(ex, field(n, 'body'), id, goCalls); + goRoutes(field(n, 'body')); + break; + } + case 'method_declaration': { + const name = field(n, 'name')?.text; + if (!name) break; + const recv = field(n, 'receiver')?.descendantsOfType('type_identifier')[0]?.text ?? null; + // Methods are attached to their receiver type when it is declared in this file. + const parent = recv && ex.facts.symbols.some((s) => s.localId === recv) ? recv : null; + const id = ex.symbol(n, name, 'Method', parent, goExported(name), { receiver: recv }); + collectCalls(ex, field(n, 'body'), id, goCalls); + goRoutes(field(n, 'body')); + break; + } + case 'type_declaration': + for (const spec of named(n)) { + if (spec.type !== 'type_spec' && spec.type !== 'type_alias') continue; + const name = field(spec, 'name')?.text; + if (!name) continue; + const t = field(spec, 'type'); + const kind: NodeType = t?.type === 'interface_type' ? 'Interface' : t?.type === 'struct_type' ? 'Class' : 'Type'; + const tags = t?.type === 'struct_type' && /`[^`]*(gorm|db|bson):/.test(t.text); + const id = ex.symbol(n.namedChildCount === 1 ? n : spec, name, tags ? 'DatabaseModel' : kind, null, goExported(name), { goKind: t?.type }); + if (t?.type === 'struct_type') + for (const f of t.descendantsOfType('field_declaration')) { + if (!f) continue; + const ft = field(f, 'type'); + const tid = ft?.type === 'type_identifier' ? ft : ft?.descendantsOfType('type_identifier')[0]; + // An embedded field (no name) is Go's form of composition/inheritance. + if (tid) ex.ref(field(f, 'name') ? 'USES' : 'EXTENDS', id, tid.text, tid, undefined, field(f, 'name') ? { typeOnly: true } : { embedded: true }); + } + } + break; + case 'const_declaration': + case 'var_declaration': + for (const spec of n.descendantsOfType(n.type === 'const_declaration' ? 'const_spec' : 'var_spec')) { + if (!spec) continue; + const name = field(spec, 'name')?.text; + if (name && name !== '_') { + const id = ex.symbol(spec, name, n.type === 'const_declaration' ? 'Constant' : 'Variable', null, goExported(name)); + collectCalls(ex, field(spec, 'value'), id, goCalls); + } + } + break; + default: + break; + } + } +}; + +// --------------------------------------------------------------------------- +// Rust +// --------------------------------------------------------------------------- + +const rustCalls: CallSpec = { + calls: { + call_expression: (n) => { + const fn = field(n, 'function'); + if (!fn) return null; + if (fn.type === 'identifier') return { name: fn.text }; + if (fn.type === 'scoped_identifier') return { name: field(fn, 'name')?.text ?? '', receiver: field(fn, 'path')?.text }; + if (fn.type === 'field_expression') return { name: field(fn, 'field')?.text ?? '', receiver: field(fn, 'value')?.text.slice(0, 60) }; + return null; + }, + }, + news: { + struct_expression: (n) => { + const t = field(n, 'name'); + return t ? lastSegment(t.text, '::') : null; + }, + }, + stop: new Set(), +}; +const rustPub = (n: Node): boolean => named(n).some((c) => c.type === 'visibility_modifier'); + +const walkRust: Walker = (ex, root) => { + const useNames = (n: Node, prefix: string, out: { path: string; name: string; local: string }[]) => { + switch (n.type) { + case 'identifier': + case 'crate': + case 'self': + case 'super': + out.push({ path: prefix ? `${prefix}::${n.text}` : n.text, name: n.text, local: n.text }); + break; + case 'scoped_identifier': + out.push({ path: prefix ? `${prefix}::${n.text}` : n.text, name: field(n, 'name')?.text ?? '', local: field(n, 'name')?.text ?? '' }); + break; + case 'use_as_clause': { + const p = field(n, 'path'); + const alias = field(n, 'alias')?.text ?? ''; + if (p) out.push({ path: prefix ? `${prefix}::${p.text}` : p.text, name: lastSegment(p.text, '::'), local: alias }); + break; + } + case 'use_wildcard': { + const inner = named(n)[0]?.text ?? ''; + out.push({ path: [prefix, inner].filter(Boolean).join('::'), name: '*', local: '*' }); + break; + } + case 'scoped_use_list': { + const p = field(n, 'path')?.text ?? ''; + const list = field(n, 'list'); + if (list) for (const c of named(list)) useNames(c, [prefix, p].filter(Boolean).join('::'), out); + break; + } + case 'use_list': + for (const c of named(n)) useNames(c, prefix, out); + break; + default: + break; + } + }; + const attrsBefore = (n: Node): string[] => { + const out: string[] = []; + let p = n.previousNamedSibling; + while (p && (p.type === 'attribute_item' || /comment/.test(p.type))) { + if (p.type === 'attribute_item') out.push(p.text); + p = p.previousNamedSibling; + } + return out; + }; + const visitFn = (n: Node, parent: string | null, kind: NodeType) => { + const name = field(n, 'name')?.text; + if (!name) return; + const attrs = attrsBefore(n); + const id = ex.symbol(n, name, kind, parent, rustPub(n), attrs.length ? { attributes: attrs.map((a) => a.slice(0, 80)) } : {}); + for (const a of attrs) { + const m = /#\[\s*(get|post|put|delete|patch)\s*\(\s*"([^"]+)"/i.exec(a); + if (m) ex.endpoint(n, m[1]!.toUpperCase(), m[2]!, id); + } + collectCalls(ex, field(n, 'body'), id, rustCalls); + }; + const visitItems = (items: Node[], prefix: string | null) => { + for (const n of items) { + switch (n.type) { + case 'use_declaration': { + const arg = field(n, 'argument'); + if (!arg) break; + const out: { path: string; name: string; local: string }[] = []; + useNames(arg, '', out); + for (const u of out) ex.import(n, u.path, [{ imported: u.name, local: u.local }]); + break; + } + case 'mod_item': { + const name = field(n, 'name')?.text; + const body = field(n, 'body'); + if (name && !body) ex.import(n, `self::${name}`, [{ imported: '*', local: name }]); + else if (name && body) visitItems(named(body), prefix ? `${prefix}.${name}` : name); + break; + } + case 'function_item': + visitFn(n, prefix, 'Function'); + break; + case 'struct_item': + case 'enum_item': + case 'union_item': { + const name = field(n, 'name')?.text; + if (!name) break; + const attrs = attrsBefore(n).join(' '); + const model = /derive\([^)]*(Queryable|Insertable|FromRow|Model|Entity)/.test(attrs) || /#\[\s*(table_name|sea_orm|diesel)/.test(attrs); + const id = ex.symbol(n, name, model ? 'DatabaseModel' : n.type === 'struct_item' ? 'Class' : 'Type', prefix, rustPub(n), { rustKind: n.type.replace('_item', '') }); + const body = field(n, 'body'); + if (body) for (const t of body.descendantsOfType('type_identifier')) if (t) ex.ref('USES', id, t.text, t, undefined, { typeOnly: true }); + break; + } + case 'trait_item': { + const name = field(n, 'name')?.text; + if (!name) break; + const id = ex.symbol(n, name, 'Interface', prefix, rustPub(n)); + const body = field(n, 'body'); + if (body) for (const f of named(body)) if (f.type === 'function_item' || f.type === 'function_signature_item') visitFn(f, id, 'Method'); + break; + } + case 'impl_item': { + const typeNode = field(n, 'type'); + const typeName = typeNode ? lastSegment(typeNode.text.replace(/<.*$/, ''), '::') : null; + const traitNode = field(n, 'trait'); + const owner = typeName && ex.facts.symbols.some((s) => s.localId === (prefix ? `${prefix}.${typeName}` : typeName)) ? (prefix ? `${prefix}.${typeName}` : typeName) : null; + if (traitNode && typeName) { + const traitName = lastSegment(traitNode.text.replace(/<.*$/, ''), '::'); + if (owner) ex.ref('IMPLEMENTS', owner, traitName, traitNode); + } + const body = field(n, 'body'); + if (body) for (const f of named(body)) if (f.type === 'function_item') visitFn(f, owner, owner ? 'Method' : 'Function'); + break; + } + case 'const_item': + case 'static_item': { + const name = field(n, 'name')?.text; + if (name) ex.symbol(n, name, 'Constant', prefix, rustPub(n)); + break; + } + case 'type_item': { + const name = field(n, 'name')?.text; + if (name) ex.symbol(n, name, 'Type', prefix, rustPub(n)); + break; + } + default: + break; + } + } + }; + visitItems(named(root), null); +}; + +// --------------------------------------------------------------------------- +// C / C++ +// --------------------------------------------------------------------------- + +const cCalls: CallSpec = { + calls: { + call_expression: (n) => { + const fn = field(n, 'function'); + if (!fn) return null; + if (fn.type === 'identifier') return { name: fn.text }; + if (fn.type === 'field_expression') return { name: field(fn, 'field')?.text ?? '', receiver: field(fn, 'argument')?.text.slice(0, 60) }; + if (fn.type === 'qualified_identifier') return { name: lastSegment(fn.text, '::'), receiver: fn.text.split('::').slice(0, -1).join('::') }; + if (fn.type === 'template_function') return { name: field(fn, 'name')?.text ?? '' }; + return null; + }, + }, + news: { + new_expression: (n) => { + const t = field(n, 'type'); + return t ? lastSegment(t.text.replace(/<.*$/, ''), '::') : null; + }, + }, + stop: new Set(['class_specifier', 'struct_specifier']), +}; + +/** Finds the declared name inside nested declarators (pointers, references, functions). */ +function declaratorName(d: Node | null): { name: string; scope: string | null; isFunction: boolean } | null { + let cur = d; + let isFunction = false; + for (let i = 0; cur && i < 8; i++) { + if (cur.type === 'function_declarator') isFunction = true; + if (cur.type === 'identifier' || cur.type === 'field_identifier' || cur.type === 'type_identifier' || cur.type === 'destructor_name' || cur.type === 'operator_name') + return { name: cur.text, scope: null, isFunction }; + if (cur.type === 'qualified_identifier') { + const parts = cur.text.split('::'); + return { name: parts.pop() ?? cur.text, scope: parts.join('::') || null, isFunction }; + } + cur = field(cur, 'declarator') ?? named(cur).find((c) => /declarator|identifier/.test(c.type)) ?? null; + } + return null; +} + +const walkC: Walker = (ex, root) => { + const isHeader = /\.(h|hh|hpp|hxx)$/.test(ex.facts.path); + const visit = (items: Node[], parent: string | null, ns: string | null) => { + for (const n of items) { + switch (n.type) { + case 'preproc_include': { + const p = field(n, 'path'); + if (p) ex.import(n, stripQuotes(p.text), [{ imported: '*', local: '*' }], 'include'); + if (p && p.type === 'system_lib_string') ex.facts.imports[ex.facts.imports.length - 1]!.externalPackage = stripQuotes(p.text); + break; + } + case 'preproc_def': { + const name = field(n, 'name')?.text; + if (name && field(n, 'value')) ex.symbol(n, name, 'Constant', parent, true, { macro: true }); + break; + } + case 'preproc_function_def': { + const name = field(n, 'name')?.text; + if (name) ex.symbol(n, name, 'Function', parent, true, { macro: true }); + break; + } + case 'preproc_ifdef': + case 'preproc_if': + case 'preproc_else': + case 'preproc_elif': + case 'linkage_specification': + case 'declaration_list': + visit(named(n), parent, ns); + break; + case 'namespace_definition': { + const name = field(n, 'name')?.text ?? null; + const body = field(n, 'body'); + if (body) visit(named(body), parent, name ? (ns ? `${ns}::${name}` : name) : ns); + if (name) ex.facts.moduleName ??= name; + break; + } + case 'template_declaration': + visit(named(n).filter((c) => c.type !== 'template_parameter_list'), parent, ns); + break; + case 'function_definition': { + const d = declaratorName(field(n, 'declarator')); + if (!d) break; + // `Foo::bar` defined out of line belongs to class Foo when Foo is declared in this file. + const owner = d.scope ? lastSegment(d.scope, '::') : null; + const ownerId = owner && ex.facts.symbols.some((s) => s.localId === owner) ? owner : parent; + const id = ex.symbol(n, d.name, ownerId || d.scope ? 'Method' : 'Function', ownerId, !/\bstatic\b/.test(n.text.slice(0, 40)), d.scope ? { scope: d.scope } : {}); + collectCalls(ex, field(n, 'body'), id, cCalls); + break; + } + case 'class_specifier': + case 'struct_specifier': + case 'union_specifier': { + const name = field(n, 'name')?.text; + const body = field(n, 'body'); + if (!name || !body) break; + const id = ex.symbol(n, name, 'Class', parent, true, { cKind: n.type.replace('_specifier', ''), ...(ns ? { namespace: ns } : {}) }); + const bases = named(n).find((c) => c.type === 'base_class_clause'); + if (bases) + for (const b of named(bases)) + if (b.type === 'type_identifier' || b.type === 'qualified_identifier' || b.type === 'template_type') + ex.ref('EXTENDS', id, lastSegment(b.text.replace(/<.*$/, ''), '::'), b); + for (const m of named(body)) { + if (m.type === 'function_definition') { + const d = declaratorName(field(m, 'declarator')); + if (d) { + const mid = ex.symbol(m, d.name, 'Method', id, true); + collectCalls(ex, field(m, 'body'), mid, cCalls); + } + } else if (m.type === 'declaration' || m.type === 'field_declaration') { + const d = declaratorName(field(m, 'declarator')); + if (d?.isFunction) ex.symbol(m, d.name, 'Method', id, true, { declarationOnly: true }); + const t = field(m, 'type'); + if (t?.type === 'type_identifier') ex.ref('USES', id, t.text, t, undefined, { typeOnly: true }); + } else if (/_specifier$/.test(m.type)) { + visit([m], id, ns); + } + } + break; + } + case 'enum_specifier': { + const name = field(n, 'name')?.text; + if (name && field(n, 'body')) ex.symbol(n, name, 'Type', parent, true, { enum: true }); + break; + } + case 'type_definition': { + const d = declaratorName(field(n, 'declarator')); + const t = field(n, 'type'); + if (t && /_specifier$/.test(t.type) && field(t, 'body') && field(t, 'name')) visit([t], parent, ns); + else if (d) ex.symbol(n, d.name, t && /struct|union/.test(t.type) && field(t, 'body') ? 'Class' : 'Type', parent, true); + break; + } + case 'alias_declaration': { + const name = field(n, 'name')?.text; + if (name) ex.symbol(n, name, 'Type', parent, true); + break; + } + case 'declaration': { + const t = field(n, 'type'); + if (t && /_specifier$/.test(t.type) && field(t, 'body')) visit([t], parent, ns); + const d = declaratorName(field(n, 'declarator')); + if (!d) break; + if (d.isFunction) { + // Prototypes are recorded for headers only; the definition carries the body. + if (isHeader) ex.symbol(n, d.name, 'Function', parent, true, { declarationOnly: true }); + } else if (!parent) { + const id = ex.symbol(n, d.name, /\bconst\b/.test(n.text.slice(0, 60)) ? 'Constant' : 'Variable', parent, !/\bstatic\b/.test(n.text.slice(0, 40))); + collectCalls(ex, n, id, cCalls); + } + break; + } + default: + break; + } + } + }; + visit(named(root), null, null); +}; + +// --------------------------------------------------------------------------- +// C# +// --------------------------------------------------------------------------- + +const csCalls: CallSpec = { + calls: { + invocation_expression: (n) => { + const fn = field(n, 'function'); + if (!fn) return null; + if (fn.type === 'identifier') return { name: fn.text }; + if (fn.type === 'generic_name') return { name: named(fn)[0]?.text ?? '' }; + if (fn.type === 'member_access_expression') { + const nm = field(fn, 'name'); + return { name: nm?.type === 'generic_name' ? (named(nm)[0]?.text ?? '') : (nm?.text ?? ''), receiver: field(fn, 'expression')?.text.slice(0, 60) }; + } + return null; + }, + }, + news: { + object_creation_expression: (n) => { + const t = field(n, 'type'); + return t ? lastSegment(t.text.replace(/<.*$/, ''), '.') : null; + }, + }, + stop: new Set(['class_declaration', 'struct_declaration', 'interface_declaration', 'record_declaration']), +}; + +function csAttributes(n: Node): { name: string; node: Node }[] { + return named(n) + .filter((c) => c.type === 'attribute_list') + .flatMap((l) => named(l).filter((a) => a.type === 'attribute')) + .map((a) => ({ name: lastSegment(field(a, 'name')?.text ?? '', '.').replace(/Attribute$/, ''), node: a })); +} +const csPublic = (n: Node): boolean => named(n).some((c) => c.type === 'modifier' && /public|internal/.test(c.text)); + +const walkCSharp: Walker = (ex, root) => { + const visit = (items: Node[], parent: string | null) => { + for (const n of items) { + switch (n.type) { + case 'using_directive': { + const nm = named(n).find((c) => c.type === 'qualified_name' || c.type === 'identifier'); + if (nm) ex.import(n, nm.text, [{ imported: '*', local: '*' }]); + break; + } + case 'namespace_declaration': + case 'file_scoped_namespace_declaration': { + ex.facts.moduleName ??= field(n, 'name')?.text; + const body = field(n, 'body'); + visit(body ? named(body) : named(n), parent); + break; + } + case 'class_declaration': + case 'struct_declaration': + case 'interface_declaration': + case 'record_declaration': + case 'enum_declaration': { + const name = field(n, 'name')?.text; + if (!name) break; + const attrs = csAttributes(n); + const baseList = named(n).find((c) => c.type === 'base_list'); + const bases = baseList ? named(baseList).map((b) => lastSegment(b.text.replace(/<.*$/, ''), '.')) : []; + let kind: NodeType = n.type === 'interface_declaration' ? 'Interface' : n.type === 'enum_declaration' ? 'Type' : 'Class'; + if (attrs.some((a) => a.name === 'Table' || a.name === 'Entity') || bases.includes('DbContext')) kind = 'DatabaseModel'; + const id = ex.symbol(n, name, kind, parent, csPublic(n), { attributes: attrs.map((a) => a.name) }); + if (baseList) + named(baseList).forEach((b, i) => { + const bn = lastSegment(b.text.replace(/<.*$/, ''), '.'); + // By convention interface names start with `I` followed by an upper-case letter. + const isInterface = /^I[A-Z]/.test(bn); + ex.ref(n.type === 'interface_declaration' || (!isInterface && i === 0) ? 'EXTENDS' : 'IMPLEMENTS', id, bn, b); + }); + const routeAttr = attrs.find((a) => a.name === 'Route'); + const basePath = routeAttr ? (firstString(routeAttr.node) ?? '') : ''; + const body = field(n, 'body'); + if (!body) break; + for (const m of named(body)) { + if (m.type === 'method_declaration' || m.type === 'constructor_declaration') { + const mname = field(m, 'name')?.text ?? 'constructor'; + const mattrs = csAttributes(m); + const mid = ex.symbol(m, mname, 'Method', id, csPublic(m), { attributes: mattrs.map((a) => a.name) }); + for (const a of mattrs) { + const http = ASPNET_ATTRS[a.name]; + if (http) ex.endpoint(a.node, http, `${basePath}/${firstString(a.node) ?? ''}`.replace(/\/+/g, '/').replace(/(.)\/$/, '$1'), mid); + } + collectCalls(ex, field(m, 'body') ?? m, mid, csCalls); + } else if (m.type === 'property_declaration' || m.type === 'field_declaration') { + const t = field(m, 'type') ?? m.descendantsOfType('variable_declaration')[0]?.childForFieldName('type') ?? null; + if (t && (t.type === 'identifier' || t.type === 'generic_name')) + for (const idn of t.type === 'identifier' ? [t] : t.descendantsOfType('identifier')) if (idn) ex.ref('USES', id, idn.text, idn, undefined, { typeOnly: true }); + collectCalls(ex, m, id, csCalls); + } else if (/_declaration$/.test(m.type)) { + visit([m], id); + } + } + break; + } + default: + break; + } + } + }; + visit(named(root), null); +}; + +const WALKERS: Record = { java: walkJava, go: walkGo, rust: walkRust, c: walkC, cpp: walkC, csharp: walkCSharp }; + +export function createTreeSitterAdapter(): LanguageAdapter { + return { + id: 'tree-sitter', + technique: 'Tree-sitter syntax trees', + scope: 'file', + languages: [ + { id: 'java', name: 'Java', tier: 2, extensions: ['.java'] }, + { id: 'go', name: 'Go', tier: 2, extensions: ['.go'] }, + { id: 'rust', name: 'Rust', tier: 2, extensions: ['.rs'] }, + { id: 'c', name: 'C', tier: 2, extensions: ['.c', '.h'] }, + { id: 'cpp', name: 'C++', tier: 2, extensions: ['.cpp', '.cc', '.cxx', '.hpp', '.hh', '.hxx'] }, + { id: 'csharp', name: 'C#', tier: 2, extensions: ['.cs'] }, + ], + async analyze(files: SourceFileInput[], ctx: AnalyzeContext): Promise { + const out: FileFacts[] = []; + const parsers = new Map(); + let done = 0; + for (const file of files) { + let facts = emptyFacts(file, 'tree-sitter'); + try { + const walker = WALKERS[file.language]; + if (!walker) throw new Error(`Unsupported language ${file.language}`); + let parser = parsers.get(file.language); + if (!parser) { + const language = await loadLanguage(file.language); + parser = new Parser(); + parser.setLanguage(language); + parsers.set(file.language, parser); + } + const source = fs.readFileSync(file.absPath, 'utf8'); + const tree = parser.parse(source); + if (!tree) throw new Error('Parser returned no tree'); + try { + const ex = new FileExtractor(file, source); + walker(ex, tree.rootNode); + facts = ex.facts; + if (tree.rootNode.hasError) { + const err = tree.rootNode.descendantsOfType('ERROR')[0]; + facts.errors.push({ + path: file.path, + message: 'Syntax errors found; extraction may be incomplete', + line: err ? err.startPosition.row + 1 : undefined, + severity: 'warning', + }); + } + } finally { + tree.delete(); + } + } catch (err) { + facts.errors.push({ path: file.path, message: `Analysis failed: ${(err as Error).message}`, severity: 'error' }); + } + out.push(facts); + done++; + if (done % 50 === 0 || done === files.length) ctx.onProgress?.(done, files.length); + } + for (const p of parsers.values()) p.delete(); + return out; + }, + }; +} diff --git a/packages/language-adapters/src/types.ts b/packages/language-adapters/src/types.ts new file mode 100644 index 0000000..de80e15 --- /dev/null +++ b/packages/language-adapters/src/types.ts @@ -0,0 +1,143 @@ +import type { EdgeType, ExtractionMethod, NodeType, SourceLocation } from '@vectora/graph-schema'; + +/** A source file handed to an adapter. Paths are repository-relative, POSIX style. */ +export interface SourceFileInput { + path: string; + absPath: string; + language: string; +} + +export interface SymbolFact { + /** Qualified name, unique within its file (e.g. `UserService.login`). */ + localId: string; + name: string; + kind: NodeType; + parent: string | null; + location: SourceLocation; + exported: boolean; + description?: string; + metadata?: Record; +} + +export interface ImportFact { + specifier: string; + /** `imported` is `*` for namespace/module imports and `default` for default imports. */ + names: { imported: string; local: string }[]; + kind: 'static' | 'dynamic' | 'require' | 'include' | 'reexport'; + location: SourceLocation; + evidence: string; + /** Repository-relative path when the adapter resolved the import itself. */ + resolvedPath?: string | null; + /** External package name when the specifier does not point into the repository. */ + externalPackage?: string | null; + builtin?: boolean; +} + +export type ReferenceTarget = + /** The adapter resolved the reference to a definition. */ + | { resolved: { path: string; localId: string | null } } + /** Only a name is known; the indexer resolves it through imports and scope. */ + | { name: string; receiver?: string }; + +export interface ReferenceFact { + kind: EdgeType; + /** Enclosing symbol (localId) or null for module-level code. */ + from: string | null; + target: ReferenceTarget; + location: SourceLocation; + evidence: string; + method: ExtractionMethod; + confidence: number; + verified: boolean; + metadata?: Record; +} + +export interface ParseIssue { + path: string; + message: string; + line?: number; + severity: 'error' | 'warning'; +} + +/** Everything an adapter learned about one file. Cached per content hash. */ +export interface FileFacts { + path: string; + language: string; + adapter: string; + lineCount: number; + /** Package / namespace / module the file declares, when the language has one. */ + moduleName?: string; + symbols: SymbolFact[]; + imports: ImportFact[]; + references: ReferenceFact[]; + errors: ParseIssue[]; +} + +export interface WorkspacePackage { + name: string; + /** Repository-relative directory of the package. */ + dir: string; + /** Repository-relative entry file, when it could be determined. */ + entry: string | null; +} + +export interface AnalyzeContext { + rootDir: string; + /** All repository-relative file paths that are part of the index. */ + allFiles: ReadonlySet; + /** Paths that must be (re)analysed. Other files only provide declarations. */ + analyzeOnly?: ReadonlySet; + workspacePackages: WorkspacePackage[]; + pythonCommand?: string; + onProgress?: (processed: number, total: number) => void; +} + +export interface LanguageMeta { + id: string; + name: string; + tier: 1 | 2; + extensions: string[]; +} + +/** + * Common contract for every language adapter: parse files, extract symbols and + * relationships with source locations, and report parsing errors. + */ +export interface LanguageAdapter { + id: string; + /** Human-readable description of the analysis technique. */ + technique: string; + languages: LanguageMeta[]; + /** + * `project` adapters need every file of their languages at once (cross-file + * type resolution); `file` adapters can analyse files independently. + */ + scope: 'project' | 'file'; + analyze(files: SourceFileInput[], ctx: AnalyzeContext): Promise; +} + +export const emptyFacts = (file: SourceFileInput, adapter: string, lineCount = 0): FileFacts => ({ + path: file.path, + language: file.language, + adapter, + lineCount, + symbols: [], + imports: [], + references: [], + errors: [], +}); + +export const evidenceLine = (text: string): string => { + const line = text.split(/\r?\n/, 1)[0] ?? ''; + const t = line.trim(); + return t.length > 200 ? `${t.slice(0, 197)}...` : t; +}; + +/** Makes `base` unique within `used` by appending `~2`, `~3`, ... */ +export function uniqueLocalId(used: Set, base: string): string { + let id = base; + let i = 2; + while (used.has(id)) id = `${base}~${i++}`; + used.add(id); + return id; +} diff --git a/packages/language-adapters/src/typescript-adapter.ts b/packages/language-adapters/src/typescript-adapter.ts new file mode 100644 index 0000000..83a90df --- /dev/null +++ b/packages/language-adapters/src/typescript-adapter.ts @@ -0,0 +1,865 @@ +/** + * TypeScript / JavaScript adapter. + * + * Builds one `ts.Program` for all TypeScript and JavaScript files in the + * repository and uses the type checker to resolve references to their + * declarations. A relationship is only emitted as resolved when the checker + * ties the identifier to a declaration inside the repository. + */ +import fs from 'node:fs'; +import path from 'node:path'; +import ts from 'typescript'; +import type { EdgeType, NodeType, SourceLocation } from '@vectora/graph-schema'; +import { normalizePath } from '@vectora/graph-schema'; +import { + type AnalyzeContext, + type FileFacts, + type ImportFact, + type LanguageAdapter, + type ReferenceFact, + type SourceFileInput, + type SymbolFact, + emptyFacts, + evidenceLine, + uniqueLocalId, +} from './types'; + +const CODE_EXTS = ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs']; +const RESOLVE_EXTS = ['.ts', '.tsx', '.d.ts', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs']; +const HTTP_METHODS = new Set(['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'all']); +const ROUTE_RECEIVER = /(^|[a-z_])(app|router|server|fastify|api|routes?|instance)$/i; +const NEST_HTTP = new Set(['Get', 'Post', 'Put', 'Patch', 'Delete', 'Head', 'Options', 'All']); +const MODEL_BASES = new Set(['Model', 'BaseEntity', 'Document', 'Entity']); +const MODEL_DECORATORS = new Set(['Entity', 'Table', 'Schema', 'ObjectType']); +const TABLE_FACTORIES = new Set(['sqliteTable', 'pgTable', 'mysqlTable', 'defineTable', 'model', 'define']); +const DB_READ = /^(find|get|select|query|count|all|where|aggregate|first|exists|list|fetch|load|search|paginate)/i; +const DB_WRITE = /^(create|insert|update|delete|save|remove|upsert|destroy|bulk|truncate|increment|decrement|set|add|put|drop)/i; +const KNOWN_GLOBALS = new Set([ + 'require', 'describe', 'it', 'test', 'expect', 'beforeEach', 'afterEach', 'beforeAll', 'afterAll', 'jest', 'vi', + 'process', 'Buffer', 'setImmediate', 'clearImmediate', 'define', '$', 'jQuery', 'suite', 'before', 'after', 'gc', +]); +const NODE_BUILTINS = new Set([ + 'assert', 'buffer', 'child_process', 'cluster', 'console', 'constants', 'crypto', 'dgram', 'dns', 'domain', 'events', + 'fs', 'http', 'http2', 'https', 'module', 'net', 'os', 'path', 'perf_hooks', 'process', 'punycode', 'querystring', + 'readline', 'repl', 'stream', 'string_decoder', 'sys', 'timers', 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'worker_threads', 'zlib', +]); + +interface SymRef { + path: string; + localId: string; + kind: NodeType; +} + +interface TsconfigScope { + dir: string; // repository-relative, '' for root + baseUrl: string; // repository-relative + paths: Record; +} + +const isWin = process.platform === 'win32'; +const canon = (p: string): string => { + const n = p.replace(/\\/g, '/'); + return isWin ? n.toLowerCase() : n; +}; + +function scriptKindFor(file: string): ts.ScriptKind { + const ext = path.extname(file).toLowerCase(); + if (ext === '.tsx') return ts.ScriptKind.TSX; + if (ext === '.jsx') return ts.ScriptKind.JSX; + if (ext === '.js' || ext === '.mjs' || ext === '.cjs') return ts.ScriptKind.JS; + return ts.ScriptKind.TS; +} + +function extensionFor(file: string): ts.Extension { + const lower = file.toLowerCase(); + if (lower.endsWith('.d.ts')) return ts.Extension.Dts; + const ext = path.extname(lower); + switch (ext) { + case '.tsx': + return ts.Extension.Tsx; + case '.jsx': + return ts.Extension.Jsx; + case '.js': + return ts.Extension.Js; + case '.mjs': + return ts.Extension.Mjs; + case '.cjs': + return ts.Extension.Cjs; + case '.mts': + return ts.Extension.Mts; + case '.cts': + return ts.Extension.Cts; + default: + return ts.Extension.Ts; + } +} + +const hasModifier = (node: ts.Node, kind: ts.SyntaxKind): boolean => + ts.canHaveModifiers(node) ? (ts.getModifiers(node)?.some((m) => m.kind === kind) ?? false) : false; + +function decoratorNames(node: ts.Node): string[] { + if (!ts.canHaveDecorators(node)) return []; + return (ts.getDecorators(node) ?? []).map((d) => { + const e = ts.isCallExpression(d.expression) ? d.expression.expression : d.expression; + return ts.isIdentifier(e) ? e.text : ts.isPropertyAccessExpression(e) ? e.name.text : e.getText(); + }); +} + +function decoratorCall(node: ts.Node, names: Set): { name: string; arg: string | null } | null { + if (!ts.canHaveDecorators(node)) return null; + for (const d of ts.getDecorators(node) ?? []) { + const call = ts.isCallExpression(d.expression) ? d.expression : null; + const e = call ? call.expression : d.expression; + const name = ts.isIdentifier(e) ? e.text : null; + if (name && names.has(name)) { + const a = call?.arguments[0]; + return { name, arg: a && ts.isStringLiteralLike(a) ? a.text : null }; + } + } + return null; +} + +function containsJsx(node: ts.Node | undefined): boolean { + if (!node) return false; + let found = false; + const walk = (n: ts.Node) => { + if (found) return; + if (ts.isJsxElement(n) || ts.isJsxSelfClosingElement(n) || ts.isJsxFragment(n)) { + found = true; + return; + } + ts.forEachChild(n, walk); + }; + walk(node); + return found; +} + +const isFunctionLike = (n: ts.Node | undefined): n is ts.ArrowFunction | ts.FunctionExpression => + !!n && (ts.isArrowFunction(n) || ts.isFunctionExpression(n)); + +/** Unwraps `memo(fn)`, `forwardRef(fn)` and similar wrappers to the inner function. */ +function wrappedFunction(init: ts.Expression | undefined): ts.ArrowFunction | ts.FunctionExpression | null { + if (!init) return null; + if (isFunctionLike(init)) return init; + if (ts.isCallExpression(init)) { + for (const a of init.arguments) { + const inner = wrappedFunction(a); + if (inner) return inner; + } + } + return null; +} + +function jsDocOf(node: ts.Node): string | undefined { + const host = ts.isVariableDeclaration(node) ? node.parent?.parent : node; + const docs = (host as { jsDoc?: ts.JSDoc[] } | undefined)?.jsDoc; + const text = docs?.length ? ts.getTextOfJSDocComment(docs[docs.length - 1]!.comment) : undefined; + if (!text) return undefined; + const first = text.trim().split(/\n\s*\n/)[0]!.replace(/\s+/g, ' '); + return first.length > 300 ? `${first.slice(0, 297)}...` : first; +} + +function routeCallInfo(call: ts.CallExpression): { method: string; routePath: string } | null { + const callee = call.expression; + if (!ts.isPropertyAccessExpression(callee)) return null; + const method = callee.name.text; + if (!HTTP_METHODS.has(method) || call.arguments.length < 2) return null; + const first = call.arguments[0]!; + if (!ts.isStringLiteralLike(first) || !first.text.startsWith('/')) return null; + const recv = callee.expression; + const recvName = ts.isIdentifier(recv) ? recv.text : ts.isPropertyAccessExpression(recv) ? recv.name.text : null; + if (!recvName || !ROUTE_RECEIVER.test(recvName)) return null; + return { method: method.toUpperCase(), routePath: first.text }; +} + +function packageNameOf(specifier: string): string { + const parts = specifier.split('/'); + return specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0]!; +} + +class Resolver { + private scopes: TsconfigScope[] = []; + private cache = new Map(); + + constructor( + private ctx: AnalyzeContext, + private codeFiles: Set, + ) { + for (const f of ctx.allFiles) { + const base = f.slice(f.lastIndexOf('/') + 1); + if (base !== 'tsconfig.json' && base !== 'jsconfig.json') continue; + try { + const abs = path.join(ctx.rootDir, f); + const parsed = ts.parseConfigFileTextToJson(abs, fs.readFileSync(abs, 'utf8')); + const co = parsed.config?.compilerOptions; + if (!co?.paths && !co?.baseUrl) continue; + const dir = f.includes('/') ? f.slice(0, f.lastIndexOf('/')) : ''; + const baseUrl = normalizePath(path.posix.join(dir, co.baseUrl ?? '.')); + this.scopes.push({ dir, baseUrl: baseUrl === '.' ? '' : baseUrl, paths: co.paths ?? {} }); + } catch { + // Unreadable config: aliases from it simply stay unresolved. + } + } + this.scopes.sort((a, b) => b.dir.length - a.dir.length); + } + + /** Finds an indexed file for a path without extension. */ + tryFile(base: string, codeOnly = true): string | null { + const b = normalizePath(path.posix.normalize(base)); + if (b.startsWith('..')) return null; + const has = (p: string) => (codeOnly ? this.codeFiles.has(p) : this.ctx.allFiles.has(p)); + if (has(b) && (!codeOnly || CODE_EXTS.some((e) => b.endsWith(e)))) return b; + // `./x.js` written in TypeScript sources refers to `./x.ts`. + const m = /\.(js|jsx|mjs|cjs)$/.exec(b); + if (m) { + const stem = b.slice(0, -m[0].length); + for (const e of ['.ts', '.tsx', '.mts', '.cts']) if (this.codeFiles.has(stem + e)) return stem + e; + } + for (const e of RESOLVE_EXTS) if (this.codeFiles.has(b + e)) return b + e; + for (const e of RESOLVE_EXTS) if (this.codeFiles.has(`${b}/index${e}`)) return `${b}/index${e}`; + return null; + } + + resolve(specifier: string, fromFile: string): { path: string | null; asset: string | null; external: string | null; builtin: boolean } { + const key = `${fromFile}\0${specifier}`; + const dir = fromFile.includes('/') ? fromFile.slice(0, fromFile.lastIndexOf('/')) : ''; + const none = { path: null, asset: null, external: null, builtin: false }; + if (specifier.startsWith('.')) { + const target = path.posix.join(dir, specifier); + const hit = this.cache.get(key) ?? this.tryFile(target); + this.cache.set(key, hit); + if (hit) return { ...none, path: hit }; + const asset = this.ctx.allFiles.has(normalizePath(target)) ? normalizePath(target) : null; + return { ...none, asset }; + } + if (specifier.startsWith('node:') || NODE_BUILTINS.has(packageNameOf(specifier))) + return { ...none, external: `node:${specifier.replace(/^node:/, '').split('/')[0]}`, builtin: true }; + if (this.cache.has(key)) { + const c = this.cache.get(key)!; + return c ? { ...none, path: c } : { ...none, external: packageNameOf(specifier) }; + } + let hit: string | null = null; + // tsconfig path aliases, nearest config first + for (const scope of this.scopes) { + if (scope.dir && !(fromFile === scope.dir || fromFile.startsWith(`${scope.dir}/`))) continue; + for (const [pattern, targets] of Object.entries(scope.paths)) { + const star = pattern.indexOf('*'); + let capture: string | null = null; + if (star === -1) { + if (pattern === specifier) capture = ''; + } else if (specifier.startsWith(pattern.slice(0, star)) && specifier.endsWith(pattern.slice(star + 1))) { + capture = specifier.slice(star, specifier.length - (pattern.length - star - 1)); + } + if (capture === null) continue; + for (const t of targets) { + hit = this.tryFile(path.posix.join(scope.baseUrl, t.replace('*', capture))); + if (hit) break; + } + if (hit) break; + } + if (hit) break; + // bare baseUrl-relative import + hit = this.tryFile(path.posix.join(scope.baseUrl, specifier)); + if (hit) break; + } + // workspace packages + if (!hit) { + const pkgName = packageNameOf(specifier); + const pkg = this.ctx.workspacePackages.find((p) => p.name === pkgName); + if (pkg) { + const sub = specifier.slice(pkgName.length).replace(/^\//, ''); + hit = sub + ? (this.tryFile(path.posix.join(pkg.dir, sub)) ?? this.tryFile(path.posix.join(pkg.dir, 'src', sub))) + : ((pkg.entry && this.codeFiles.has(pkg.entry) ? pkg.entry : null) ?? + this.tryFile(path.posix.join(pkg.dir, 'src/index')) ?? + this.tryFile(path.posix.join(pkg.dir, 'index'))); + } + } + this.cache.set(key, hit); + return hit ? { ...none, path: hit } : { ...none, external: packageNameOf(specifier) }; + } +} + +export function createTypeScriptAdapter(): LanguageAdapter { + return { + id: 'typescript', + technique: 'TypeScript Compiler API with type-checker symbol resolution', + scope: 'project', + languages: [ + { id: 'typescript', name: 'TypeScript', tier: 1, extensions: ['.ts', '.tsx', '.mts', '.cts'] }, + { id: 'javascript', name: 'JavaScript', tier: 1, extensions: ['.js', '.jsx', '.mjs', '.cjs'] }, + ], + async analyze(files, ctx) { + return analyzeProject(files, ctx); + }, + }; +} + +function analyzeProject(files: SourceFileInput[], ctx: AnalyzeContext): FileFacts[] { + if (files.length === 0) return []; + const rootAbs = canon(path.resolve(ctx.rootDir)); + const relByAbs = new Map(); + const inputByRel = new Map(); + for (const f of files) { + relByAbs.set(canon(path.resolve(f.absPath)), f.path); + inputByRel.set(f.path, f); + } + const codeFiles = new Set(files.map((f) => f.path)); + const resolver = new Resolver(ctx, codeFiles); + const absOf = (rel: string) => path.resolve(ctx.rootDir, rel).replace(/\\/g, '/'); + const relOf = (abs: string): string | null => relByAbs.get(canon(abs)) ?? null; + + const options: ts.CompilerOptions = { + allowJs: true, + checkJs: false, + jsx: ts.JsxEmit.Preserve, + target: ts.ScriptTarget.ESNext, + module: ts.ModuleKind.ESNext, + moduleResolution: ts.ModuleResolutionKind.Bundler, + noEmit: true, + skipLibCheck: true, + skipDefaultLibCheck: true, + allowImportingTsExtensions: true, + esModuleInterop: true, + allowSyntheticDefaultImports: true, + experimentalDecorators: true, + types: [], + strict: false, + maxNodeModuleJsDepth: 0, + }; + const host = ts.createCompilerHost(options, true); + const defaultGetSourceFile = host.getSourceFile.bind(host); + host.getSourceFile = (fileName, languageVersion, onError, shouldCreate) => { + const rel = relOf(fileName); + if (rel) { + try { + const text = fs.readFileSync(inputByRel.get(rel)!.absPath, 'utf8'); + return ts.createSourceFile(fileName, text, languageVersion, true, scriptKindFor(fileName)); + } catch { + return undefined; + } + } + // Only the compiler's own library files may be read from outside the repository. + if (!canon(fileName).startsWith(`${rootAbs}/`)) return defaultGetSourceFile(fileName, languageVersion, onError, shouldCreate); + return undefined; + }; + host.resolveModuleNameLiterals = (literals, containingFile) => { + const from = relOf(containingFile); + return literals.map((lit) => { + if (!from) return { resolvedModule: undefined }; + const r = resolver.resolve(lit.text, from); + if (!r.path) return { resolvedModule: undefined }; + const abs = absOf(r.path); + return { resolvedModule: { resolvedFileName: abs, extension: extensionFor(abs), isExternalLibraryImport: false } }; + }); + }; + host.resolveTypeReferenceDirectiveReferences = (refs) => refs.map(() => ({ resolvedTypeReferenceDirective: undefined })); + + const program = ts.createProgram({ rootNames: files.map((f) => absOf(f.path)), options, host }); + const checker = program.getTypeChecker(); + + // ---- Pass 1: declarations of every file -------------------------------- + const declMap = new Map(); + const endpointCalls = new Map(); + const perFile = new Map(); + + for (const f of files) { + const sf = program.getSourceFile(absOf(f.path)); + if (!sf) { + const facts = emptyFacts(f, 'typescript'); + facts.errors.push({ path: f.path, message: 'File could not be read', severity: 'error' }); + perFile.set(f.path, { sf: undefined as unknown as ts.SourceFile, facts, extraRefs: [] }); + continue; + } + const facts = emptyFacts(f, 'typescript', sf.getLineStarts().length); + const extraRefs: ReferenceFact[] = []; + collectSymbols(sf, f.path, facts, declMap, endpointCalls, extraRefs); + perFile.set(f.path, { sf, facts, extraRefs }); + } + + // ---- Pass 2: references of the files that need analysis ---------------- + const targets = files.filter((f) => !ctx.analyzeOnly || ctx.analyzeOnly.has(f.path)); + let done = 0; + for (const f of targets) { + const entry = perFile.get(f.path)!; + if (entry.sf) { + try { + collectReferences(entry.sf, f.path, entry.facts, checker, declMap, endpointCalls, resolver); + entry.facts.references.push(...entry.extraRefs); + const diags = (program.getSyntacticDiagnostics(entry.sf) ?? []).slice(0, 5); + for (const d of diags) { + const line = d.start !== undefined ? entry.sf.getLineAndCharacterOfPosition(d.start).line + 1 : undefined; + entry.facts.errors.push({ + path: f.path, + line, + message: ts.flattenDiagnosticMessageText(d.messageText, ' '), + severity: 'warning', + }); + } + } catch (err) { + entry.facts.errors.push({ path: f.path, message: `Analysis failed: ${(err as Error).message}`, severity: 'error' }); + } + } + done++; + if (done % 25 === 0 || done === targets.length) ctx.onProgress?.(done, targets.length); + } + return targets.map((f) => perFile.get(f.path)!.facts); +} + +// --------------------------------------------------------------------------- +// Pass 1 — symbols +// --------------------------------------------------------------------------- + +function collectSymbols( + sf: ts.SourceFile, + rel: string, + facts: FileFacts, + declMap: Map, + endpointCalls: Map, + extraRefs: ReferenceFact[], +): void { + const used = new Set(); + const isJsxFile = /\.(tsx|jsx|js)$/.test(rel); + const exportedNames = new Set(); + let defaultExportName: string | null = null; + + for (const st of sf.statements) { + if (ts.isExportDeclaration(st) && !st.moduleSpecifier && st.exportClause && ts.isNamedExports(st.exportClause)) { + for (const el of st.exportClause.elements) exportedNames.add((el.propertyName ?? el.name).text); + } else if (ts.isExportAssignment(st) && ts.isIdentifier(st.expression)) { + defaultExportName = st.expression.text; + } + } + + const loc = (node: ts.Node): SourceLocation => { + const s = sf.getLineAndCharacterOfPosition(node.getStart(sf)); + const e = sf.getLineAndCharacterOfPosition(node.getEnd()); + return { path: rel, startLine: s.line + 1, endLine: e.line + 1, startColumn: s.character, endColumn: e.character }; + }; + const signature = (node: ts.Node, body: ts.Node | undefined): string => { + const end = body ? body.getStart(sf) : node.getEnd(); + const text = sf.text.slice(node.getStart(sf), end).replace(/\s+/g, ' ').trim().replace(/\s*=>?\s*$/, ''); + return text.length > 200 ? `${text.slice(0, 197)}...` : text; + }; + const add = ( + node: ts.Node, + name: string, + kind: NodeType, + parent: string | null, + exported: boolean, + metadata: Record = {}, + mapNode: ts.Node = node, + ): string => { + const localId = uniqueLocalId(used, parent ? `${parent}.${name}` : name); + const decorators = decoratorNames(node); + if (decorators.length) metadata.decorators = decorators; + const sym: SymbolFact = { localId, name, kind, parent, location: loc(node), exported, metadata }; + const doc = jsDocOf(mapNode); + if (doc) sym.description = doc; + facts.symbols.push(sym); + declMap.set(mapNode, { path: rel, localId, kind }); + return localId; + }; + const isExported = (node: ts.Node, name: string): boolean => + hasModifier(node, ts.SyntaxKind.ExportKeyword) || exportedNames.has(name) || defaultExportName === name; + + const classKind = (node: ts.ClassLikeDeclaration): NodeType => { + const decs = decoratorNames(node); + if (decs.some((d) => MODEL_DECORATORS.has(d))) return 'DatabaseModel'; + for (const h of node.heritageClauses ?? []) { + if (h.token !== ts.SyntaxKind.ExtendsKeyword) continue; + for (const t of h.types) { + const e = t.expression; + const base = ts.isIdentifier(e) ? e.text : ts.isPropertyAccessExpression(e) ? e.name.text : ''; + if (MODEL_BASES.has(base)) return 'DatabaseModel'; + if (base === 'Component' || base === 'PureComponent') return 'Component'; + } + } + return 'Class'; + }; + + const addEndpoint = (node: ts.Node, method: string, routePath: string, extra: Record = {}): string => { + const localId = uniqueLocalId(used, `route:${method} ${routePath}`); + facts.symbols.push({ + localId, + name: `${method} ${routePath}`, + kind: 'ApiEndpoint', + parent: null, + location: loc(node), + exported: false, + metadata: { httpMethod: method, routePath, ...extra }, + }); + return localId; + }; + + const visitClass = (node: ts.ClassLikeDeclaration, name: string, parent: string | null, exported: boolean, mapNode: ts.Node = node) => { + const kind = classKind(node); + const id = add(node, name, kind, parent, exported, { abstract: hasModifier(node, ts.SyntaxKind.AbstractKeyword) || undefined }, mapNode); + if (mapNode !== node) declMap.set(node, { path: rel, localId: id, kind }); + const controller = decoratorCall(node, new Set(['Controller'])); + for (const m of node.members) { + let mid: string | null = null; + if (ts.isMethodDeclaration(m) && m.name && (ts.isIdentifier(m.name) || ts.isStringLiteral(m.name) || ts.isPrivateIdentifier(m.name))) { + mid = add(m, m.name.text, 'Method', id, false, { + signature: signature(m, m.body), + async: hasModifier(m, ts.SyntaxKind.AsyncKeyword) || undefined, + static: hasModifier(m, ts.SyntaxKind.StaticKeyword) || undefined, + visibility: hasModifier(m, ts.SyntaxKind.PrivateKeyword) ? 'private' : hasModifier(m, ts.SyntaxKind.ProtectedKeyword) ? 'protected' : 'public', + }); + const http = decoratorCall(m, NEST_HTTP); + if (http) { + const base = controller?.arg ?? ''; + const full = `/${[base, http.arg ?? ''].join('/')}`.replace(/\/+/g, '/').replace(/(.)\/$/, '$1'); + const ep = addEndpoint(m, http.name.toUpperCase(), full, { framework: 'decorator' }); + extraRefs.push({ + kind: 'ROUTES_TO', + from: ep, + target: { resolved: { path: rel, localId: mid } }, + location: loc(m), + evidence: evidenceLine(sf.text.slice(m.getStart(sf))), + method: 'pattern', + confidence: 0.95, + verified: true, + }); + } + } else if (ts.isConstructorDeclaration(m)) { + mid = add(m, 'constructor', 'Method', id, false, { signature: signature(m, m.body) }); + } else if ((ts.isGetAccessorDeclaration(m) || ts.isSetAccessorDeclaration(m)) && ts.isIdentifier(m.name)) { + mid = add(m, m.name.text, 'Method', id, false, { accessor: ts.isGetAccessorDeclaration(m) ? 'get' : 'set' }); + } else if (ts.isPropertyDeclaration(m) && ts.isIdentifier(m.name) && isFunctionLike(m.initializer)) { + mid = add(m, m.name.text, 'Method', id, false, { signature: signature(m, m.initializer.body) }); + } + void mid; + } + }; + + const visitStatement = (st: ts.Node, parent: string | null) => { + if (ts.isFunctionDeclaration(st)) { + const name = st.name?.text ?? 'default'; + const kind: NodeType = isJsxFile && /^[A-Z]/.test(name) && containsJsx(st.body) ? 'Component' : 'Function'; + const id = add(st, name, kind, parent, isExported(st, name), { + signature: signature(st, st.body), + async: hasModifier(st, ts.SyntaxKind.AsyncKeyword) || undefined, + generator: st.asteriskToken ? true : undefined, + }); + // Next.js route handlers: app/**/route.ts exporting GET, POST, ... + const m = /(?:^|\/)app\/(.*\/)?route\.(ts|js|tsx|jsx)$/.exec(rel); + if (m && /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)$/.test(name) && hasModifier(st, ts.SyntaxKind.ExportKeyword)) { + const routePath = `/${(m[1] ?? '').replace(/\/$/, '').replace(/\([^)]*\)\/?/g, '')}`.replace(/\/$/, '') || '/'; + const ep = addEndpoint(st, name, routePath, { framework: 'file-route' }); + extraRefs.push({ + kind: 'ROUTES_TO', + from: ep, + target: { resolved: { path: rel, localId: id } }, + location: loc(st), + evidence: `${rel} exports ${name}`, + method: 'pattern', + confidence: 0.9, + verified: true, + }); + } + } else if (ts.isClassDeclaration(st)) { + const name = st.name?.text ?? 'default'; + visitClass(st, name, parent, isExported(st, name)); + } else if (ts.isInterfaceDeclaration(st)) { + add(st, st.name.text, 'Interface', parent, isExported(st, st.name.text), { members: st.members.length }); + } else if (ts.isTypeAliasDeclaration(st)) { + add(st, st.name.text, 'Type', parent, isExported(st, st.name.text)); + } else if (ts.isEnumDeclaration(st)) { + add(st, st.name.text, 'Type', parent, isExported(st, st.name.text), { enum: true, members: st.members.length }); + } else if (ts.isModuleDeclaration(st) && ts.isIdentifier(st.name) && st.body && ts.isModuleBlock(st.body)) { + const prefix = parent ? `${parent}.${st.name.text}` : st.name.text; + for (const inner of st.body.statements) visitStatement(inner, prefix); + } else if (ts.isVariableStatement(st)) { + const isConst = (st.declarationList.flags & ts.NodeFlags.Const) !== 0; + for (const d of st.declarationList.declarations) { + if (!ts.isIdentifier(d.name)) continue; + const name = d.name.text; + const exported = hasModifier(st, ts.SyntaxKind.ExportKeyword) || exportedNames.has(name) || defaultExportName === name; + const init = d.initializer; + const fn = wrappedFunction(init); + if (init && ts.isClassExpression(init)) { + visitClass(init, name, parent, exported, d); + } else if (fn) { + const kind: NodeType = isJsxFile && /^[A-Z]/.test(name) && containsJsx(fn.body) ? 'Component' : 'Function'; + add(d, name, kind, parent, exported, { + signature: signature(d, fn.body), + async: hasModifier(fn, ts.SyntaxKind.AsyncKeyword) || undefined, + wrapped: fn !== init || undefined, + }); + } else { + let kind: NodeType = isConst ? 'Constant' : 'Variable'; + const meta: Record = {}; + if (init && ts.isCallExpression(init)) { + const c = init.expression; + const callee = ts.isIdentifier(c) ? c.text : ts.isPropertyAccessExpression(c) ? c.name.text : ''; + const recv = ts.isPropertyAccessExpression(c) && ts.isIdentifier(c.expression) ? c.expression.text : ''; + const tableLike = + (TABLE_FACTORIES.has(callee) && callee !== 'model' && callee !== 'define') || + (callee === 'model' && /mongoose|models?/i.test(recv)) || + (callee === 'define' && /sequelize|db/i.test(recv)); + if (tableLike) { + kind = 'DatabaseModel'; + const a0 = init.arguments[0]; + if (a0 && ts.isStringLiteralLike(a0)) meta.table = a0.text; + meta.factory = callee; + } + } + add(d, name, kind, parent, exported, meta); + } + } + } else if (ts.isExportAssignment(st)) { + const e = st.expression; + if (isFunctionLike(e)) add(st, 'default', isJsxFile && containsJsx(e.body) ? 'Component' : 'Function', parent, true, { signature: signature(st, e.body) }); + else if (ts.isClassExpression(e)) visitClass(e, e.name?.text ?? 'default', parent, true, st); + } + }; + for (const st of sf.statements) visitStatement(st, null); + + // Route registrations can appear anywhere (module level or inside setup functions). + const findRoutes = (n: ts.Node) => { + if (ts.isCallExpression(n)) { + const info = routeCallInfo(n); + if (info) endpointCalls.set(n, addEndpoint(n, info.method, info.routePath, { framework: 'router-call' })); + } + ts.forEachChild(n, findRoutes); + }; + findRoutes(sf); +} + +// --------------------------------------------------------------------------- +// Pass 2 — imports and references +// --------------------------------------------------------------------------- + +function collectReferences( + sf: ts.SourceFile, + rel: string, + facts: FileFacts, + checker: ts.TypeChecker, + declMap: Map, + endpointCalls: Map, + resolver: Resolver, +): void { + const seen = new Set(); + const loc = (node: ts.Node): SourceLocation => { + const s = sf.getLineAndCharacterOfPosition(node.getStart(sf)); + const e = sf.getLineAndCharacterOfPosition(node.getEnd()); + return { path: rel, startLine: s.line + 1, endLine: e.line + 1, startColumn: s.character }; + }; + const lineText = (node: ts.Node): string => { + const pos = node.getStart(sf); + const starts = sf.getLineStarts(); + const line = sf.getLineAndCharacterOfPosition(pos).line; + return evidenceLine(sf.text.slice(starts[line], starts[line + 1] ?? sf.text.length)); + }; + + const addImport = (specNode: ts.Node, specifier: string, names: ImportFact['names'], kind: ImportFact['kind'], stmt: ts.Node) => { + const r = resolver.resolve(specifier, rel); + const fact: ImportFact = { specifier, names, kind, location: loc(stmt), evidence: lineText(stmt) }; + if (r.path) fact.resolvedPath = r.path; + else if (r.asset) fact.resolvedPath = r.asset; + else if (r.external) { + fact.externalPackage = r.external; + fact.builtin = r.builtin; + } else fact.resolvedPath = null; + facts.imports.push(fact); + void specNode; + }; + + for (const st of sf.statements) { + if (ts.isImportDeclaration(st) && ts.isStringLiteralLike(st.moduleSpecifier)) { + const names: ImportFact['names'] = []; + const c = st.importClause; + if (c?.name) names.push({ imported: 'default', local: c.name.text }); + if (c?.namedBindings) { + if (ts.isNamespaceImport(c.namedBindings)) names.push({ imported: '*', local: c.namedBindings.name.text }); + else for (const el of c.namedBindings.elements) names.push({ imported: (el.propertyName ?? el.name).text, local: el.name.text }); + } + addImport(st.moduleSpecifier, st.moduleSpecifier.text, names, 'static', st); + } else if (ts.isExportDeclaration(st) && st.moduleSpecifier && ts.isStringLiteralLike(st.moduleSpecifier)) { + const names: ImportFact['names'] = []; + if (st.exportClause && ts.isNamedExports(st.exportClause)) + for (const el of st.exportClause.elements) names.push({ imported: (el.propertyName ?? el.name).text, local: el.name.text }); + else names.push({ imported: '*', local: '*' }); + addImport(st.moduleSpecifier, st.moduleSpecifier.text, names, 'reexport', st); + } + } + + const resolveSymbol = (node: ts.Node, depth = 0): SymRef | 'unknown' | 'other' => { + let sym: ts.Symbol | undefined; + try { + sym = + ts.isShorthandPropertyAssignment(node.parent) && node.parent.name === node + ? checker.getShorthandAssignmentValueSymbol(node.parent) + : checker.getSymbolAtLocation(node); + if (sym && sym.flags & ts.SymbolFlags.Alias) { + sym = checker.getAliasedSymbol(sym); + // An import that leads outside the repository is external, not unresolved. + if (!sym.declarations?.length) return 'other'; + } + } catch { + return 'other'; + } + if (!sym || !sym.declarations?.length) return 'unknown'; + for (const d of sym.declarations) { + const direct = declMap.get(d); + if (direct) return direct; + } + for (const d of sym.declarations) { + if (ts.isExportAssignment(d) && depth < 2) { + const inner = resolveSymbol(d.expression, depth + 1); + if (typeof inner === 'object') return inner; + } + // Members of interfaces / classes that are not symbols themselves resolve to their container. + if (d.parent) { + const container = declMap.get(d.parent); + if (container && (ts.isPropertySignature(d) || ts.isMethodSignature(d) || ts.isPropertyDeclaration(d) || ts.isEnumMember(d))) + return { ...container, kind: container.kind, localId: container.localId, path: container.path, member: true } as SymRef & { member: true }; + } + } + return 'other'; + }; + + const push = (kind: EdgeType, from: string | null, target: SymRef, node: ts.Node, extra?: Record, confidence = 1, verified = true) => { + if (target.path === rel) { + if (kind !== 'CALLS' && (from === target.localId || (from && from.startsWith(`${target.localId}.`)))) return; + } + const key = `${kind}|${from}|${target.path}#${target.localId}`; + if (seen.has(key)) return; + seen.add(key); + facts.references.push({ + kind, + from, + target: { resolved: { path: target.path, localId: target.localId } }, + location: loc(node), + evidence: lineText(node), + method: kind === 'READS_FROM' || kind === 'WRITES_TO' ? 'pattern' : 'typescript-checker', + confidence, + verified, + ...(extra ? { metadata: extra } : {}), + }); + }; + + const classify = (id: ts.Node): { kind: EdgeType; extra?: Record } => { + let cur: ts.Node = id; + let p = cur.parent; + // climb through `a.b.c` so that the outermost access is classified + while (p && ts.isPropertyAccessExpression(p) && p.name === cur) { + cur = p; + p = p.parent; + } + if (!p) return { kind: 'USES' }; + if (ts.isCallExpression(p) && p.expression === cur) return { kind: 'CALLS' }; + if (ts.isNewExpression(p) && p.expression === cur) return { kind: 'INSTANTIATES' }; + if (ts.isExpressionWithTypeArguments(p) && p.expression === cur && p.parent && ts.isHeritageClause(p.parent)) { + const clause = p.parent; + return { kind: clause.token === ts.SyntaxKind.ImplementsKeyword ? 'IMPLEMENTS' : 'EXTENDS' }; + } + if ((ts.isJsxOpeningElement(p) || ts.isJsxSelfClosingElement(p)) && p.tagName === cur) return { kind: 'USES', extra: { renders: true } }; + if (ts.isTypeReferenceNode(p) || ts.isTypeQueryNode(p) || ts.isQualifiedName(p)) return { kind: 'USES', extra: { typeOnly: true } }; + if (ts.isDecorator(p) || (ts.isCallExpression(p) && p.parent && ts.isDecorator(p.parent))) return { kind: 'USES', extra: { decorator: true } }; + return { kind: 'USES' }; + }; + + const rootIdentifier = (e: ts.Expression): ts.Identifier | null => { + let cur: ts.Expression = e; + while (ts.isPropertyAccessExpression(cur) || ts.isCallExpression(cur) || ts.isNonNullExpression(cur) || ts.isAwaitExpression(cur) || ts.isParenthesizedExpression(cur)) + cur = cur.expression; + return ts.isIdentifier(cur) ? cur : null; + }; + + const visit = (node: ts.Node, enclosing: string | null): void => { + if (ts.isImportDeclaration(node) || ts.isImportEqualsDeclaration(node)) return; + if (ts.isExportDeclaration(node)) return; + + const own = declMap.get(node); + if (own && own.path === rel) enclosing = own.localId; + + if (ts.isCallExpression(node)) { + const callee = node.expression; + // require('x') / import('x') + const a0 = node.arguments[0]; + if (a0 && ts.isStringLiteralLike(a0)) { + if (ts.isIdentifier(callee) && callee.text === 'require' && node.arguments.length === 1) addImport(a0, a0.text, [{ imported: '*', local: '*' }], 'require', node); + else if (callee.kind === ts.SyntaxKind.ImportKeyword) addImport(a0, a0.text, [{ imported: '*', local: '*' }], 'dynamic', node); + } + // Route registration + const endpoint = endpointCalls.get(node); + if (endpoint) { + visit(callee, enclosing); + for (const arg of node.arguments.slice(1)) { + if (ts.isIdentifier(arg) || ts.isPropertyAccessExpression(arg)) { + const nameNode = ts.isIdentifier(arg) ? arg : arg.name; + const r = resolveSymbol(nameNode); + if (typeof r === 'object') push('ROUTES_TO', endpoint, r, arg); + else + facts.references.push({ + kind: 'ROUTES_TO', + from: endpoint, + target: { name: arg.getText(sf) }, + location: loc(arg), + evidence: lineText(arg), + method: 'typescript-checker', + confidence: 0, + verified: false, + }); + } + visit(arg, endpoint); + } + return; + } + // Data access against a known model + if (ts.isPropertyAccessExpression(callee)) { + const m = callee.name.text; + const root = rootIdentifier(callee.expression); + const rootRef = root ? resolveSymbol(root) : 'other'; + if (typeof rootRef === 'object' && rootRef.kind === 'DatabaseModel') { + if (DB_WRITE.test(m)) push('WRITES_TO', enclosing, rootRef, node, { operation: m }, 0.8, false); + else if (DB_READ.test(m)) push('READS_FROM', enclosing, rootRef, node, { operation: m }, 0.8, false); + } + if (/^(from|into|insert|update|delete|join|leftJoin|innerJoin)$/.test(m) && a0 && ts.isIdentifier(a0)) { + const argRef = resolveSymbol(a0); + if (typeof argRef === 'object' && argRef.kind === 'DatabaseModel') + push(/^(from|join|leftJoin|innerJoin)$/.test(m) ? 'READS_FROM' : 'WRITES_TO', enclosing, argRef, node, { operation: m }, 0.8, false); + } + } + } + + if (ts.isIdentifier(node)) { + const p = node.parent; + const isDeclName = + p && + (p as { name?: ts.Node }).name === node && + (ts.isFunctionDeclaration(p) || ts.isClassDeclaration(p) || ts.isClassExpression(p) || ts.isInterfaceDeclaration(p) || ts.isTypeAliasDeclaration(p) || + ts.isEnumDeclaration(p) || ts.isVariableDeclaration(p) || ts.isParameter(p) || ts.isMethodDeclaration(p) || ts.isPropertyDeclaration(p) || + ts.isPropertySignature(p) || ts.isMethodSignature(p) || ts.isPropertyAssignment(p) || ts.isEnumMember(p) || ts.isModuleDeclaration(p) || + ts.isBindingElement(p) || ts.isTypeParameterDeclaration(p) || ts.isGetAccessorDeclaration(p) || ts.isSetAccessorDeclaration(p) || + ts.isFunctionExpression(p) || ts.isJsxAttribute(p) || ts.isLabeledStatement(p) || ts.isNamedTupleMember(p)); + if (isDeclName) return; + const r = resolveSymbol(node); + const { kind, extra } = classify(node); + if (typeof r === 'object') { + const member = (r as SymRef & { member?: boolean }).member; + push(member && kind === 'CALLS' ? 'USES' : kind, enclosing, r, node, extra); + } else if (r === 'unknown' && kind === 'CALLS' && p && ts.isCallExpression(p) && p.expression === node && !KNOWN_GLOBALS.has(node.text)) { + const key = `unresolved|${enclosing}|${node.text}`; + if (!seen.has(key)) { + seen.add(key); + facts.references.push({ + kind: 'CALLS', + from: enclosing, + target: { name: node.text }, + location: loc(node), + evidence: lineText(node), + method: 'typescript-checker', + confidence: 0, + verified: false, + }); + } + } + return; + } + ts.forEachChild(node, (c) => visit(c, enclosing)); + }; + visit(sf, null); +} diff --git a/packages/repository-indexer/package.json b/packages/repository-indexer/package.json new file mode 100644 index 0000000..401354b --- /dev/null +++ b/packages/repository-indexer/package.json @@ -0,0 +1,9 @@ +{ + "name": "@vectora/repository-indexer", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MIT", + "exports": { ".": "./src/index.ts" }, + "dependencies": { "@vectora/graph-schema": "*", "@vectora/shared": "*", "@vectora/language-adapters": "*", "@vectora/graph-engine": "*", "fast-glob": "^3.3.3", "ignore": "^7.0.14", "p-limit": "^7.3.3" } +} diff --git a/packages/repository-indexer/src/analyze-worker.ts b/packages/repository-indexer/src/analyze-worker.ts new file mode 100644 index 0000000..8a06925 --- /dev/null +++ b/packages/repository-indexer/src/analyze-worker.ts @@ -0,0 +1,22 @@ +import { parentPort } from 'node:worker_threads'; +import { type WorkerRequest, type WorkerResponse, runTaskInProcess } from './workers'; + +if (!parentPort) throw new Error('analyze-worker must run as a worker thread'); +const port = parentPort; + +port.on('message', (req: WorkerRequest) => { + void (async () => { + try { + let last = 0; + const facts = await runTaskInProcess(req.task, req.ctx, (processed, total) => { + const now = Date.now(); + if (now - last < 120 && processed !== total) return; + last = now; + port.postMessage({ type: 'progress', taskIndex: req.taskIndex, processed, total } satisfies WorkerResponse); + }); + port.postMessage({ type: 'done', taskIndex: req.taskIndex, facts } satisfies WorkerResponse); + } catch (err) { + port.postMessage({ type: 'error', taskIndex: req.taskIndex, message: (err as Error).message } satisfies WorkerResponse); + } + })(); +}); diff --git a/packages/repository-indexer/src/index.ts b/packages/repository-indexer/src/index.ts new file mode 100644 index 0000000..cd5d931 --- /dev/null +++ b/packages/repository-indexer/src/index.ts @@ -0,0 +1,6 @@ +export * from './scan'; +export * from './manifests'; +export * from './resolve'; +export * from './organize'; +export * from './pipeline'; +export { runTasks, runTaskInProcess, type AnalyzeTask, type TaskContext } from './workers'; diff --git a/packages/repository-indexer/src/manifests.ts b/packages/repository-indexer/src/manifests.ts new file mode 100644 index 0000000..41c2d8e --- /dev/null +++ b/packages/repository-indexer/src/manifests.ts @@ -0,0 +1,295 @@ +/** + * Reads package manifests and derives declared dependencies, workspace + * packages, frameworks and declared entry points. Manifests are parsed as + * data; nothing in them is executed. + */ +import fs from 'node:fs'; +import path from 'node:path'; +import type { WorkspacePackage } from '@vectora/language-adapters'; +import type { ScannedFile } from './scan'; + +export interface DeclaredDependency { + name: string; + version: string | null; + manifest: string; + ecosystem: 'npm' | 'pypi' | 'go' | 'cargo' | 'maven' | 'nuget'; + dev: boolean; + line: number; + evidence: string; +} + +export interface ManifestInfo { + dependencies: DeclaredDependency[]; + workspacePackages: WorkspacePackage[]; + frameworks: { name: string; evidence: string }[]; + declaredEntryPoints: { path: string; reason: string }[]; + description: string | null; + descriptionSource: string | null; + goModules: { dir: string; module: string }[]; + cargoCrates: { dir: string; name: string }[]; + manifests: string[]; +} + +const FRAMEWORKS: Record = { + react: 'React', 'react-dom': 'React', next: 'Next.js', vue: 'Vue', nuxt: 'Nuxt', svelte: 'Svelte', '@angular/core': 'Angular', + express: 'Express', fastify: 'Fastify', koa: 'Koa', '@nestjs/core': 'NestJS', hono: 'Hono', vite: 'Vite', webpack: 'webpack', + tailwindcss: 'Tailwind CSS', three: 'Three.js', electron: 'Electron', '@tauri-apps/api': 'Tauri', prisma: 'Prisma', '@prisma/client': 'Prisma', + 'drizzle-orm': 'Drizzle ORM', typeorm: 'TypeORM', sequelize: 'Sequelize', mongoose: 'Mongoose', vitest: 'Vitest', jest: 'Jest', + '@playwright/test': 'Playwright', graphql: 'GraphQL', 'react-native': 'React Native', zustand: 'Zustand', redux: 'Redux', + django: 'Django', flask: 'Flask', fastapi: 'FastAPI', sqlalchemy: 'SQLAlchemy', pytest: 'pytest', celery: 'Celery', pydantic: 'Pydantic', + numpy: 'NumPy', pandas: 'pandas', torch: 'PyTorch', tensorflow: 'TensorFlow', starlette: 'Starlette', aiohttp: 'aiohttp', + 'github.com/gin-gonic/gin': 'Gin', 'github.com/labstack/echo': 'Echo', 'github.com/gorilla/mux': 'Gorilla Mux', 'gorm.io/gorm': 'GORM', + 'github.com/spf13/cobra': 'Cobra', tokio: 'Tokio', 'actix-web': 'Actix Web', axum: 'Axum', rocket: 'Rocket', serde: 'Serde', diesel: 'Diesel', + clap: 'clap', 'org.springframework.boot': 'Spring Boot', 'org.springframework': 'Spring', 'org.hibernate': 'Hibernate', junit: 'JUnit', + 'Microsoft.AspNetCore.App': 'ASP.NET Core', 'Microsoft.EntityFrameworkCore': 'Entity Framework Core', +}; + +const read = (abs: string): string | null => { + try { + return fs.readFileSync(abs, 'utf8'); + } catch { + return null; + } +}; +const dirOf = (p: string): string => (p.includes('/') ? p.slice(0, p.lastIndexOf('/')) : ''); +const lineOf = (text: string, needle: string): number => { + const i = text.indexOf(needle); + return i === -1 ? 1 : text.slice(0, i).split('\n').length; +}; + +export function readManifests(rootDir: string, files: ScannedFile[]): ManifestInfo { + const info: ManifestInfo = { + dependencies: [], + workspacePackages: [], + frameworks: [], + declaredEntryPoints: [], + description: null, + descriptionSource: null, + goModules: [], + cargoCrates: [], + manifests: [], + }; + const fileSet = new Set(files.map((f) => f.path)); + const frameworkSeen = new Set(); + const addDep = (d: DeclaredDependency) => { + info.dependencies.push(d); + const fw = FRAMEWORKS[d.name] ?? FRAMEWORKS[d.name.toLowerCase()] ?? Object.entries(FRAMEWORKS).find(([k]) => k.includes('.') && d.name.startsWith(k))?.[1]; + if (fw && !frameworkSeen.has(fw)) { + frameworkSeen.add(fw); + info.frameworks.push({ name: fw, evidence: `${d.manifest}:${d.line} declares ${d.name}` }); + } + }; + const findEntry = (dir: string, candidates: (string | undefined)[]): string | null => { + for (const c of candidates) { + if (!c || typeof c !== 'string') continue; + const base = path.posix.normalize(path.posix.join(dir, c)); + const stem = base.replace(/\.(js|mjs|cjs|jsx)$/, ''); + for (const p of [base, `${stem}.ts`, `${stem}.tsx`, `${base}.ts`, `${base}.js`, `${base}/index.ts`, `${base}/index.js`]) if (fileSet.has(p)) return p; + // Built output usually mirrors src/. + const src = base.replace(/^(.*?\/)?(dist|build|lib|out)\//, '$1src/').replace(/\.(js|mjs|cjs)$/, ''); + for (const p of [`${src}.ts`, `${src}.tsx`, `${src}.js`]) if (fileSet.has(p)) return p; + } + return null; + }; + + for (const f of files) { + const base = f.path.slice(f.path.lastIndexOf('/') + 1); + const dir = dirOf(f.path); + if (base === 'package.json') { + const text = read(f.absPath); + if (!text) continue; + let pkg: Record; + try { + pkg = JSON.parse(text) as Record; + } catch { + continue; + } + info.manifests.push(f.path); + for (const [field, dev] of [['dependencies', false], ['devDependencies', true], ['peerDependencies', false], ['optionalDependencies', false]] as const) { + const deps = pkg[field]; + if (!deps || typeof deps !== 'object') continue; + for (const [name, version] of Object.entries(deps as Record)) { + const needle = `"${name}"`; + addDep({ name, version: typeof version === 'string' ? version : null, manifest: f.path, ecosystem: 'npm', dev, line: lineOf(text, needle), evidence: `${needle}: "${String(version)}"` }); + } + } + const exp = pkg.exports; + const exportEntry = + typeof exp === 'string' ? exp : exp && typeof exp === 'object' ? ((exp as Record)['.'] as unknown) : undefined; + const exportPath = + typeof exportEntry === 'string' + ? exportEntry + : exportEntry && typeof exportEntry === 'object' + ? (Object.values(exportEntry as Record).find((v) => typeof v === 'string') as string | undefined) + : undefined; + const entry = findEntry(dir, [pkg.source as string, exportPath, pkg.module as string, pkg.main as string, 'src/index', 'index']); + if (typeof pkg.name === 'string') info.workspacePackages.push({ name: pkg.name, dir, entry }); + if (typeof pkg.main === 'string' || exportPath) { + const e = findEntry(dir, [exportPath, pkg.main as string]); + if (e) info.declaredEntryPoints.push({ path: e, reason: `${f.path} "main"/"exports"` }); + } + const bin = pkg.bin; + for (const b of typeof bin === 'string' ? [bin] : bin && typeof bin === 'object' ? Object.values(bin as Record) : []) { + const e = findEntry(dir, [b]); + if (e) info.declaredEntryPoints.push({ path: e, reason: `${f.path} "bin"` }); + } + const scripts = pkg.scripts; + if (scripts && typeof scripts === 'object') { + for (const key of ['start', 'dev', 'serve']) { + const cmd = (scripts as Record)[key]; + if (typeof cmd !== 'string') continue; + const m = /(?:node|tsx|ts-node|bun|deno run)\s+(?:--?[\w-]+(?:[= ]\S+)?\s+)*([\w./-]+\.(?:[cm]?[jt]sx?))/.exec(cmd); + const e = m ? findEntry(dir, [m[1]]) : null; + if (e) info.declaredEntryPoints.push({ path: e, reason: `${f.path} script "${key}"` }); + } + } + if (dir === '' && typeof pkg.description === 'string' && pkg.description.trim()) { + info.description = pkg.description.trim(); + info.descriptionSource = f.path; + } + } else if (base === 'requirements.txt' || /^requirements[-_.].*\.txt$/.test(base)) { + const text = read(f.absPath); + if (!text) continue; + info.manifests.push(f.path); + text.split(/\r?\n/).forEach((raw, i) => { + const line = raw.split('#')[0]!.trim(); + const m = /^([A-Za-z0-9][A-Za-z0-9._-]*)\s*(?:\[[^\]]*\])?\s*([<>=!~].*)?$/.exec(line); + if (m) addDep({ name: m[1]!.toLowerCase(), version: m[2]?.trim() ?? null, manifest: f.path, ecosystem: 'pypi', dev: /dev|test/.test(base), line: i + 1, evidence: line }); + }); + } else if (base === 'pyproject.toml') { + const text = read(f.absPath); + if (!text) continue; + info.manifests.push(f.path); + const lines = text.split(/\r?\n/); + let section = ''; + let inArray = false; + lines.forEach((raw, i) => { + const line = raw.trim(); + const sec = /^\[([^\]]+)\]$/.exec(line); + if (sec) { + section = sec[1]!; + inArray = false; + return; + } + if (section === 'project' && /^dependencies\s*=\s*\[/.test(line)) inArray = !line.includes(']'); + const inDepsArray = (section === 'project' && (inArray || /^dependencies\s*=/.test(line))) || /optional-dependencies|dependency-groups/.test(section); + if (inDepsArray) { + for (const m of line.matchAll(/["']([A-Za-z0-9][A-Za-z0-9._-]*)\s*(?:\[[^\]]*\])?\s*([<>=!~][^"']*)?["']/g)) + addDep({ name: m[1]!.toLowerCase(), version: m[2]?.trim() ?? null, manifest: f.path, ecosystem: 'pypi', dev: section !== 'project', line: i + 1, evidence: line }); + if (inArray && line.includes(']')) inArray = false; + } else if (/^tool\.poetry\.(dev-)?dependencies|^tool\.poetry\.group\..*\.dependencies/.test(section)) { + const m = /^([A-Za-z0-9][A-Za-z0-9._-]*)\s*=\s*(.+)$/.exec(line); + if (m && m[1] !== 'python') addDep({ name: m[1]!.toLowerCase(), version: m[2]!.replace(/["']/g, ''), manifest: f.path, ecosystem: 'pypi', dev: /dev|group/.test(section), line: i + 1, evidence: line }); + } + if (dir === '' && (section === 'project' || section === 'tool.poetry') && !info.description) { + const d = /^description\s*=\s*["'](.+)["']\s*$/.exec(line); + if (d) { + info.description = d[1]!; + info.descriptionSource = f.path; + } + } + }); + } else if (base === 'go.mod') { + const text = read(f.absPath); + if (!text) continue; + info.manifests.push(f.path); + const mod = /^module\s+(\S+)/m.exec(text); + if (mod) info.goModules.push({ dir, module: mod[1]! }); + text.split(/\r?\n/).forEach((raw, i) => { + const m = /^\s*(?:require\s+)?([\w.-]+\.[\w.-]+\/\S+)\s+(v\S+)/.exec(raw); + if (m) addDep({ name: m[1]!, version: m[2]!, manifest: f.path, ecosystem: 'go', dev: /\/\/\s*indirect/.test(raw), line: i + 1, evidence: raw.trim() }); + }); + } else if (base === 'Cargo.toml') { + const text = read(f.absPath); + if (!text) continue; + info.manifests.push(f.path); + let section = ''; + text.split(/\r?\n/).forEach((raw, i) => { + const line = raw.trim(); + const sec = /^\[([^\]]+)\]$/.exec(line); + if (sec) { + section = sec[1]!; + return; + } + if (section === 'package') { + const n = /^name\s*=\s*"([^"]+)"/.exec(line); + if (n) info.cargoCrates.push({ dir, name: n[1]! }); + const d = /^description\s*=\s*"([^"]+)"/.exec(line); + if (d && dir === '' && !info.description) { + info.description = d[1]!; + info.descriptionSource = f.path; + } + } else if (/dependencies$/.test(section)) { + const m = /^([A-Za-z0-9_-]+)\s*=\s*(.+)$/.exec(line); + if (m) { + const v = /"([^"]+)"/.exec(m[2]!); + addDep({ name: m[1]!, version: v?.[1] ?? null, manifest: f.path, ecosystem: 'cargo', dev: section !== 'dependencies', line: i + 1, evidence: line }); + } + } + }); + } else if (base === 'pom.xml') { + const text = read(f.absPath); + if (!text) continue; + info.manifests.push(f.path); + for (const m of text.matchAll(/([\s\S]*?)<\/dependency>/g)) { + const g = /([^<]+)<\/groupId>/.exec(m[1]!)?.[1]; + const a = /([^<]+)<\/artifactId>/.exec(m[1]!)?.[1]; + const v = /([^<]+)<\/version>/.exec(m[1]!)?.[1] ?? null; + if (g && a) addDep({ name: `${g}:${a}`, version: v, manifest: f.path, ecosystem: 'maven', dev: /test<\/scope>/.test(m[1]!), line: lineOf(text, m[0]), evidence: `${g}:${a}${v ? `:${v}` : ''}` }); + if (g && FRAMEWORKS[g] && !frameworkSeen.has(FRAMEWORKS[g]!)) { + frameworkSeen.add(FRAMEWORKS[g]!); + info.frameworks.push({ name: FRAMEWORKS[g]!, evidence: `${f.path} declares ${g}:${a}` }); + } + } + } else if (base.endsWith('.csproj')) { + const text = read(f.absPath); + if (!text) continue; + info.manifests.push(f.path); + for (const m of text.matchAll(/<(PackageReference|FrameworkReference)\s+Include="([^"]+)"(?:\s+Version="([^"]+)")?/g)) + addDep({ name: m[2]!, version: m[3] ?? null, manifest: f.path, ecosystem: 'nuget', dev: false, line: lineOf(text, m[0]), evidence: m[0] }); + if (/Sdk="Microsoft\.NET\.Sdk\.Web"/.test(text) && !frameworkSeen.has('ASP.NET Core')) { + frameworkSeen.add('ASP.NET Core'); + info.frameworks.push({ name: 'ASP.NET Core', evidence: `${f.path} uses Microsoft.NET.Sdk.Web` }); + } + } + } + + // Fall back to the first paragraph of the root README for the description. + if (!info.description) { + const readme = files.find((f) => /^readme(\.(md|rst|txt))?$/i.test(f.path)); + const text = readme ? read(readme.absPath) : null; + if (readme && text) { + const para = text + .split(/\r?\n\s*\r?\n/) + .map((p) => p.trim()) + .find((p) => p && !/^(#|=|!\[|<|\[!\[|---|```)/.test(p) && p.length > 20); + if (para) { + const clean = para.replace(/\s+/g, ' ').replace(/[*_`]/g, ''); + info.description = clean.length > 400 ? `${clean.slice(0, 397)}...` : clean; + info.descriptionSource = readme.path; + } + } + } + return info; +} + +const CONFIG_NAMES = new Set([ + 'package.json', 'tsconfig.json', 'jsconfig.json', 'pyproject.toml', 'setup.py', 'setup.cfg', 'requirements.txt', 'go.mod', 'cargo.toml', 'pom.xml', + 'build.gradle', 'build.gradle.kts', 'settings.gradle', 'makefile', 'cmakelists.txt', 'dockerfile', 'docker-compose.yml', 'docker-compose.yaml', + '.env.example', '.editorconfig', '.eslintrc', '.eslintrc.json', '.eslintrc.js', '.prettierrc', '.prettierrc.json', '.babelrc', '.npmrc', 'tox.ini', + 'pytest.ini', 'manage.py', 'webpack.config.js', 'rollup.config.js', 'turbo.json', 'nx.json', 'lerna.json', 'pnpm-workspace.yaml', 'vercel.json', + 'netlify.toml', 'procfile', 'appsettings.json', '.gitignore', '.gitattributes', '.dockerignore', +]); + +export function isConfigFile(p: string): boolean { + const base = p.slice(p.lastIndexOf('/') + 1).toLowerCase(); + if (CONFIG_NAMES.has(base)) return true; + if (/^(vite|vitest|playwright|eslint|tailwind|postcss|next|nuxt|svelte|astro|jest|babel|drizzle|tsup|rollup|webpack)\.config\.[cm]?[jt]s$/.test(base)) return true; + if (/\.(csproj|sln|tf|tfvars)$/.test(base)) return true; + if (p.startsWith('.github/') && /\.ya?ml$/.test(base)) return true; + if (/^tsconfig\..*\.json$/.test(base) || /^dockerfile\./.test(base) || /^\.env\./.test(base)) return true; + return false; +} + +export const isTestFile = (p: string): boolean => + /(^|\/)(__tests__|tests?|spec|e2e)\//.test(p) || /\.(test|spec)\.[cm]?[jt]sx?$/.test(p) || /(^|\/)test_[^/]+\.py$/.test(p) || /_test\.(go|py)$/.test(p) || /Tests?\.(java|cs)$/.test(p); diff --git a/packages/repository-indexer/src/organize.ts b/packages/repository-indexer/src/organize.ts new file mode 100644 index 0000000..053e697 --- /dev/null +++ b/packages/repository-indexer/src/organize.ts @@ -0,0 +1,445 @@ +/** + * Stages 4 and 5 — execution flows and semantic organisation. + * + * Everything produced here is a derived interpretation and is marked as such: + * subsystem membership comes from repository layout, concept membership from + * identifier and path evidence. Nothing in this stage alters verified facts. + */ +import { type GraphEdge, type GraphNode, edgeId, isSymbolType, nodeId } from '@vectora/graph-schema'; +import { slugify } from '@vectora/shared'; +import type { ManifestInfo } from './manifests'; + +export interface ExecutionFlow { + id: string; + name: string; + kind: 'request' | 'startup'; + /** Ordered node ids from the entry to the deepest reached node. */ + steps: string[]; + reachesData: boolean; +} + +export interface EntryPoint { + path: string; + nodeId: string; + reason: string; +} + +export interface OrganizeOutput { + nodes: GraphNode[]; + edges: GraphEdge[]; + entryPoints: EntryPoint[]; + flows: ExecutionFlow[]; +} + +const CONCEPTS: { key: string; name: string; terms: string[]; description: string }[] = [ + { key: 'authentication', name: 'Authentication', terms: ['auth', 'authentication', 'authorize', 'authorization', 'login', 'logout', 'signin', 'signup', 'session', 'jwt', 'oauth', 'password', 'credential', 'credentials', 'permission', 'token'], description: 'Identity, sessions and access control.' }, + { key: 'user-management', name: 'User management', terms: ['user', 'users', 'account', 'accounts', 'profile', 'member', 'role', 'roles', 'registration', 'register'], description: 'User accounts, profiles and roles.' }, + { key: 'payments', name: 'Payment processing', terms: ['payment', 'payments', 'billing', 'invoice', 'checkout', 'stripe', 'subscription', 'cart', 'order', 'orders', 'refund', 'price', 'pricing'], description: 'Orders, billing and payment handling.' }, + { key: 'data-storage', name: 'Database management', terms: ['database', 'db', 'repository', 'repositories', 'model', 'models', 'schema', 'migration', 'migrations', 'query', 'orm', 'sql', 'sqlite', 'postgres', 'mongo', 'persistence', 'storage', 'store', 'entity', 'entities'], description: 'Persistence, models and data access.' }, + { key: 'api-layer', name: 'API layer', terms: ['api', 'route', 'routes', 'router', 'controller', 'controllers', 'endpoint', 'endpoints', 'handler', 'handlers', 'rest', 'graphql', 'middleware', 'server', 'http', 'request', 'response'], description: 'Request handling and service interfaces.' }, + { key: 'interface', name: 'Frontend rendering', terms: ['component', 'components', 'view', 'views', 'page', 'pages', 'ui', 'render', 'layout', 'widget', 'template', 'templates', 'hook', 'hooks', 'screen', 'theme', 'style', 'styles'], description: 'User interface components and presentation.' }, + { key: 'configuration', name: 'Configuration', terms: ['config', 'configuration', 'settings', 'env', 'options', 'preferences'], description: 'Settings and environment configuration.' }, + { key: 'infrastructure', name: 'Infrastructure', terms: ['docker', 'deploy', 'deployment', 'ci', 'k8s', 'kubernetes', 'terraform', 'infra', 'infrastructure', 'pipeline', 'build', 'release', 'workflow', 'workflows'], description: 'Build, deployment and operations.' }, + { key: 'testing', name: 'Testing', terms: ['test', 'tests', 'spec', 'mock', 'mocks', 'fixture', 'fixtures', 'e2e', 'benchmark'], description: 'Automated tests and fixtures.' }, + { key: 'messaging', name: 'Messaging and events', terms: ['queue', 'event', 'events', 'pubsub', 'kafka', 'email', 'mail', 'notification', 'notifications', 'webhook', 'message', 'broker', 'worker', 'job', 'jobs'], description: 'Asynchronous work, events and notifications.' }, + { key: 'search', name: 'Search', terms: ['search', 'index', 'indexer', 'indexing', 'lookup', 'ranking'], description: 'Indexing and retrieval.' }, + { key: 'caching', name: 'Caching', terms: ['cache', 'caching', 'redis', 'memo', 'memoize'], description: 'Caches and memoisation.' }, + { key: 'observability', name: 'Logging and monitoring', terms: ['log', 'logger', 'logging', 'telemetry', 'metrics', 'tracing', 'monitor', 'monitoring'], description: 'Logs, metrics and diagnostics.' }, + { key: 'parsing', name: 'Parsing and analysis', terms: ['parser', 'parse', 'ast', 'lexer', 'tokenizer', 'compiler', 'analyzer', 'analysis', 'adapter', 'adapters', 'grammar', 'syntax'], description: 'Parsing, syntax trees and static analysis.' }, + { key: 'visualization', name: 'Visualisation', terms: ['graph', 'chart', 'canvas', 'visualization', 'visualisation', 'plot', 'diagram', 'scene', 'camera', 'atlas', 'mindmap'], description: 'Graphs, charts and visual rendering.' }, + { key: 'security', name: 'Security', terms: ['security', 'crypto', 'encrypt', 'encryption', 'decrypt', 'hash', 'sanitize', 'csrf', 'cors', 'secret', 'secrets', 'redact'], description: 'Cryptography and input protection.' }, + { key: 'import-export', name: 'Import and export', terms: ['import', 'importer', 'export', 'exporter', 'upload', 'download', 'archive', 'zip', 'serialize', 'serializer'], description: 'Moving data in and out of the system.' }, +]; + +const tokenize = (s: string): string[] => + s + .replace(/([a-z0-9])([A-Z])/g, '$1 $2') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2') + .toLowerCase() + .split(/[^a-z0-9]+/) + .filter((t) => t.length > 1); + +const pretty = (s: string): string => + s + .replace(/[-_.]+/g, ' ') + .replace(/([a-z0-9])([A-Z])/g, '$1 $2') + .replace(/\b\w/g, (c) => c.toUpperCase()) + .trim(); + +const dirOf = (p: string): string => (p.includes('/') ? p.slice(0, p.lastIndexOf('/')) : ''); + +/** Chooses the directory prefixes that act as subsystems. */ +export function chooseSubsystemRoots(filePaths: string[], manifests: ManifestInfo): { key: string; name: string; dir: string }[] { + const code = filePaths; + const workspace = manifests.workspacePackages.filter((p) => p.dir !== '' && code.some((f) => f.startsWith(`${p.dir}/`))); + if (workspace.length >= 2) { + return workspace + .filter((p, _, all) => !all.some((o) => o !== p && p.dir.startsWith(`${o.dir}/`))) + .map((p) => ({ key: p.dir, name: pretty(p.dir.split('/').pop()!), dir: p.dir })); + } + // Descend through wrapper directories (`src/`, `lib/`, a single package dir) that hold nearly everything. + let base = ''; + for (let depth = 0; depth < 4; depth++) { + const counts = new Map(); + let direct = 0; + let total = 0; + for (const f of code) { + if (base && !f.startsWith(`${base}/`)) continue; + total++; + const rest = base ? f.slice(base.length + 1) : f; + const i = rest.indexOf('/'); + if (i === -1) direct++; + else counts.set(rest.slice(0, i), (counts.get(rest.slice(0, i)) ?? 0) + 1); + } + const dominant = [...counts.entries()].sort((a, b) => b[1] - a[1])[0]; + if (dominant && dominant[1] >= total * 0.8 && direct <= total * 0.15 && counts.size <= 4) base = base ? `${base}/${dominant[0]}` : dominant[0]; + else break; + } + const groups = new Map(); + for (const f of code) { + if (base && !f.startsWith(`${base}/`)) { + const top = f.includes('/') ? f.slice(0, f.indexOf('/')) : ''; + if (top) groups.set(top, (groups.get(top) ?? 0) + 1); + continue; + } + const rest = base ? f.slice(base.length + 1) : f; + const i = rest.indexOf('/'); + if (i !== -1) { + const dir = base ? `${base}/${rest.slice(0, i)}` : rest.slice(0, i); + groups.set(dir, (groups.get(dir) ?? 0) + 1); + } + } + return [...groups.entries()] + .filter(([dir]) => !dir.startsWith('.')) + .map(([dir]) => ({ key: dir, name: pretty(dir.split('/').pop()!), dir })); +} + +export function organize( + repositoryId: string, + repositoryName: string, + baseNodes: GraphNode[], + baseEdges: GraphEdge[], + manifests: ManifestInfo, +): OrganizeOutput { + const nodes: GraphNode[] = []; + const edges: GraphEdge[] = []; + const byId = new Map(baseNodes.map((n) => [n.id, n])); + const fileNodes = baseNodes.filter((n) => n.type === 'File' || n.type === 'Configuration'); + const repoId = nodeId.repository(); + + // ---- subsystems (structural grouping) ---------------------------------- + const roots = chooseSubsystemRoots( + fileNodes.map((n) => n.filePath!), + manifests, + ).sort((a, b) => b.dir.length - a.dir.length); + const subsystemOfFile = new Map(); + const subsystemFiles = new Map(); + const rootKey = '__root__'; + for (const f of fileNodes) { + const p = f.filePath!; + const root = roots.find((r) => p.startsWith(`${r.dir}/`)); + const key = root?.key ?? rootKey; + subsystemOfFile.set(f.id, key); + subsystemFiles.set(key, (subsystemFiles.get(key) ?? 0) + 1); + } + const subsystemIds = new Map(); + for (const [key, count] of subsystemFiles) { + const root = roots.find((r) => r.key === key); + const id = nodeId.subsystem(key === rootKey ? 'root' : key); + subsystemIds.set(key, id); + nodes.push({ + id, + name: root ? root.name : `${repositoryName} root`, + type: 'Subsystem', + repositoryId, + filePath: root?.dir ?? '', + location: null, + language: null, + description: root ? `Files under ${root.dir}/` : 'Files at the top level of the repository.', + metadata: { files: count, derived: true, basis: 'directory layout' }, + extractionMethod: 'structural-grouping', + confidence: 0.9, + verified: true, + }); + edges.push({ + id: edgeId('CONTAINS', repoId, id), + source: repoId, + target: id, + type: 'CONTAINS', + evidence: root ? `Directory ${root.dir}/ holds ${count} files` : `${count} top-level files`, + location: null, + extractionMethod: 'structural-grouping', + confidence: 0.9, + verified: true, + }); + } + for (const f of fileNodes) { + const key = subsystemOfFile.get(f.id)!; + const sid = subsystemIds.get(key)!; + f.metadata.subsystem = sid; + edges.push({ + id: edgeId('BELONGS_TO', f.id, sid), + source: f.id, + target: sid, + type: 'BELONGS_TO', + evidence: key === rootKey ? `${f.filePath} is a top-level file` : `${f.filePath} is under ${key}/`, + location: null, + extractionMethod: 'structural-grouping', + confidence: 0.9, + verified: true, + }); + } + // Symbols inherit the subsystem of their file (used for clustering in the views). + const fileOf = (n: GraphNode): GraphNode | undefined => (n.filePath ? byId.get(nodeId.file(n.filePath)) : undefined); + for (const n of baseNodes) if (isSymbolType(n.type)) n.metadata.subsystem = fileOf(n)?.metadata.subsystem; + + // ---- aggregated subsystem dependencies --------------------------------- + const subOfNode = (id: string): string | undefined => { + const n = byId.get(id); + if (!n) return undefined; + return (n.metadata.subsystem as string | undefined) ?? undefined; + }; + const agg = new Map }>(); + for (const e of baseEdges) { + if (!['IMPORTS', 'CALLS', 'USES', 'EXTENDS', 'IMPLEMENTS', 'INSTANTIATES', 'READS_FROM', 'WRITES_TO'].includes(e.type)) continue; + const a = subOfNode(e.source); + const b = subOfNode(e.target); + if (!a || !b || a === b) continue; + e.metadata = { ...(e.metadata ?? {}), crossSubsystem: true }; + const key = `${a}|${b}`; + const cur = agg.get(key); + if (cur) { + cur.count++; + cur.kinds[e.type] = (cur.kinds[e.type] ?? 0) + 1; + } else agg.set(key, { count: 1, example: e, kinds: { [e.type]: 1 } }); + } + for (const [key, v] of agg) { + const [a, b] = key.split('|') as [string, string]; + const ex = v.example; + edges.push({ + id: edgeId('DEPENDS_ON', a, b), + source: a, + target: b, + type: 'DEPENDS_ON', + evidence: `${v.count} cross-subsystem relationship${v.count === 1 ? '' : 's'}, e.g. ${ex.location ? `${ex.location.path}:${ex.location.startLine}` : ex.source} — ${ex.evidence}`, + location: ex.location, + extractionMethod: 'aggregation', + confidence: 1, + verified: true, + metadata: { count: v.count, kinds: v.kinds }, + }); + } + + // ---- concepts (keyword evidence) --------------------------------------- + const symbolsByFile = new Map(); + for (const n of baseNodes) { + if (!isSymbolType(n.type) || !n.filePath) continue; + const fid = nodeId.file(n.filePath); + (symbolsByFile.get(fid) ?? symbolsByFile.set(fid, []).get(fid)!).push(n); + } + const importsByFile = new Map(); + for (const e of baseEdges) { + if (e.type !== 'IMPORTS' || !e.target.startsWith('pkg:')) continue; + (importsByFile.get(e.source) ?? importsByFile.set(e.source, []).get(e.source)!).push(e.target.slice(4)); + } + const termIndex = new Map(); + CONCEPTS.forEach((c, i) => c.terms.forEach((t) => (termIndex.get(t) ?? termIndex.set(t, []).get(t)!).push(i))); + const members: { fileId: string; score: number; evidence: string[] }[][] = CONCEPTS.map(() => []); + + for (const f of fileNodes) { + const p = f.filePath!; + const scores = new Map(); + const hit = (ci: number, weight: number, ev: string) => { + const s = scores.get(ci) ?? { score: 0, evidence: [] }; + s.score += weight; + if (s.evidence.length < 6 && !s.evidence.includes(ev)) s.evidence.push(ev); + scores.set(ci, s); + }; + const segs = p.split('/'); + segs.forEach((seg, i) => { + for (const t of new Set(tokenize(seg))) for (const ci of termIndex.get(t) ?? []) hit(ci, i === segs.length - 1 ? 2 : 3, `path segment "${seg}"`); + }); + const seenSym = new Set(); + for (const s of symbolsByFile.get(f.id) ?? []) { + if (s.type === 'ApiEndpoint') hit(CONCEPTS.findIndex((c) => c.key === 'api-layer'), 4, `defines endpoint ${s.name}`); + else if (s.type === 'DatabaseModel') hit(CONCEPTS.findIndex((c) => c.key === 'data-storage'), 4, `defines model ${s.name}`); + else if (s.type === 'Component') hit(CONCEPTS.findIndex((c) => c.key === 'interface'), 2, `defines component ${s.name}`); + for (const t of new Set(tokenize(s.name))) { + for (const ci of termIndex.get(t) ?? []) { + const k = `${ci}:${s.name}`; + if (seenSym.has(k)) continue; + seenSym.add(k); + hit(ci, 1, `symbol ${s.name}`); + } + } + } + for (const pkg of importsByFile.get(f.id) ?? []) for (const t of new Set(tokenize(pkg))) for (const ci of termIndex.get(t) ?? []) hit(ci, 1, `imports ${pkg}`); + if (f.metadata.test) hit(CONCEPTS.findIndex((c) => c.key === 'testing'), 4, 'test file naming convention'); + for (const [ci, s] of scores) if (s.score >= 3) members[ci]!.push({ fileId: f.id, score: s.score, evidence: s.evidence }); + } + + const conceptOfFile = new Map(); + CONCEPTS.forEach((c, i) => { + const m = members[i]!; + if (m.length < 2 && !(m.length === 1 && m[0]!.score >= 6)) return; + const id = nodeId.concept(c.key); + nodes.push({ + id, + name: c.name, + type: 'Concept', + repositoryId, + filePath: null, + location: null, + language: null, + description: c.description, + metadata: { files: m.length, derived: true, basis: 'identifier and path evidence', terms: c.terms }, + extractionMethod: 'keyword-evidence', + confidence: 0.6, + verified: false, + }); + edges.push({ + id: edgeId('CONTAINS', repoId, id), + source: repoId, + target: id, + type: 'CONTAINS', + evidence: `${m.length} files carry evidence for "${c.name}"`, + location: null, + extractionMethod: 'keyword-evidence', + confidence: 0.6, + verified: false, + }); + for (const mem of m) { + const fn = byId.get(mem.fileId)!; + (conceptOfFile.get(mem.fileId) ?? conceptOfFile.set(mem.fileId, []).get(mem.fileId)!).push(id); + edges.push({ + id: edgeId('BELONGS_TO', mem.fileId, id), + source: mem.fileId, + target: id, + type: 'BELONGS_TO', + evidence: mem.evidence.join('; '), + location: fn.location, + extractionMethod: 'keyword-evidence', + confidence: Math.min(0.9, 0.4 + mem.score * 0.05), + verified: false, + metadata: { score: mem.score }, + }); + } + }); + for (const [fid, concepts] of conceptOfFile) byId.get(fid)!.metadata.concepts = concepts; + + // Concepts that reference each other through verified relationships. + const conceptLinks = new Map(); + for (const e of baseEdges) { + if (!['IMPORTS', 'CALLS', 'USES', 'INSTANTIATES', 'EXTENDS'].includes(e.type)) continue; + const sf = byId.get(e.source)?.filePath; + const tf = byId.get(e.target)?.filePath; + if (!sf || !tf || sf === tf) continue; + const sc = conceptOfFile.get(nodeId.file(sf)); + const tc = conceptOfFile.get(nodeId.file(tf)); + if (!sc || !tc) continue; + for (const a of sc) + for (const b of tc) { + if (a === b) continue; + const key = a < b ? `${a}|${b}` : `${b}|${a}`; + const cur = conceptLinks.get(key); + if (cur) cur.count++; + else conceptLinks.set(key, { count: 1, example: e }); + } + } + for (const [key, v] of conceptLinks) { + if (v.count < 3) continue; + const [a, b] = key.split('|') as [string, string]; + edges.push({ + id: edgeId('RELATED_TO', a, b), + source: a, + target: b, + type: 'RELATED_TO', + evidence: `${v.count} relationships connect files of both concepts, e.g. ${v.example.location ? `${v.example.location.path}:${v.example.location.startLine}` : ''} — ${v.example.evidence}`, + location: v.example.location, + extractionMethod: 'aggregation', + confidence: 0.5, + verified: false, + metadata: { count: v.count }, + }); + } + + // ---- entry points ------------------------------------------------------- + const entryPoints: EntryPoint[] = []; + const seenEntry = new Set(); + const addEntry = (p: string, reason: string) => { + const id = nodeId.file(p); + const n = byId.get(id); + if (!n || seenEntry.has(p)) return; + seenEntry.add(p); + n.metadata.entryPoint = reason; + entryPoints.push({ path: p, nodeId: id, reason }); + }; + for (const e of manifests.declaredEntryPoints) addEntry(e.path, `declared in ${e.reason}`); + const importers = new Map(); + const importsOut = new Map(); + for (const e of baseEdges) { + if (e.type !== 'IMPORTS' || !e.target.startsWith('file:')) continue; + importers.set(e.target, (importers.get(e.target) ?? 0) + 1); + importsOut.set(e.source, (importsOut.get(e.source) ?? 0) + 1); + } + const ENTRY_NAME = /^(main|index|app|server|cli|__main__|manage|wsgi|asgi|program|application|start|run)\.(ts|tsx|js|mjs|cjs|py|go|rs|java|cs|c|cpp)$/i; + for (const f of fileNodes) { + if (f.metadata.test || !f.metadata.analyzed) continue; + const p = f.filePath!; + const base = p.slice(p.lastIndexOf('/') + 1); + const depth = p.split('/').length; + const hasMain = (symbolsByFile.get(f.id) ?? []).some((s) => s.name === 'main' && !s.metadata.qualifiedName?.toString().includes('.')); + if (hasMain && /\.(go|rs|c|cpp|java|cs|py)$/.test(p)) addEntry(p, 'defines a main function'); + else if (ENTRY_NAME.test(base) && depth <= 4 && !importers.has(f.id) && (importsOut.get(f.id) ?? 0) > 0) addEntry(p, 'conventional entry file that nothing else imports'); + } + + // ---- execution flows ---------------------------------------------------- + const out = new Map(); + for (const e of baseEdges) { + if (!['ROUTES_TO', 'CALLS', 'INSTANTIATES', 'READS_FROM', 'WRITES_TO'].includes(e.type)) continue; + (out.get(e.source) ?? out.set(e.source, []).get(e.source)!).push(e); + } + const flows: ExecutionFlow[] = []; + const trace = (start: string, maxDepth: number): { steps: string[]; reachesData: boolean } => { + // Breadth-first search for the shortest chain that reaches data access; + // falls back to the deepest chain found. + const parent = new Map([[start, null]]); + let frontier = [start]; + let deepest = start; + let dataHit: string | null = null; + for (let d = 0; d < maxDepth && frontier.length && !dataHit; d++) { + const next: string[] = []; + for (const id of frontier) { + for (const e of out.get(id) ?? []) { + if (parent.has(e.target)) continue; + parent.set(e.target, id); + next.push(e.target); + deepest = e.target; + if (e.type === 'READS_FROM' || e.type === 'WRITES_TO' || byId.get(e.target)?.type === 'DatabaseModel') { + dataHit = e.target; + break; + } + } + if (dataHit) break; + } + frontier = next.slice(0, 400); + } + const steps: string[] = []; + for (let cur: string | null = dataHit ?? deepest; cur; cur = parent.get(cur) ?? null) steps.unshift(cur); + return { steps, reachesData: !!dataHit }; + }; + for (const n of baseNodes) { + if (n.type !== 'ApiEndpoint') continue; + const t = trace(n.id, 8); + if (t.steps.length > 1) flows.push({ id: `flow:${slugify(n.id)}`, name: n.name, kind: 'request', steps: t.steps, reachesData: t.reachesData }); + n.metadata.flowSteps = t.steps.length; + } + for (const ep of entryPoints.slice(0, 20)) { + const main = (symbolsByFile.get(ep.nodeId) ?? []).find((s) => s.name === 'main' || s.name === 'start' || s.name === 'bootstrap' || s.name === 'run'); + const start = main?.id ?? ep.nodeId; + const t = trace(start, 6); + if (t.steps.length > 1) flows.push({ id: `flow:${slugify(start)}`, name: `Startup: ${ep.path}`, kind: 'startup', steps: t.steps, reachesData: t.reachesData }); + } + + return { nodes, edges, entryPoints, flows }; +} diff --git a/packages/repository-indexer/src/pipeline.ts b/packages/repository-indexer/src/pipeline.ts new file mode 100644 index 0000000..4b64210 --- /dev/null +++ b/packages/repository-indexer/src/pipeline.ts @@ -0,0 +1,217 @@ +/** + * The indexing pipeline: discovery → syntax analysis → relationship + * resolution → execution flows → semantic organisation → graph generation. + * Persistence (stage 7) is done by the caller with the returned result. + */ +import path from 'node:path'; +import { type RepositoryAnalysis, assignCommunities } from '@vectora/graph-engine'; +import { type KnowledgeGraph, SCHEMA_VERSION, computeStats, isSymbolType, normalizeGraph, validateGraph } from '@vectora/graph-schema'; +import { type FileFacts, type SourceFileInput, SUPPORTED_LANGUAGES, createAdapters, languageName, languageTier } from '@vectora/language-adapters'; +import type { IndexStage, IndexSummary } from '@vectora/shared'; +import { readManifests } from './manifests'; +import { organize } from './organize'; +import { resolveGraph } from './resolve'; +import { type ScannedFile, scanRepository } from './scan'; +import { type AnalyzeTask, runTasks } from './workers'; + +export interface IndexOptions { + repositoryId: string; + repositoryName: string; + rootDir: string; + ignorePatterns?: string[]; + maxFileSizeBytes?: number; + maxFiles?: number; + disabledLanguages?: string[]; + concurrency?: number; + /** Cached facts from the previous run, keyed by path. Enables incremental indexing. */ + previous?: Map; + inProcess?: boolean; + pythonCommand?: string; + onProgress?: (stage: IndexStage, message: string, processed: number, total: number) => void; +} + +export interface IndexResult { + graph: KnowledgeGraph; + analysis: RepositoryAnalysis; + facts: { path: string; hash: string; facts: FileFacts }[]; +} + +const TREE_SITTER_BATCH = 150; + +export async function indexRepository(opts: IndexOptions): Promise { + const started = Date.now(); + const progress = opts.onProgress ?? (() => undefined); + const rootDir = path.resolve(opts.rootDir); + + // ---- Stage 1: discovery ------------------------------------------------- + progress('discover', 'Scanning files', 0, 0); + const scan = await scanRepository(rootDir, { + ignorePatterns: opts.ignorePatterns, + maxFileSizeBytes: opts.maxFileSizeBytes, + maxFiles: opts.maxFiles, + disabledLanguages: opts.disabledLanguages, + onProgress: (p, t) => progress('discover', 'Reading files', p, t), + }); + const files = scan.files; + // A `.h` file is treated as C++ when the repository contains C++ sources. + if (files.some((f) => f.language === 'cpp')) for (const f of files) if (f.language === 'c' && f.path.endsWith('.h')) f.language = 'cpp'; + const manifests = readManifests(rootDir, files); + progress('discover', `${files.length} files`, files.length, files.length); + + // ---- Stage 2: syntax analysis ------------------------------------------ + const adapters = createAdapters(); + const adapterOf = (lang: string) => adapters.find((a) => a.languages.some((l) => l.id === lang)); + const previous = opts.previous ?? new Map(); + const facts = new Map(); + const byAdapter = new Map(); + for (const f of files) { + if (!f.analyzable || !f.language) continue; + const a = adapterOf(f.language); + if (!a) continue; + (byAdapter.get(a.id) ?? byAdapter.set(a.id, []).get(a.id)!).push(f); + } + const toInput = (f: ScannedFile): SourceFileInput => ({ path: f.path, absPath: f.absPath, language: f.language! }); + const currentPaths = new Set(files.map((f) => f.path)); + const tasks: AnalyzeTask[] = []; + let reused = 0; + + for (const [adapterId, list] of byAdapter) { + const adapter = adapters.find((a) => a.id === adapterId)!; + const unchanged = (f: ScannedFile) => { + const prev = previous.get(f.path); + return prev && prev.hash === f.hash && prev.facts.adapter === adapterId && prev.facts.language === f.language ? prev.facts : null; + }; + if (adapter.scope === 'file') { + const todo: ScannedFile[] = []; + for (const f of list) { + const cached = unchanged(f); + if (cached) { + facts.set(f.path, cached); + reused++; + } else todo.push(f); + } + const byLang = new Map(); + for (const f of todo) (byLang.get(f.language!) ?? byLang.set(f.language!, []).get(f.language!)!).push(f); + for (const group of byLang.values()) + for (let i = 0; i < group.length; i += TREE_SITTER_BATCH) tasks.push({ adapterId, files: group.slice(i, i + TREE_SITTER_BATCH).map(toInput) }); + } else { + // Project-scope adapter: a file must be re-analysed when it changed or + // when anything it resolved into changed, appeared or disappeared. + const changed = new Set(); + for (const f of list) if (!unchanged(f)) changed.add(f.path); + const removed = new Set(); + for (const p of previous.keys()) if (!currentPaths.has(p)) removed.add(p); + const added = list.some((f) => !previous.has(f.path)); + const reanalyze = new Set(changed); + if (changed.size || removed.size) { + for (const f of list) { + if (reanalyze.has(f.path)) continue; + const prev = previous.get(f.path)!.facts; + const touches = (p: string | null | undefined) => !!p && (changed.has(p) || removed.has(p)); + const dependsOnChange = + prev.imports.some((i) => touches(i.resolvedPath) || (added && !i.resolvedPath && !i.builtin)) || + prev.references.some((r) => ('resolved' in r.target ? touches(r.target.resolved.path) : added)); + if (dependsOnChange) reanalyze.add(f.path); + } + } + for (const f of list) { + if (!reanalyze.has(f.path)) { + facts.set(f.path, previous.get(f.path)!.facts); + reused++; + } + } + if (reanalyze.size) tasks.push({ adapterId, files: list.map(toInput), analyzeOnly: [...reanalyze] }); + } + } + + const toAnalyze = tasks.reduce((a, t) => a + (t.analyzeOnly?.length ?? t.files.length), 0); + progress('analyze', toAnalyze ? `Analysing ${toAnalyze} files` : 'All files unchanged', 0, toAnalyze); + const run = await runTasks( + tasks, + { rootDir, allFiles: files.map((f) => f.path), workspacePackages: manifests.workspacePackages, pythonCommand: opts.pythonCommand }, + { concurrency: opts.concurrency ?? 4, inProcess: opts.inProcess, onProgress: (p, t) => progress('analyze', `Analysing ${t} files`, p, t) }, + ); + for (const ff of run.facts) facts.set(ff.path, ff); + + // ---- Stage 3: relationship resolution ---------------------------------- + progress('resolve', 'Resolving relationships', 0, 0); + const resolved = resolveGraph({ repositoryId: opts.repositoryId, repositoryName: opts.repositoryName, files, facts, manifests }); + + // ---- Stages 4–5: execution flows and semantic organisation ------------- + progress('flows', 'Tracing execution flows', 0, 0); + const organized = organize(opts.repositoryId, opts.repositoryName, resolved.nodes, resolved.edges, manifests); + progress('organize', `${organized.nodes.length} subsystems and concepts`, 0, 0); + + // ---- Stage 6: graph generation ----------------------------------------- + progress('graph', 'Validating graph', 0, 0); + const normalized = normalizeGraph([...resolved.nodes, ...organized.nodes], [...resolved.edges, ...organized.edges]); + const communities = assignCommunities(normalized.nodes, normalized.edges); + const validation = validateGraph(normalized, { checkSchema: normalized.nodes.length <= 20000 }); + const stats = computeStats(normalized.nodes, normalized.edges, resolved.unresolvedCount); + const generatedAt = new Date().toISOString(); + const graph: KnowledgeGraph = { schemaVersion: SCHEMA_VERSION, repositoryId: opts.repositoryId, generatedAt, nodes: normalized.nodes, edges: normalized.edges, stats }; + + // ---- language coverage -------------------------------------------------- + const cov = new Map(); + for (const f of files) { + const lang = f.language ?? 'other'; + let c = cov.get(lang); + if (!c) { + const adapter = f.language ? adapterOf(f.language) : undefined; + c = { language: lang, name: lang === 'other' ? 'Other' : languageName(lang), tier: languageTier(lang), files: 0, analyzedFiles: 0, symbols: 0, parseErrors: 0, adapter: adapter && f.analyzable ? adapter.technique : null, lines: 0 }; + cov.set(lang, c); + } + c.files++; + c.lines += f.lineCount; + const ff = facts.get(f.path); + if (ff) { + if (!ff.errors.some((e) => e.severity === 'error')) c.analyzedFiles++; + c.symbols += ff.symbols.length; + c.parseErrors += ff.errors.length; + } + } + const parseIssues: RepositoryAnalysis['parseIssues'] = []; + for (const ff of facts.values()) for (const e of ff.errors) if (parseIssues.length < 200) parseIssues.push(e); + + const summary: IndexSummary = { + files: files.length, + analyzedFiles: toAnalyze, + reusedFiles: reused, + symbols: normalized.nodes.filter((n) => isSymbolType(n.type)).length, + relationships: normalized.edges.length, + unresolved: resolved.unresolvedCount, + parseErrors: parseIssues.length, + durationMs: Date.now() - started, + incremental: previous.size > 0, + }; + const analysis: RepositoryAnalysis = { + generatedAt, + description: manifests.description, + descriptionSource: manifests.descriptionSource, + languages: [...cov.values()].sort((a, b) => (b.tier > 0 ? 1 : 0) - (a.tier > 0 ? 1 : 0) || b.files - a.files), + frameworks: manifests.frameworks, + entryPoints: organized.entryPoints, + flows: organized.flows, + declaredDependencies: manifests.dependencies.map((d) => ({ name: d.name, version: d.version, manifest: d.manifest, ecosystem: d.ecosystem, dev: d.dev, line: d.line })), + unresolvedCount: resolved.unresolvedCount, + unresolvedByReason: resolved.unresolvedByReason, + unresolvedSamples: resolved.unresolved.slice(0, 500), + validation: { errors: validation.errorCount, warnings: validation.warningCount, issues: validation.issues.slice(0, 50) }, + normalization: { removedNodes: normalized.removedNodes, mergedEdges: normalized.mergedEdges, droppedEdges: normalized.droppedEdges }, + skipped: scan.skipped, + truncated: scan.truncated, + parseIssues, + communities, + summary, + }; + progress('graph', `${graph.nodes.length} nodes, ${graph.edges.length} relationships`, 1, 1); + + const hashOf = new Map(files.map((f) => [f.path, f.hash])); + return { + graph, + analysis, + facts: [...facts.values()].map((ff) => ({ path: ff.path, hash: hashOf.get(ff.path) ?? '', facts: ff })), + }; +} + +export const supportedLanguages = () => SUPPORTED_LANGUAGES; diff --git a/packages/repository-indexer/src/resolve.ts b/packages/repository-indexer/src/resolve.ts new file mode 100644 index 0000000..b4c8de0 --- /dev/null +++ b/packages/repository-indexer/src/resolve.ts @@ -0,0 +1,705 @@ +/** + * Stage 3 — relationship resolution. + * + * Turns per-file facts into graph nodes and edges. A name is only tied to a + * definition when there is scope evidence for it (same file, an import that + * leads to the defining file, or a language-defined visibility rule such as + * "same package"). Everything else is reported as unresolved, never guessed. + */ +import path from 'node:path'; +import { + type EdgeType, + type ExtractionMethod, + type GraphEdge, + type GraphNode, + type NodeType, + type SourceLocation, + type UnresolvedReference, + edgeId, + nodeId, +} from '@vectora/graph-schema'; +import type { FileFacts, ImportFact, ReferenceFact, SymbolFact } from '@vectora/language-adapters'; +import { type ManifestInfo, isConfigFile, isTestFile } from './manifests'; +import type { ScannedFile } from './scan'; + +export interface ResolveInput { + repositoryId: string; + repositoryName: string; + files: ScannedFile[]; + facts: Map; + manifests: ManifestInfo; +} + +export interface ResolveOutput { + nodes: GraphNode[]; + edges: GraphEdge[]; + unresolved: UnresolvedReference[]; + unresolvedCount: number; + unresolvedByReason: Record; +} + +interface Binding { + /** Candidate files (one for a module, several for a package / namespace). */ + files: string[]; + /** Symbol inside the first file, or null when the binding is the module itself. */ + localId: string | null; +} + +interface FileCtx { + facts: FileFacts; + top: Map; + byLocal: Map; + bindings: Map; + visible: string[]; + /** Local names bound to something outside the repository (external package or standard library). */ + external: Set; +} + +interface Target { + path: string; + localId: string | null; + kind: NodeType | null; + method: ExtractionMethod; + confidence: number; + verified: boolean; +} + +const MAX_UNRESOLVED_SAMPLES = 2000; +const CLASS_KINDS: ReadonlySet = new Set(['Class', 'DatabaseModel', 'Component', 'Interface', 'Type']); +const SELF_NAMES = new Set(['self', 'this', 'cls', 'Self', 'super', 'base']); +const PY_STDLIB = new Set( + ('abc argparse array ast asyncio base64 bisect builtins calendar collections concurrent configparser contextlib copy csv ctypes dataclasses datetime ' + + 'decimal difflib dis email enum errno functools gc getpass glob gzip hashlib heapq hmac html http importlib inspect io ipaddress itertools json ' + + 'logging math mimetypes multiprocessing operator os pathlib pickle platform pprint queue random re secrets select shlex shutil signal socket ' + + 'sqlite3 ssl stat string struct subprocess sys tempfile textwrap threading time timeit tkinter traceback types typing unittest urllib uuid ' + + 'warnings weakref xml zipfile zlib zoneinfo __future__ typing_extensions').split(' '), +); + +const dirOf = (p: string): string => (p.includes('/') ? p.slice(0, p.lastIndexOf('/')) : ''); +const baseOf = (p: string): string => p.slice(p.lastIndexOf('/') + 1); +const stemOf = (p: string): string => p.replace(/\.[^./]+$/, ''); + +export function resolveGraph(input: ResolveInput): ResolveOutput { + const { repositoryId, files, facts, manifests } = input; + const nodes: GraphNode[] = []; + const edges: GraphEdge[] = []; + const nodeIds = new Set(); + const unresolved: UnresolvedReference[] = []; + const unresolvedByReason: Record = {}; + let unresolvedCount = 0; + + const addNode = (n: Omit): void => { + if (nodeIds.has(n.id)) return; + nodeIds.add(n.id); + nodes.push({ ...n, repositoryId }); + }; + const addEdge = ( + type: EdgeType, + source: string, + target: string, + evidence: string, + location: SourceLocation | null, + method: ExtractionMethod, + confidence = 1, + verified = true, + metadata?: Record, + ): void => { + edges.push({ id: edgeId(type, source, target), source, target, type, evidence, location, extractionMethod: method, confidence, verified, ...(metadata ? { metadata } : {}) }); + }; + const reportUnresolved = (fromPath: string, fromSymbol: string | null, kind: EdgeType, name: string, line: number, reason: string): void => { + unresolvedCount++; + unresolvedByReason[reason] = (unresolvedByReason[reason] ?? 0) + 1; + if (unresolved.length < MAX_UNRESOLVED_SAMPLES) unresolved.push({ fromPath, fromSymbol, kind, name, line, reason }); + }; + + // ---- structure: repository, directories, files ------------------------- + const repoId = nodeId.repository(); + addNode({ + id: repoId, + name: input.repositoryName, + type: 'Repository', + filePath: null, + location: null, + language: null, + description: manifests.description ?? undefined, + metadata: { files: files.length }, + extractionMethod: 'filesystem', + confidence: 1, + verified: true, + }); + + const fileSet = new Set(files.map((f) => f.path)); + const filesByDir = new Map(); + const filesByBase = new Map(); + const packageDirs = new Set([ + ...manifests.workspacePackages.map((p) => p.dir), + ...manifests.goModules.map((m) => m.dir), + ...manifests.cargoCrates.map((c) => c.dir), + ]); + for (const f of files) { + const d = dirOf(f.path); + (filesByDir.get(d) ?? filesByDir.set(d, []).get(d)!).push(f.path); + const b = baseOf(f.path); + (filesByBase.get(b) ?? filesByBase.set(b, []).get(b)!).push(f.path); + if (/^(__init__\.py|mod\.rs|index\.[cm]?[jt]sx?)$/.test(b)) packageDirs.add(d); + } + + const ensureDir = (dir: string): string => { + if (dir === '') return repoId; + const id = nodeId.directory(dir); + if (nodeIds.has(id)) return id; + const isModule = packageDirs.has(dir); + addNode({ + id, + name: baseOf(dir), + type: isModule ? 'Module' : 'Directory', + filePath: dir, + location: null, + language: null, + metadata: {}, + extractionMethod: 'filesystem', + confidence: 1, + verified: true, + }); + const parent = ensureDir(dirOf(dir)); + addEdge('CONTAINS', parent, id, `${dir}/`, null, 'filesystem'); + return id; + }; + + for (const f of files) { + const ff = facts.get(f.path); + const config = isConfigFile(f.path); + const id = nodeId.file(f.path); + addNode({ + id, + name: baseOf(f.path), + type: config ? 'Configuration' : 'File', + filePath: f.path, + location: { path: f.path, startLine: 1, endLine: Math.max(1, f.lineCount) }, + language: f.language, + metadata: { + size: f.size, + lines: f.lineCount, + hash: f.hash, + analyzed: !!ff && !ff.errors.some((e) => e.severity === 'error'), + adapter: ff?.adapter ?? null, + parseErrors: ff?.errors.length ?? 0, + ...(ff?.moduleName ? { moduleName: ff.moduleName } : {}), + ...(isTestFile(f.path) ? { test: true } : {}), + }, + extractionMethod: 'filesystem', + confidence: 1, + verified: true, + }); + addEdge('CONTAINS', ensureDir(dirOf(f.path)), id, f.path, null, 'filesystem'); + } + + // ---- symbols ------------------------------------------------------------ + const ctxs = new Map(); + const byModuleName = new Map(); + const pySuffix = new Map(); + for (const [p, ff] of facts) { + if (!fileSet.has(p)) continue; + const top = new Map(); + const byLocal = new Map(); + const fileId = nodeId.file(p); + for (const s of ff.symbols) { + byLocal.set(s.localId, s); + if (!s.parent && s.kind !== 'ApiEndpoint' && !top.has(s.name)) top.set(s.name, s.localId); + } + for (const s of ff.symbols) { + const id = nodeId.symbol(p, s.localId); + addNode({ + id, + name: s.name, + type: s.kind, + filePath: p, + location: s.location, + language: ff.language, + description: s.description, + metadata: { ...(s.metadata ?? {}), qualifiedName: s.localId, exported: s.exported }, + extractionMethod: ff.adapter === 'typescript' ? 'typescript-compiler' : ff.adapter === 'python' ? 'python-ast' : 'tree-sitter', + confidence: 1, + verified: true, + }); + const parentId = s.parent && byLocal.has(s.parent) ? nodeId.symbol(p, s.parent) : fileId; + const ev = `${s.name} declared at ${p}:${s.location.startLine}`; + addEdge('CONTAINS', parentId, id, ev, s.location, 'filesystem'); + if (parentId !== fileId) addEdge('DEFINED_IN', id, fileId, ev, s.location, 'filesystem'); + else if (s.exported && s.kind !== 'ApiEndpoint') addEdge('EXPORTS', fileId, id, `${s.name} is exported from ${p}`, s.location, nodes[nodes.length - 1]!.extractionMethod); + } + ctxs.set(p, { facts: ff, top, byLocal, bindings: new Map(), visible: [], external: new Set() }); + if (ff.moduleName) { + (byModuleName.get(`${ff.language}:${ff.moduleName}`) ?? byModuleName.set(`${ff.language}:${ff.moduleName}`, []).get(`${ff.language}:${ff.moduleName}`)!).push(p); + if (ff.language === 'python') { + const parts = ff.moduleName.split('.'); + for (let i = 0; i < parts.length; i++) { + const suffix = parts.slice(i).join('.'); + (pySuffix.get(suffix) ?? pySuffix.set(suffix, []).get(suffix)!).push(p); + } + } + } + } + + // ---- packages ----------------------------------------------------------- + const declared = new Map(); + for (const d of manifests.dependencies) if (!declared.has(d.name)) declared.set(d.name, d); + const ensurePackage = (name: string, ecosystem: string): string => { + const id = nodeId.pkg(name); + if (!nodeIds.has(id)) { + const dep = declared.get(name) ?? declared.get(name.replace(/_/g, '-')); + addNode({ + id, + name, + type: 'Package', + filePath: null, + location: null, + language: null, + metadata: { external: true, declared: !!dep, version: dep?.version ?? null, ecosystem: dep?.ecosystem ?? ecosystem, dev: dep?.dev ?? false }, + extractionMethod: dep ? 'manifest' : 'filesystem', + confidence: 1, + verified: true, + }); + } + return id; + }; + for (const d of manifests.dependencies) { + const pkgId = ensurePackage(d.name, d.ecosystem); + const manifestId = nodeId.file(d.manifest); + if (nodeIds.has(manifestId)) + addEdge('DEPENDS_ON', manifestId, pkgId, d.evidence, { path: d.manifest, startLine: d.line, endLine: d.line }, 'manifest', 1, true, { dev: d.dev, version: d.version }); + } + + // ---- imports ------------------------------------------------------------ + const bind = (ctx: FileCtx, local: string, b: Binding) => { + if (local && local !== '*' && !ctx.bindings.has(local)) ctx.bindings.set(local, b); + }; + const symbolIn = (filesList: string[], name: string): { path: string; localId: string } | null => { + let hit: { path: string; localId: string } | null = null; + for (const f of filesList) { + const l = ctxs.get(f)?.top.get(name); + if (l) { + if (hit) return null; // ambiguous + hit = { path: f, localId: l }; + } + } + return hit; + }; + const closest = (from: string, candidates: string[]): string | null => { + if (candidates.length === 0) return null; + if (candidates.length === 1) return candidates[0]!; + const fromParts = dirOf(from).split('/'); + let best: string | null = null; + let bestScore = -1; + let tie = false; + for (const c of candidates) { + const parts = dirOf(c).split('/'); + let i = 0; + while (i < parts.length && i < fromParts.length && parts[i] === fromParts[i]) i++; + if (i > bestScore) { + best = c; + bestScore = i; + tie = false; + } else if (i === bestScore) tie = true; + } + return tie ? null : best; + }; + + const importEdge = (from: string, target: string, imp: ImportFact, method: ExtractionMethod, confidence = 1, verified = true) => { + const targetId = fileSet.has(target) ? nodeId.file(target) : nodeIds.has(nodeId.directory(target)) ? nodeId.directory(target) : null; + if (!targetId) return; + addEdge('IMPORTS', nodeId.file(from), targetId, imp.evidence, imp.location, method, confidence, verified, { specifier: imp.specifier, kind: imp.kind }); + }; + const externalImport = (from: string, pkg: string, ecosystem: string, imp: ImportFact, method: ExtractionMethod) => { + markExternal(from, imp); + addEdge('IMPORTS', nodeId.file(from), ensurePackage(pkg, ecosystem), imp.evidence, imp.location, method, 1, true, { specifier: imp.specifier, external: true }); + }; + const fileNodeIndex = new Map(); + for (const n of nodes) if (n.type === 'File' || n.type === 'Configuration') fileNodeIndex.set(n.id, n); + const markExternal = (from: string, imp: ImportFact) => { + const c = ctxs.get(from); + if (!c) return; + for (const n of imp.names) if (n.local && n.local !== '*') c.external.add(n.local); + // `import a.b.c` binds the top-level name `a`. + if (c.facts.language === 'python' && !imp.specifier.startsWith('.')) c.external.add(imp.specifier.split('.')[0]!); + }; + const noteBuiltinFast = (from: string, name: string, imp?: ImportFact) => { + if (imp) markExternal(from, imp); + const node = fileNodeIndex.get(nodeId.file(from)); + if (!node) return; + const list = ((node.metadata.builtinImports as string[] | undefined) ??= []); + if (!list.includes(name) && list.length < 50) list.push(name); + }; + + const rustCrateRoot = (file: string): string | null => { + let best: string | null = null; + for (const c of manifests.cargoCrates) if ((c.dir === '' || file.startsWith(`${c.dir}/`)) && (best === null || c.dir.length > best.length)) best = c.dir; + if (best !== null) return best === '' ? 'src' : `${best}/src`; + const i = file.lastIndexOf('/src/'); + return i === -1 ? (file.startsWith('src/') ? 'src' : null) : file.slice(0, i + 4); + }; + const rustFile = (root: string, segs: string[]): string | null => { + if (segs.length === 0) return [`${root}/lib.rs`, `${root}/main.rs`].find((f) => fileSet.has(f)) ?? null; + const base = `${root}/${segs.join('/')}`; + return [`${base}.rs`, `${base}/mod.rs`].find((f) => fileSet.has(f)) ?? null; + }; + + for (const [p, ctx] of ctxs) { + const lang = ctx.facts.language; + for (const imp of ctx.facts.imports) { + // --- TypeScript / JavaScript: the adapter already resolved the import + if (ctx.facts.adapter === 'typescript') { + if (imp.resolvedPath) { + importEdge(p, imp.resolvedPath, imp, 'typescript-compiler'); + if (imp.kind === 'reexport') { + const tctx = ctxs.get(imp.resolvedPath); + for (const n of imp.names) { + const l = n.imported !== '*' ? tctx?.top.get(n.imported) : undefined; + if (l) addEdge('EXPORTS', nodeId.file(p), nodeId.symbol(imp.resolvedPath, l), imp.evidence, imp.location, 'typescript-compiler', 1, true, { reexport: true }); + } + } + } else if (imp.externalPackage) { + if (imp.builtin) noteBuiltinFast(p, imp.externalPackage, imp); + else externalImport(p, imp.externalPackage, 'npm', imp, 'typescript-compiler'); + } else reportUnresolved(p, null, 'IMPORTS', imp.specifier, imp.location.startLine, 'import target not found in repository'); + continue; + } + + if (lang === 'python') { + const level = /^\.*/.exec(imp.specifier)![0].length; + const rest = imp.specifier.slice(level); + const moduleFile = (dotted: string): string | null => { + if (level > 0) { + let dir = dirOf(p); + for (let i = 1; i < level; i++) dir = dirOf(dir); + const base = dotted ? path.posix.join(dir, dotted.replace(/\./g, '/')) : dir; + return [`${base}.py`, `${base}/__init__.py`, `${base}.pyi`].find((f) => fileSet.has(f)) ?? null; + } + return dotted ? closest(p, pySuffix.get(dotted) ?? []) : null; + }; + const mod = moduleFile(rest); + let linked = false; + for (const n of imp.names) { + if (n.imported === '*' && !imp.specifier.startsWith('.') && imp.names.length === 1 && n.local !== '*') { + // `import a.b.c [as x]` + if (mod) { + bind(ctx, n.local === rest.split('.')[0] ? rest : n.local, { files: [mod], localId: null }); + bind(ctx, rest, { files: [mod], localId: null }); + } + continue; + } + if (n.imported === '*') { + if (mod) ctx.visible.push(mod); + continue; + } + const sub = moduleFile(rest ? `${rest}.${n.imported}` : n.imported); + if (sub) { + bind(ctx, n.local, { files: [sub], localId: null }); + importEdge(p, sub, imp, 'scope-resolution'); + linked = true; + } else if (mod) { + const l = ctxs.get(mod)?.top.get(n.imported) ?? null; + bind(ctx, n.local, { files: [mod], localId: l }); + } + } + if (mod) importEdge(p, mod, imp, 'scope-resolution'); + else if (!linked) { + const topName = rest.split('.')[0] ?? ''; + if (level > 0 || !topName) reportUnresolved(p, null, 'IMPORTS', imp.specifier, imp.location.startLine, 'import target not found in repository'); + else if (PY_STDLIB.has(topName)) noteBuiltinFast(p, topName, imp); + else externalImport(p, declared.has(topName.toLowerCase()) ? topName.toLowerCase() : topName, 'pypi', imp, 'python-ast'); + } + continue; + } + + if (lang === 'java') { + const wildcard = imp.specifier.endsWith('.*'); + const full = wildcard ? imp.specifier.slice(0, -2) : imp.specifier; + const pkg = wildcard ? full : full.slice(0, full.lastIndexOf('.')); + const name = wildcard ? '*' : full.slice(full.lastIndexOf('.') + 1); + let pkgFiles = byModuleName.get(`java:${pkg}`) ?? []; + let symName = name; + if (pkgFiles.length === 0 && !wildcard && pkg.includes('.')) { + // static import `a.b.C.member` + pkgFiles = byModuleName.get(`java:${pkg.slice(0, pkg.lastIndexOf('.'))}`) ?? []; + symName = pkg.slice(pkg.lastIndexOf('.') + 1); + } + if (pkgFiles.length) { + if (wildcard) { + ctx.visible.push(...pkgFiles); + for (const f of pkgFiles.slice(0, 25)) importEdge(p, f, imp, 'scope-resolution'); + } else { + const hit = symbolIn(pkgFiles, symName); + if (hit) { + bind(ctx, symName, { files: [hit.path], localId: hit.localId }); + importEdge(p, hit.path, imp, 'scope-resolution'); + } else reportUnresolved(p, null, 'IMPORTS', imp.specifier, imp.location.startLine, 'imported name not found in package'); + } + } else if (/^(java|javax|jdk|sun)\./.test(full)) noteBuiltinFast(p, full.split('.').slice(0, 2).join('.'), imp); + else externalImport(p, full.split('.').slice(0, 2).join('.'), 'maven', imp, 'tree-sitter'); + continue; + } + + if (lang === 'go') { + const mod = manifests.goModules.find((m) => imp.specifier === m.module || imp.specifier.startsWith(`${m.module}/`)); + if (mod) { + const dir = path.posix.join(mod.dir, imp.specifier.slice(mod.module.length)).replace(/^\/|\/$/g, ''); + const pkgFiles = (filesByDir.get(dir) ?? []).filter((f) => f.endsWith('.go')); + if (pkgFiles.length) { + for (const n of imp.names) bind(ctx, n.local, { files: pkgFiles, localId: null }); + importEdge(p, dir, imp, 'scope-resolution'); + } else reportUnresolved(p, null, 'IMPORTS', imp.specifier, imp.location.startLine, 'import target not found in repository'); + } else if (!imp.specifier.split('/')[0]!.includes('.')) noteBuiltinFast(p, imp.specifier, imp); + else externalImport(p, imp.specifier.split('/').slice(0, 3).join('/'), 'go', imp, 'tree-sitter'); + continue; + } + + if (lang === 'rust') { + const segs = imp.specifier.split('::').filter(Boolean); + const root = rustCrateRoot(p); + const n = imp.names[0] ?? { imported: '*', local: '*' }; + if (!root || segs.length === 0) continue; + const rel = p.slice(root.length + 1).replace(/\.rs$/, '').split('/'); + const cur = ['lib', 'main', 'mod'].includes(rel[rel.length - 1]!) ? rel.slice(0, -1) : rel; + let abs: string[] | null = null; + if (segs[0] === 'crate') abs = segs.slice(1); + else if (segs[0] === 'self') abs = [...cur, ...segs.slice(1)]; + else if (segs[0] === 'super') { + let base = cur.slice(0, -1); + let i = 1; + while (segs[i] === 'super') { + base = base.slice(0, -1); + i++; + } + abs = [...base, ...segs.slice(i)]; + } else if (rustFile(root, [...cur, segs[0]!])) abs = [...cur, ...segs]; + else if (rustFile(root, [segs[0]!])) abs = segs; + if (abs) { + const path0 = n.imported === '*' ? abs : abs; + let done = false; + for (let k = path0.length; k >= 0 && !done; k--) { + const file = rustFile(root, path0.slice(0, k)); + if (!file) continue; + const remaining = path0.slice(k); + if (n.imported === '*' && imp.specifier.endsWith('*')) ctx.visible.push(file); + else if (remaining.length === 0) bind(ctx, n.local, { files: [file], localId: null }); + else bind(ctx, n.local, { files: [file], localId: ctxs.get(file)?.top.get(remaining[0]!) ?? null }); + if (file !== p) importEdge(p, file, imp, 'scope-resolution'); + done = true; + } + if (!done) reportUnresolved(p, null, 'IMPORTS', imp.specifier, imp.location.startLine, 'import target not found in repository'); + } else if (['std', 'core', 'alloc'].includes(segs[0]!)) noteBuiltinFast(p, segs[0]!, imp); + else { + const crate = segs[0]!; + externalImport(p, declared.has(crate) ? crate : declared.has(crate.replace(/_/g, '-')) ? crate.replace(/_/g, '-') : crate, 'cargo', imp, 'tree-sitter'); + } + continue; + } + + if (lang === 'c' || lang === 'cpp') { + if (imp.externalPackage) { + noteBuiltinFast(p, imp.externalPackage, imp); + continue; + } + const rel = path.posix.normalize(path.posix.join(dirOf(p), imp.specifier)); + let target = fileSet.has(rel) ? rel : null; + if (!target) { + const cands = (filesByBase.get(baseOf(imp.specifier)) ?? []).filter((f) => f.endsWith(imp.specifier.replace(/^(\.\.?\/)+/, ''))); + target = closest(p, cands) ?? (cands.length === 1 ? cands[0]! : null); + } + if (target) { + ctx.visible.push(target); + importEdge(p, target, imp, 'scope-resolution'); + } else reportUnresolved(p, null, 'IMPORTS', imp.specifier, imp.location.startLine, 'included file not found in repository'); + continue; + } + + if (lang === 'csharp') { + const nsFiles = byModuleName.get(`csharp:${imp.specifier}`) ?? []; + if (nsFiles.length) { + ctx.visible.push(...nsFiles); + for (const f of nsFiles.slice(0, 25)) if (f !== p) importEdge(p, f, imp, 'scope-resolution'); + } else if (/^(System|Microsoft)(\.|$)/.test(imp.specifier)) noteBuiltinFast(p, imp.specifier, imp); + else externalImport(p, imp.specifier.split('.').slice(0, 2).join('.'), 'nuget', imp, 'tree-sitter'); + } + } + + // Language visibility rules: same package (Java, Go) or namespace (C#). + if ((lang === 'java' || lang === 'csharp') && ctx.facts.moduleName) ctx.visible.push(...(byModuleName.get(`${lang}:${ctx.facts.moduleName}`) ?? []).filter((f) => f !== p)); + if (lang === 'go') ctx.visible.push(...(filesByDir.get(dirOf(p)) ?? []).filter((f) => f !== p && f.endsWith('.go') && ctxs.get(f)?.facts.moduleName === ctx.facts.moduleName)); + } + + // ---- references --------------------------------------------------------- + const kindOf = (pth: string, localId: string | null): NodeType | null => (localId ? (ctxs.get(pth)?.byLocal.get(localId)?.kind ?? null) : null); + const mk = (pth: string, localId: string | null, method: ExtractionMethod, confidence: number, verified: boolean): Target => ({ + path: pth, + localId, + kind: kindOf(pth, localId), + method, + confidence, + verified, + }); + + /** Resolves an unqualified name from the point of view of one file. */ + const lookupName = (p: string, ctx: FileCtx, name: string): Target | { reason: string } => { + const own = ctx.top.get(name); + if (own) return mk(p, own, 'scope-resolution', 0.95, true); + const b = ctx.bindings.get(name); + if (b) { + if (b.localId) return mk(b.files[0]!, b.localId, 'scope-resolution', 0.9, true); + if (b.files.length === 1) return mk(b.files[0]!, null, 'scope-resolution', 0.9, true); + } + if (ctx.visible.length) { + const matches: { path: string; localId: string }[] = []; + for (const f of ctx.visible) { + const l = ctxs.get(f)?.top.get(name); + if (l) matches.push({ path: f, localId: l }); + } + if (matches.length > 1) { + // A prototype in a header and its definition are the same entity: prefer the definition. + const defs = matches.filter((m) => !ctxs.get(m.path)?.byLocal.get(m.localId)?.metadata?.declarationOnly); + if (defs.length === 1) return mk(defs[0]!.path, defs[0]!.localId, 'name-resolution', 0.7, false); + return { reason: 'ambiguous name (several visible definitions)' }; + } + if (matches.length === 1) { + let m = matches[0]!; + const sym = ctxs.get(m.path)?.byLocal.get(m.localId); + if (sym?.metadata?.declarationOnly) { + // Look for the definition next to the header (util.h -> util.c / util.cpp). + const stem = stemOf(m.path); + const impl = ['.c', '.cc', '.cpp', '.cxx'].map((e) => stem + e).find((f) => ctxs.get(f)?.top.has(name)); + if (impl) m = { path: impl, localId: ctxs.get(impl)!.top.get(name)! }; + } + return mk(m.path, m.localId, 'name-resolution', 0.7, false); + } + } + return { reason: 'no definition found in scope (external, built-in or dynamic)' }; + }; + + /** Resolves `a.b.c` / `a::b` to a symbol or module by walking imports. */ + const lookupDotted = (p: string, ctx: FileCtx, dotted: string): Target | null => { + const whole = ctx.bindings.get(dotted); + if (whole) return whole.localId ? mk(whole.files[0]!, whole.localId, 'scope-resolution', 0.9, true) : whole.files.length === 1 ? mk(whole.files[0]!, null, 'scope-resolution', 0.9, true) : null; + const parts = dotted.split(/\.|::/).filter(Boolean); + if (parts.length === 0) return null; + let cur: Target | null = null; + let files: string[] | null = null; + const first = lookupName(p, ctx, parts[0]!); + if ('reason' in first) { + const b = ctx.bindings.get(parts[0]!); + if (!b) return null; + files = b.files; + } else cur = first; + for (let i = 1; i < parts.length; i++) { + const part = parts[i]!; + if (cur && cur.localId === null) files = [cur.path]; + if (files) { + const hit = symbolIn(files, part); + if (!hit) return null; + cur = mk(hit.path, hit.localId, 'scope-resolution', 0.9, true); + files = null; + } else if (cur?.localId) { + const member = `${cur.localId}.${part}`; + if (!ctxs.get(cur.path)?.byLocal.has(member)) return null; + cur = mk(cur.path, member, cur.method, cur.confidence, cur.verified); + } else return null; + } + if (!cur && files) return files.length === 1 ? mk(files[0]!, null, 'scope-resolution', 0.9, true) : ({ path: files[0]!, localId: null, kind: null, method: 'scope-resolution', confidence: 0.9, verified: true, files } as Target & { files: string[] }); + return cur; + }; + + const IMPLICIT_THIS = new Set(['java', 'csharp', 'cpp']); + const enclosingType = (ctx: FileCtx, from: string | null): string | null => { + let cls = from ? (ctx.byLocal.get(from)?.parent ?? null) : null; + while (cls && !CLASS_KINDS.has(ctx.byLocal.get(cls)?.kind ?? 'Function')) cls = ctx.byLocal.get(cls)?.parent ?? null; + return cls; + }; + const resolveNamed = (p: string, ctx: FileCtx, ref: ReferenceFact, name: string, receiver: string | undefined): Target | { reason: string } | { external: true } => { + if (!receiver) { + // Languages with an implicit receiver: an unqualified call may be a member of the enclosing type. + if (IMPLICIT_THIS.has(ctx.facts.language) && ref.kind === 'CALLS') { + const cls = enclosingType(ctx, ref.from); + if (cls && ctx.byLocal.has(`${cls}.${name}`)) return mk(p, `${cls}.${name}`, 'scope-resolution', 0.9, true); + } + const r = lookupName(p, ctx, name); + if ('reason' in r && ctx.external.has(name)) return { external: true }; + return r; + } + const head = receiver.split(/\.|::/)[0]!; + if (ctx.external.has(head) && !ctx.top.has(head)) return { external: true }; + if (SELF_NAMES.has(head)) { + if (receiver !== head) return { reason: 'receiver type unknown' }; + const cls = enclosingType(ctx, ref.from); + if (cls && ctx.byLocal.has(`${cls}.${name}`)) return mk(p, `${cls}.${name}`, 'scope-resolution', 0.9, true); + return { reason: 'member not found on enclosing type (inherited or dynamic)' }; + } + const recv = lookupDotted(p, ctx, receiver); + if (!recv) return { reason: 'receiver type unknown' }; + const multi = (recv as Target & { files?: string[] }).files; + if (recv.localId === null) { + const hit = symbolIn(multi ?? [recv.path], name); + return hit ? mk(hit.path, hit.localId, 'scope-resolution', 0.9, true) : { reason: 'member not found in imported module' }; + } + if (recv.kind && CLASS_KINDS.has(recv.kind)) { + const member = `${recv.localId}.${name}`; + if (ctxs.get(recv.path)?.byLocal.has(member)) return mk(recv.path, member, recv.method, Math.min(recv.confidence, 0.9), recv.verified); + return { reason: 'member not found on type' }; + } + return { reason: 'receiver type unknown' }; + }; + + for (const [p, ctx] of ctxs) { + const fileId = nodeId.file(p); + for (const ref of ctx.facts.references) { + const fromId = ref.from && ctx.byLocal.has(ref.from) ? nodeId.symbol(p, ref.from) : fileId; + if ('resolved' in ref.target) { + const t = ref.target.resolved; + const targetId = t.localId ? nodeId.symbol(t.path, t.localId) : nodeId.file(t.path); + if (nodeIds.has(targetId)) addEdge(ref.kind, fromId, targetId, ref.evidence, ref.location, ref.method, ref.confidence, ref.verified, ref.metadata); + else reportUnresolved(p, ref.from, ref.kind, t.localId ?? t.path, ref.location.startLine, 'declaration is outside the indexed files'); + continue; + } + const { name, receiver } = ref.target; + const speculative = ref.metadata?.typeOnly === true || ref.metadata?.argument === true; + if (ctx.facts.adapter === 'typescript') { + reportUnresolved(p, ref.from, ref.kind, name, ref.location.startLine, 'no declaration found by the type checker'); + continue; + } + const result = resolveNamed(p, ctx, ref, name, receiver); + + // Data access heuristics: a call on (or passing) a known database model. + if (ref.kind === 'CALLS' && (ref.metadata?.db === 'read' || ref.metadata?.db === 'write')) { + const models = new Map(); + if (receiver) { + const parts = receiver.split('.'); + for (let i = 1; i <= parts.length; i++) { + const t = lookupDotted(p, ctx, parts.slice(0, i).join('.')); + if (t?.kind === 'DatabaseModel') models.set(`${t.path}#${t.localId}`, t); + } + } + for (const a of (ref.metadata.args as string[] | undefined) ?? []) { + const t = lookupDotted(p, ctx, a); + if (t?.kind === 'DatabaseModel') models.set(`${t.path}#${t.localId}`, t); + } + for (const t of models.values()) + addEdge(ref.metadata.db === 'read' ? 'READS_FROM' : 'WRITES_TO', fromId, nodeId.symbol(t.path, t.localId!), ref.evidence, ref.location, 'pattern', 0.7, false, { operation: name }); + } + + if ('external' in result) continue; + if ('reason' in result) { + if (!speculative) reportUnresolved(p, ref.from, ref.kind, receiver ? `${receiver}.${name}` : name, ref.location.startLine, result.reason); + continue; + } + if (speculative && result.localId === null) continue; + let kind = ref.kind; + if (kind === 'CALLS' && result.kind && (result.kind === 'Class' || result.kind === 'DatabaseModel')) kind = 'INSTANTIATES'; + if (kind === 'CALLS' && result.localId === null) continue; // a module is not callable + const targetId = result.localId ? nodeId.symbol(result.path, result.localId) : nodeId.file(result.path); + if (targetId === fromId && kind !== 'CALLS') continue; + if (!nodeIds.has(targetId)) continue; + addEdge(kind, fromId, targetId, ref.evidence, ref.location, result.method, result.confidence, result.verified, ref.metadata); + } + } + + return { nodes, edges, unresolved, unresolvedCount, unresolvedByReason }; +} diff --git a/packages/repository-indexer/src/scan.ts b/packages/repository-indexer/src/scan.ts new file mode 100644 index 0000000..6f42d31 --- /dev/null +++ b/packages/repository-indexer/src/scan.ts @@ -0,0 +1,173 @@ +/** + * Stage 1 — repository discovery: enumerate files, honour ignore rules, skip + * binary / oversized / generated content and detect languages. + */ +import { createHash } from 'node:crypto'; +import fs from 'node:fs'; +import path from 'node:path'; +import fg from 'fast-glob'; +import ignore, { type Ignore } from 'ignore'; +import { detectLanguage, isBinaryPath, languageTier, looksGenerated } from '@vectora/language-adapters'; +import { DEFAULT_IGNORE_PATTERNS } from '@vectora/shared'; + +export interface ScannedFile { + path: string; + absPath: string; + size: number; + language: string | null; + hash: string; + lineCount: number; + /** True when the file is in a language with a symbol-level adapter. */ + analyzable: boolean; +} + +export interface ScanOptions { + ignorePatterns?: string[]; + maxFileSizeBytes?: number; + maxFiles?: number; + respectGitignore?: boolean; + disabledLanguages?: string[]; + onProgress?: (processed: number, total: number) => void; +} + +export interface ScanResult { + files: ScannedFile[]; + skipped: { ignored: number; binary: number; oversized: number; generated: number; symlinks: number; unreadable: number; overLimit: number }; + truncated: boolean; +} + +/** Directories that are never worth descending into, regardless of ignore files. */ +const HARD_EXCLUDES = ['**/node_modules/**', '**/.git/**', '**/.hg/**', '**/.svn/**']; + +function loadGitignores(root: string, gitignorePaths: string[]): { dir: string; ig: Ignore }[] { + const out: { dir: string; ig: Ignore }[] = []; + for (const rel of gitignorePaths) { + try { + const content = fs.readFileSync(path.join(root, rel), 'utf8'); + const dir = rel.includes('/') ? rel.slice(0, rel.lastIndexOf('/')) : ''; + out.push({ dir, ig: ignore().add(content) }); + } catch { + // unreadable ignore file: skip it + } + } + // Parent rules first. + return out.sort((a, b) => a.dir.length - b.dir.length); +} + +export async function scanRepository(rootDir: string, opts: ScanOptions = {}): Promise { + const root = path.resolve(rootDir); + const maxSize = opts.maxFileSizeBytes ?? 512 * 1024; + const maxFiles = opts.maxFiles ?? 20000; + const skipped = { ignored: 0, binary: 0, oversized: 0, generated: 0, symlinks: 0, unreadable: 0, overLimit: 0 }; + + const entries = await fg('**/*', { + cwd: root, + dot: true, + onlyFiles: true, + followSymbolicLinks: false, + stats: true, + suppressErrors: true, + ignore: HARD_EXCLUDES, + }); + + const settingsIgnore = ignore().add(opts.ignorePatterns ?? DEFAULT_IGNORE_PATTERNS); + const gitignores = + opts.respectGitignore === false + ? [] + : loadGitignores( + root, + entries.map((e) => e.path).filter((p) => p === '.gitignore' || p.endsWith('/.gitignore')), + ); + const disabled = new Set(opts.disabledLanguages ?? []); + + const isIgnored = (rel: string): boolean => { + if (settingsIgnore.ignores(rel)) return true; + for (const g of gitignores) { + if (g.dir === '') { + if (g.ig.ignores(rel)) return true; + } else if (rel.startsWith(`${g.dir}/`)) { + if (g.ig.ignores(rel.slice(g.dir.length + 1))) return true; + } + } + return false; + }; + + const candidates: { rel: string; size: number }[] = []; + for (const e of entries) { + const rel = e.path; + if (e.stats?.isSymbolicLink() || e.dirent.isSymbolicLink()) { + skipped.symlinks++; + continue; + } + if (isIgnored(rel)) { + skipped.ignored++; + continue; + } + if (isBinaryPath(rel)) { + skipped.binary++; + continue; + } + const size = e.stats?.size ?? 0; + if (size > maxSize) { + skipped.oversized++; + continue; + } + candidates.push({ rel, size }); + } + candidates.sort((a, b) => (a.rel < b.rel ? -1 : 1)); + + let truncated = false; + let list = candidates; + if (candidates.length > maxFiles) { + truncated = true; + skipped.overLimit = candidates.length - maxFiles; + // Prefer analysable source files when the limit is hit. + const score = (p: string) => (languageTier(detectLanguage(p) ?? '') > 0 ? 0 : 1); + list = [...candidates].sort((a, b) => score(a.rel) - score(b.rel) || (a.rel < b.rel ? -1 : 1)).slice(0, maxFiles); + list.sort((a, b) => (a.rel < b.rel ? -1 : 1)); + } + + const files: ScannedFile[] = []; + let processed = 0; + for (const c of list) { + processed++; + if (processed % 200 === 0) opts.onProgress?.(processed, list.length); + const absPath = path.join(root, c.rel); + let buf: Buffer; + try { + // lstat again: the listing may be stale and we never follow links out of the tree. + if (fs.lstatSync(absPath).isSymbolicLink()) { + skipped.symlinks++; + continue; + } + buf = fs.readFileSync(absPath); + } catch { + skipped.unreadable++; + continue; + } + // Binary content without a known binary extension: NUL byte in the first 8 KB. + if (buf.subarray(0, 8192).includes(0)) { + skipped.binary++; + continue; + } + const language = detectLanguage(c.rel); + const tier = language ? languageTier(language) : 0; + if (tier > 0 && looksGenerated(c.rel, buf.subarray(0, 4096).toString('utf8'))) { + skipped.generated++; + continue; + } + let lineCount = 1; + for (let i = 0; i < buf.length; i++) if (buf[i] === 10) lineCount++; + files.push({ + path: c.rel, + absPath, + size: buf.length, + language, + hash: createHash('sha1').update(buf).digest('hex'), + lineCount, + analyzable: tier > 0 && !disabled.has(language ?? ''), + }); + } + opts.onProgress?.(list.length, list.length); + return { files, skipped, truncated }; +} diff --git a/packages/repository-indexer/src/workers.ts b/packages/repository-indexer/src/workers.ts new file mode 100644 index 0000000..9daee46 --- /dev/null +++ b/packages/repository-indexer/src/workers.ts @@ -0,0 +1,184 @@ +/** + * Bounded worker pool for syntax analysis. Each task is one adapter run over + * a batch of files. Falls back to in-process analysis when worker threads + * cannot be started. + */ +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { Worker } from 'node:worker_threads'; +import { type AnalyzeContext, type FileFacts, type SourceFileInput, type WorkspacePackage, createAdapters, emptyFacts } from '@vectora/language-adapters'; + +export interface AnalyzeTask { + adapterId: string; + files: SourceFileInput[]; + /** Files the adapter must return facts for (subset of `files`); all when omitted. */ + analyzeOnly?: string[]; +} + +export interface TaskContext { + rootDir: string; + allFiles: string[]; + workspacePackages: WorkspacePackage[]; + pythonCommand?: string; +} + +export interface WorkerRequest { + taskIndex: number; + task: AnalyzeTask; + ctx: TaskContext; +} +export type WorkerResponse = + | { type: 'progress'; taskIndex: number; processed: number; total: number } + | { type: 'done'; taskIndex: number; facts: FileFacts[] } + | { type: 'error'; taskIndex: number; message: string }; + +export async function runTaskInProcess(task: AnalyzeTask, ctx: TaskContext, onProgress?: (processed: number, total: number) => void): Promise { + const adapter = createAdapters().find((a) => a.id === task.adapterId); + if (!adapter) throw new Error(`Unknown adapter ${task.adapterId}`); + const actx: AnalyzeContext = { + rootDir: ctx.rootDir, + allFiles: new Set(ctx.allFiles), + analyzeOnly: task.analyzeOnly ? new Set(task.analyzeOnly) : undefined, + workspacePackages: ctx.workspacePackages, + pythonCommand: ctx.pythonCommand, + onProgress, + }; + return adapter.analyze(task.files, actx); +} + +function workerEntry(): { file: string; execArgv: string[] } | null { + const here = fileURLToPath(import.meta.url); + const dir = path.dirname(here); + if (here.endsWith('.ts')) { + const file = path.join(dir, 'analyze-worker.ts'); + return fs.existsSync(file) ? { file, execArgv: ['--import', 'tsx'] } : null; + } + const file = path.join(dir, 'analyze-worker.mjs'); + return fs.existsSync(file) ? { file, execArgv: [] } : null; +} + +const failedFacts = (task: AnalyzeTask, message: string): FileFacts[] => + task.files + .filter((f) => !task.analyzeOnly || task.analyzeOnly.includes(f.path)) + .map((f) => { + const facts = emptyFacts(f, task.adapterId); + facts.errors.push({ path: f.path, message, severity: 'error' }); + return facts; + }); + +export interface RunOptions { + concurrency: number; + inProcess?: boolean; + onProgress?: (processed: number, total: number) => void; +} + +export async function runTasks(tasks: AnalyzeTask[], ctx: TaskContext, opts: RunOptions): Promise<{ facts: FileFacts[]; usedWorkers: boolean }> { + const totals = tasks.map((t) => (t.analyzeOnly ? t.analyzeOnly.length : t.files.length)); + const total = totals.reduce((a, b) => a + b, 0); + const progress = tasks.map(() => 0); + const report = (i: number, processed: number) => { + progress[i] = Math.min(processed, totals[i]!); + opts.onProgress?.( + progress.reduce((a, b) => a + b, 0), + total, + ); + }; + const results: FileFacts[][] = tasks.map(() => []); + if (tasks.length === 0) return { facts: [], usedWorkers: false }; + + const inProcessAll = async () => { + for (let i = 0; i < tasks.length; i++) { + try { + results[i] = await runTaskInProcess(tasks[i]!, ctx, (p) => report(i, p)); + } catch (err) { + results[i] = failedFacts(tasks[i]!, `Analysis failed: ${(err as Error).message}`); + } + report(i, totals[i]!); + } + return { facts: results.flat(), usedWorkers: false }; + }; + + const entry = opts.inProcess ? null : workerEntry(); + if (!entry) return inProcessAll(); + + // Python analysis already runs in a separate interpreter process; keep it on the main thread. + const pending = tasks.map((_, i) => i); + const mainThread = pending.filter((i) => tasks[i]!.adapterId === 'python'); + const queue = pending.filter((i) => tasks[i]!.adapterId !== 'python'); + const mainWork = (async () => { + for (const i of mainThread) { + try { + results[i] = await runTaskInProcess(tasks[i]!, ctx, (p) => report(i, p)); + } catch (err) { + results[i] = failedFacts(tasks[i]!, `Analysis failed: ${(err as Error).message}`); + } + report(i, totals[i]!); + } + })(); + + let startFailure = false; + const workerCount = Math.max(1, Math.min(opts.concurrency, queue.length)); + const runWorker = (): Promise => + new Promise((resolve) => { + if (queue.length === 0) return resolve(); + let worker: Worker; + try { + worker = new Worker(entry.file, { execArgv: entry.execArgv, resourceLimits: { maxOldGenerationSizeMb: 3072 } }); + } catch { + startFailure = true; + return resolve(); + } + let current: number | null = null; + let gotMessage = false; + const next = () => { + const i = queue.shift(); + if (i === undefined) { + current = null; + void worker.terminate(); + return resolve(); + } + current = i; + worker.postMessage({ taskIndex: i, task: tasks[i]!, ctx } satisfies WorkerRequest); + }; + worker.on('message', (msg: WorkerResponse) => { + gotMessage = true; + if (msg.type === 'progress') report(msg.taskIndex, msg.processed); + else { + results[msg.taskIndex] = msg.type === 'done' ? msg.facts : failedFacts(tasks[msg.taskIndex]!, `Analysis failed: ${msg.message}`); + report(msg.taskIndex, totals[msg.taskIndex]!); + next(); + } + }); + worker.on('error', (err) => { + if (current !== null) { + if (!gotMessage) { + // The worker never came up: hand the task back and let the caller fall back. + queue.unshift(current); + startFailure = true; + } else { + results[current] = failedFacts(tasks[current]!, `Analysis worker stopped: ${err.message}`); + report(current, totals[current]!); + } + } + resolve(); + }); + next(); + }); + + await Promise.all([mainWork, ...Array.from({ length: workerCount }, runWorker)]); + if (startFailure && queue.length) { + for (const i of queue.splice(0)) { + try { + results[i] = await runTaskInProcess(tasks[i]!, ctx, (p) => report(i, p)); + } catch (err) { + results[i] = failedFacts(tasks[i]!, `Analysis failed: ${(err as Error).message}`); + } + report(i, totals[i]!); + } + return { facts: results.flat(), usedWorkers: false }; + } + // Tasks left over because every worker died after starting. + for (const i of queue.splice(0)) results[i] = failedFacts(tasks[i]!, 'Analysis worker stopped before this batch was processed'); + return { facts: results.flat(), usedWorkers: true }; +} diff --git a/packages/search/package.json b/packages/search/package.json new file mode 100644 index 0000000..04d2b8e --- /dev/null +++ b/packages/search/package.json @@ -0,0 +1,9 @@ +{ + "name": "@vectora/search", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MIT", + "exports": { ".": "./src/index.ts" }, + "dependencies": { "@vectora/graph-schema": "*" } +} diff --git a/packages/search/src/index.ts b/packages/search/src/index.ts new file mode 100644 index 0000000..22f429f --- /dev/null +++ b/packages/search/src/index.ts @@ -0,0 +1,158 @@ +/** + * Search over knowledge-graph nodes: exact names, partial matches, file + * paths, qualified symbol names and descriptions. Runs in the engine and in + * the browser. + */ +import type { GraphNode, NodeType } from '@vectora/graph-schema'; + +export interface SearchHit { + node: GraphNode; + score: number; + /** Which field matched, for display. */ + match: 'name' | 'qualified' | 'path' | 'description' | 'fuzzy'; +} + +export interface SearchOptions { + types?: readonly NodeType[]; + limit?: number; +} + +interface Entry { + node: GraphNode; + name: string; + qualified: string; + path: string; + description: string; + tokens: string[]; +} + +export const splitIdentifier = (s: string): string[] => + s + .replace(/([a-z0-9])([A-Z])/g, '$1 $2') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2') + .toLowerCase() + .split(/[^a-z0-9]+/) + .filter(Boolean); + +const TYPE_WEIGHT: Partial> = { + Concept: 6, + Subsystem: 6, + Class: 5, + DatabaseModel: 5, + Component: 5, + Interface: 4, + ApiEndpoint: 4, + Function: 4, + Method: 3, + Module: 3, + File: 3, + Type: 2, + Package: 2, + Configuration: 1, + Directory: 1, + Constant: 1, + Variable: 0, +}; + +/** True when every character of `needle` appears in `hay` in order. */ +function subsequence(needle: string, hay: string): boolean { + let i = 0; + for (let j = 0; j < hay.length && i < needle.length; j++) if (hay[j] === needle[i]) i++; + return i === needle.length; +} + +export class SearchIndex { + private entries: Entry[]; + + constructor(nodes: GraphNode[]) { + this.entries = nodes.map((node) => { + const qualified = String(node.metadata.qualifiedName ?? node.name); + return { + node, + name: node.name.toLowerCase(), + qualified: qualified.toLowerCase(), + path: (node.filePath ?? '').toLowerCase(), + description: (node.description ?? '').toLowerCase(), + tokens: splitIdentifier(`${node.name} ${qualified}`), + }; + }); + } + + get size(): number { + return this.entries.length; + } + + search(query: string, opts: SearchOptions = {}): SearchHit[] { + const raw = query.trim(); + if (!raw) return []; + const q = raw.toLowerCase(); + const qTokens = splitIdentifier(raw); + const types = opts.types ? new Set(opts.types) : null; + const limit = opts.limit ?? 30; + const pathLike = q.includes('/') || /\.[a-z]{1,4}$/.test(q); + const hits: SearchHit[] = []; + for (const e of this.entries) { + if (types && !types.has(e.node.type)) continue; + let score = 0; + let match: SearchHit['match'] = 'name'; + if (e.node.name === raw) score = 100; + else if (e.name === q) score = 92; + else if (e.qualified === q) (score = 90), (match = 'qualified'); + else if (e.name.startsWith(q)) score = 75 - Math.min(15, e.name.length - q.length); + else if (e.name.includes(q)) score = 58 - Math.min(15, (e.name.length - q.length) / 2); + else if (e.qualified.includes(q)) (score = 50), (match = 'qualified'); + else if (qTokens.length > 1 && qTokens.every((t) => e.tokens.some((et) => et.startsWith(t)))) score = 48; + if (score < 60 && e.path) { + if (e.path === q) (score = Math.max(score, 88)), (match = 'path'); + else if (pathLike && e.path.endsWith(q)) (score = Math.max(score, 70)), (match = 'path'); + else if (e.path.includes(q) && score < 40) { + // Path-only matches favour the file itself over its symbols. + score = e.node.type === 'File' || e.node.type === 'Configuration' || e.node.type === 'Directory' || e.node.type === 'Module' ? 40 : 18; + match = 'path'; + } + } + if (score === 0 && e.description && e.description.includes(q)) (score = 22), (match = 'description'); + if (score === 0 && qTokens.length && qTokens.every((t) => e.description.includes(t) || e.tokens.some((et) => et.startsWith(t)))) (score = 16), (match = 'description'); + if (score === 0 && q.length >= 3 && q.length <= 24 && !q.includes(' ') && subsequence(q, e.name)) (score = 10), (match = 'fuzzy'); + if (score === 0) continue; + hits.push({ node: e.node, score: score + (TYPE_WEIGHT[e.node.type] ?? 0), match }); + } + hits.sort((a, b) => b.score - a.score || a.node.name.length - b.node.name.length || (a.node.id < b.node.id ? -1 : 1)); + return hits.slice(0, limit); + } +} + +export function searchNodes(nodes: GraphNode[], query: string, opts: SearchOptions = {}): SearchHit[] { + return new SearchIndex(nodes).search(query, opts); +} + +export interface DocumentHit { + path: string; + line: number; + snippet: string; + heading: string | null; +} + +/** Plain-text search inside documentation files. */ +export function searchDocuments(docs: { path: string; content: string }[], query: string, limit = 20): DocumentHit[] { + const q = query.trim().toLowerCase(); + if (q.length < 2) return []; + const hits: DocumentHit[] = []; + for (const d of docs) { + const lines = d.content.split(/\r?\n/); + let heading: string | null = null; + let perDoc = 0; + for (let i = 0; i < lines.length && hits.length < limit && perDoc < 3; i++) { + const line = lines[i]!; + const h = /^#{1,6}\s+(.*)$/.exec(line); + if (h) heading = h[1]!.trim(); + if (line.toLowerCase().includes(q)) { + const text = line.trim(); + hits.push({ path: d.path, line: i + 1, snippet: text.length > 200 ? `${text.slice(0, 197)}...` : text, heading }); + perDoc++; + } + } + if (hits.length >= limit) break; + } + return hits; +} diff --git a/packages/shared/package.json b/packages/shared/package.json new file mode 100644 index 0000000..280bb29 --- /dev/null +++ b/packages/shared/package.json @@ -0,0 +1,9 @@ +{ + "name": "@vectora/shared", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MIT", + "exports": { ".": "./src/index.ts" }, + "dependencies": { "zod": "^4.6.7" } +} diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts new file mode 100644 index 0000000..6cd4382 --- /dev/null +++ b/packages/shared/src/index.ts @@ -0,0 +1,316 @@ +/** + * Types and helpers shared by the local engine and the web application: + * settings schema, API contracts, log redaction. + */ +import { z } from 'zod'; + +export const APP_VERSION = '0.1.0'; +export const DEFAULT_ENGINE_PORT = 4317; + +// --------------------------------------------------------------------------- +// Settings +// --------------------------------------------------------------------------- + +export const DEFAULT_IGNORE_PATTERNS = [ + 'node_modules/', + '.git/', + 'dist/', + 'build/', + 'out/', + 'target/', + 'coverage/', + 'vendor/', + '.next/', + '.nuxt/', + '.venv/', + 'venv/', + '__pycache__/', + '.idea/', + '.vscode/', + '*.min.js', + '*.min.css', + '*.map', + '*.lock', + 'package-lock.json', + 'pnpm-lock.yaml', +]; + +export const SettingsSchema = z.object({ + appearance: z + .object({ + theme: z.enum(['light', 'dark', 'system']).default('system'), + }) + .prefault({}), + graph: z + .object({ + defaultMode: z.enum(['graph', 'atlas', 'mindmap']).default('graph'), + /** Share of symbol-level nodes shown before expansion. */ + nodeDensity: z.enum(['structure', 'balanced', 'full']).default('balanced'), + hiddenRelationships: z.array(z.string()).default(['DEFINED_IN']), + showUnverified: z.boolean().default(true), + animationIntensity: z.enum(['none', 'subtle', 'standard']).default('subtle'), + labelDensity: z.enum(['low', 'medium', 'high']).default('medium'), + focusBehavior: z.enum(['neighbourhood', 'node', 'none']).default('neighbourhood'), + }) + .prefault({}), + performance: z + .object({ + workerConcurrency: z.number().int().min(1).max(16).default(4), + indexingCache: z.boolean().default(true), + renderingQuality: z.enum(['low', 'balanced', 'high']).default('balanced'), + reducedMotion: z.enum(['system', 'on', 'off']).default('system'), + maxFiles: z.number().int().min(100).max(200000).default(20000), + maxGraphNodes: z.number().int().min(500).max(200000).default(8000), + }) + .prefault({}), + repository: z + .object({ + ignorePatterns: z.array(z.string()).default(DEFAULT_IGNORE_PATTERNS), + maxFileSizeKb: z.number().int().min(16).max(8192).default(512), + disabledLanguages: z.array(z.string()).default([]), + incrementalIndexing: z.boolean().default(true), + }) + .prefault({}), + privacy: z + .object({ + includeSourceInExports: z.boolean().default(false), + }) + .prefault({}), + exploration: z + .object({ + /** Optional external narrative provider. Disabled by default. */ + providerEnabled: z.boolean().default(false), + providerEndpoint: z.string().default(''), + providerModel: z.string().default(''), + }) + .prefault({}), +}); +export type Settings = z.infer; +export const defaultSettings = (): Settings => SettingsSchema.parse({}); + +/** Deep-merges a partial settings patch into existing settings and validates. */ +export function mergeSettings(current: Settings, patch: unknown): Settings { + const merge = (a: unknown, b: unknown): unknown => { + if (b === undefined) return a; + if (a && b && typeof a === 'object' && typeof b === 'object' && !Array.isArray(a) && !Array.isArray(b)) { + const out: Record = { ...(a as Record) }; + for (const [k, v] of Object.entries(b as Record)) out[k] = merge(out[k], v); + return out; + } + return b; + }; + return SettingsSchema.parse(merge(current, patch)); +} + +// --------------------------------------------------------------------------- +// API contracts +// --------------------------------------------------------------------------- + +export type RepositorySourceKind = 'github' | 'zip' | 'local' | 'sample'; +export type IndexStatus = 'pending' | 'indexing' | 'ready' | 'failed'; + +export interface RepositoryRecord { + id: string; + name: string; + sourceKind: RepositorySourceKind; + /** Display origin: GitHub URL, archive file name or local path. Never contains credentials. */ + origin: string; + branch: string | null; + subdirectory: string | null; + status: IndexStatus; + createdAt: string; + lastIndexedAt: string | null; + fileCount: number; + symbolCount: number; + relationshipCount: number; + error: string | null; +} + +export const INDEX_STAGES = [ + 'acquire', + 'discover', + 'analyze', + 'resolve', + 'flows', + 'organize', + 'graph', + 'persist', +] as const; +export type IndexStage = (typeof INDEX_STAGES)[number]; + +export const INDEX_STAGE_LABELS: Record = { + acquire: 'Acquiring source', + discover: 'Discovering files', + analyze: 'Analysing syntax', + resolve: 'Resolving relationships', + flows: 'Tracing execution flows', + organize: 'Organising subsystems and concepts', + graph: 'Generating knowledge graph', + persist: 'Saving workspace', +}; + +export interface JobProgress { + id: string; + repositoryId: string | null; + status: 'running' | 'completed' | 'failed'; + stage: IndexStage; + stageIndex: number; + message: string; + processed: number; + total: number; + startedAt: string; + finishedAt: string | null; + error: string | null; + summary: IndexSummary | null; +} + +export interface IndexSummary { + files: number; + analyzedFiles: number; + reusedFiles: number; + symbols: number; + relationships: number; + unresolved: number; + parseErrors: number; + durationMs: number; + incremental: boolean; +} + +export interface OverviewEntryPoint { + path: string; + reason: string; + nodeId: string; +} + +export interface RepositoryOverview { + repository: RepositoryRecord; + description: string | null; + descriptionSource: string | null; + languages: { + language: string; + tier: number; + files: number; + analyzedFiles: number; + symbols: number; + parseErrors: number; + adapter: string | null; + lines: number; + }[]; + frameworks: { name: string; evidence: string }[]; + entryPoints: OverviewEntryPoint[]; + subsystems: { id: string; name: string; files: number; symbols: number; inbound: number; outbound: number }[]; + concepts: { id: string; name: string; members: number; evidence: string[] }[]; + largestModules: { id: string; path: string; symbols: number; lines: number }[]; + dependencies: { + declared: number; + imported: number; + internalImports: number; + externalPackages: { name: string; importers: number; declared: boolean; version: string | null }[]; + }; + architectureSummary: { statement: string; evidence: string; verified: boolean }[]; + unresolved: number; + validation: { errors: number; warnings: number }; + summary: IndexSummary | null; +} + +export interface EvidenceRef { + path: string; + startLine: number; + endLine: number; + nodeId?: string; + snippet?: string; +} + +export interface ExplorationStatement { + text: string; + verified: boolean; + evidence: EvidenceRef[]; +} + +export interface ExplorationAnswer { + question: string; + intent: string; + title: string; + statements: ExplorationStatement[]; + /** Node ids to highlight in the visualisations. */ + nodeIds: string[]; + edgeIds: string[]; + /** Things the engine could not establish from the graph. */ + caveats: string[]; + narrative?: string | null; + narrativeSource?: string | null; +} + +export interface SourceResponse { + path: string; + language: string | null; + content: string; + startLine: number; + endLine: number; + totalLines: number; + truncated: boolean; +} + +export interface SessionState { + view: string; + selectedIds: string[]; + focusId: string | null; + expandedIds: string[]; + hiddenNodeTypes: string[]; + hiddenEdgeTypes: string[]; + layouts: { + graph?: Record; + mindmap?: Record; + mindmapCollapsed?: string[]; + atlasCamera?: { position: [number, number, number]; target: [number, number, number] }; + }; + savedAt: string; +} + +// --------------------------------------------------------------------------- +// Secret redaction for diagnostic logs +// --------------------------------------------------------------------------- + +const SECRET_PATTERNS: RegExp[] = [ + /gh[pousr]_[A-Za-z0-9]{20,}/g, // GitHub tokens + /github_pat_[A-Za-z0-9_]{20,}/g, + /(?<=(?:authorization|x-api-key|api-key)["']?\s*[:=]\s*["']?)(?:bearer\s+|basic\s+|token\s+)?[^\s"',}]+/gi, + /(?<=(?:token|secret|password|passwd|api[_-]?key|access[_-]?key)["']?\s*[:=]\s*["']?)[^\s"',}&]{6,}/gi, + /(?<=:\/\/[^/\s:@]+:)[^@\s/]+(?=@)/g, // credentials embedded in URLs + /sk-[A-Za-z0-9_-]{20,}/g, + /AKIA[0-9A-Z]{16}/g, + /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, +]; + +/** Replaces anything that looks like a credential with a placeholder. */ +export function redactSecrets(input: string): string { + let out = input; + for (const re of SECRET_PATTERNS) out = out.replace(re, '[redacted]'); + return out; +} + +export function redactDeep(value: T): T { + if (typeof value === 'string') return redactSecrets(value) as unknown as T; + if (Array.isArray(value)) return value.map((v) => redactDeep(v)) as unknown as T; + if (value && typeof value === 'object') { + const out: Record = {}; + for (const [k, v] of Object.entries(value as Record)) { + out[k] = /token|secret|password|authorization|api[_-]?key|credential/i.test(k) && typeof v === 'string' ? '[redacted]' : redactDeep(v); + } + return out as T; + } + return value; +} + +export const formatBytes = (n: number): string => { + if (n < 1024) return `${n} B`; + if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`; + return `${(n / 1024 / 1024).toFixed(1)} MB`; +}; + +export const slugify = (s: string): string => + s + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, '') + .slice(0, 60) || 'item'; diff --git a/samples/sample-repo/.gitignore b/samples/sample-repo/.gitignore new file mode 100644 index 0000000..417ee96 --- /dev/null +++ b/samples/sample-repo/.gitignore @@ -0,0 +1,2 @@ +ignored/ +*.tmp diff --git a/samples/sample-repo/README.md b/samples/sample-repo/README.md new file mode 100644 index 0000000..5d12b37 --- /dev/null +++ b/samples/sample-repo/README.md @@ -0,0 +1,9 @@ +# Orbit Notes — VECTORA sample repository + +**This is not a real product.** It is a small, deliberately simple multi-language +repository that ships with VECTORA exclusively for automated tests and for the +onboarding demonstration. Its dependencies are never installed and its code is +never executed. + +A note-taking service with a TypeScript web application, a Python analytics +service and a few command-line tools in other languages. diff --git a/samples/sample-repo/analytics/app/__init__.py b/samples/sample-repo/analytics/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/samples/sample-repo/analytics/app/main.py b/samples/sample-repo/analytics/app/main.py new file mode 100644 index 0000000..d6d908c --- /dev/null +++ b/samples/sample-repo/analytics/app/main.py @@ -0,0 +1,25 @@ +"""Analytics service entry point.""" +from fastapi import FastAPI + +from .services.report import ReportService +from . import models + +app = FastAPI() + + +def get_session(): + return None + + +@app.get("/stats") +def stats(): + """Returns the usage report.""" + service = ReportService(get_session()) + return service.build_report() + + +@app.post("/events") +def record_event(kind: str): + ReportService(get_session()).record(kind) + undefined_function(kind) + return {"ok": True} diff --git a/samples/sample-repo/analytics/app/models.py b/samples/sample-repo/analytics/app/models.py new file mode 100644 index 0000000..908fcfe --- /dev/null +++ b/samples/sample-repo/analytics/app/models.py @@ -0,0 +1,15 @@ +"""Database models for the analytics service.""" +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column + + +class Base(DeclarativeBase): + pass + + +class Event(Base): + """A recorded usage event.""" + + __tablename__ = "events" + + id: Mapped[int] = mapped_column(primary_key=True) + kind: Mapped[str] diff --git a/samples/sample-repo/analytics/app/services/__init__.py b/samples/sample-repo/analytics/app/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/samples/sample-repo/analytics/app/services/report.py b/samples/sample-repo/analytics/app/services/report.py new file mode 100644 index 0000000..e3bb702 --- /dev/null +++ b/samples/sample-repo/analytics/app/services/report.py @@ -0,0 +1,27 @@ +"""Report generation.""" +from ..models import Event + +MAX_ROWS = 500 + + +def summarize(rows): + """Counts events per kind.""" + counts = {} + for row in rows: + counts[row.kind] = counts.get(row.kind, 0) + 1 + return counts + + +class ReportService: + """Builds usage reports from recorded events.""" + + def __init__(self, session): + self.session = session + + def build_report(self): + rows = self.session.query(Event).limit(MAX_ROWS).all() + return summarize(rows) + + def record(self, kind): + self.session.add(Event(kind=kind)) + self.missing_helper() diff --git a/samples/sample-repo/analytics/requirements.txt b/samples/sample-repo/analytics/requirements.txt new file mode 100644 index 0000000..cb2afa4 --- /dev/null +++ b/samples/sample-repo/analytics/requirements.txt @@ -0,0 +1,2 @@ +fastapi>=0.110 +sqlalchemy>=2.0 diff --git a/samples/sample-repo/package.json b/samples/sample-repo/package.json new file mode 100644 index 0000000..f6410a9 --- /dev/null +++ b/samples/sample-repo/package.json @@ -0,0 +1,9 @@ +{ + "name": "orbit-notes-sample", + "version": "1.0.0", + "description": "Sample note-taking service used by VECTORA tests and onboarding.", + "main": "web/src/server.ts", + "scripts": { "start": "node web/src/server.ts" }, + "dependencies": { "express": "^4.19.0", "drizzle-orm": "^0.30.0", "react": "^18.3.0" }, + "devDependencies": { "typescript": "^5.4.0" } +} diff --git a/samples/sample-repo/tools/c/main.c b/samples/sample-repo/tools/c/main.c new file mode 100644 index 0000000..c2983ea --- /dev/null +++ b/samples/sample-repo/tools/c/main.c @@ -0,0 +1,7 @@ +#include +#include "util.h" + +int main(void) { + printf("%d", title_length("Orbit")); + return 0; +} diff --git a/samples/sample-repo/tools/c/util.c b/samples/sample-repo/tools/c/util.c new file mode 100644 index 0000000..fd5d3fd --- /dev/null +++ b/samples/sample-repo/tools/c/util.c @@ -0,0 +1,6 @@ +#include +#include "util.h" + +int title_length(const char *title) { + return (int)strlen(title); +} diff --git a/samples/sample-repo/tools/c/util.h b/samples/sample-repo/tools/c/util.h new file mode 100644 index 0000000..60a9c0e --- /dev/null +++ b/samples/sample-repo/tools/c/util.h @@ -0,0 +1,8 @@ +#ifndef UTIL_H +#define UTIL_H + +#define MAX_TITLE 80 + +int title_length(const char *title); + +#endif diff --git a/samples/sample-repo/tools/csharp/Program.cs b/samples/sample-repo/tools/csharp/Program.cs new file mode 100644 index 0000000..e794950 --- /dev/null +++ b/samples/sample-repo/tools/csharp/Program.cs @@ -0,0 +1,14 @@ +using System; +using Orbit.Tools.Services; + +namespace Orbit.Tools +{ + public class Program + { + public static void Main(string[] args) + { + var greeter = new Greeter(); + Console.WriteLine(greeter.Greet("Orbit")); + } + } +} diff --git a/samples/sample-repo/tools/csharp/Services/Greeter.cs b/samples/sample-repo/tools/csharp/Services/Greeter.cs new file mode 100644 index 0000000..cc26d3e --- /dev/null +++ b/samples/sample-repo/tools/csharp/Services/Greeter.cs @@ -0,0 +1,20 @@ +namespace Orbit.Tools.Services +{ + public interface IGreeter + { + string Greet(string name); + } + + public class Greeter : IGreeter + { + public string Greet(string name) + { + return Format(name); + } + + private string Format(string name) + { + return "Hello, " + name; + } + } +} diff --git a/samples/sample-repo/tools/go/go.mod b/samples/sample-repo/tools/go/go.mod new file mode 100644 index 0000000..8a04f45 --- /dev/null +++ b/samples/sample-repo/tools/go/go.mod @@ -0,0 +1,3 @@ +module example.com/orbit/tools + +go 1.22 diff --git a/samples/sample-repo/tools/go/main.go b/samples/sample-repo/tools/go/main.go new file mode 100644 index 0000000..b444125 --- /dev/null +++ b/samples/sample-repo/tools/go/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "net/http" + + "example.com/orbit/tools/store" +) + +func health(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "ok") +} + +func main() { + s := store.New() + fmt.Println(store.Count(s)) + http.HandleFunc("/health", health) +} diff --git a/samples/sample-repo/tools/go/store/store.go b/samples/sample-repo/tools/go/store/store.go new file mode 100644 index 0000000..a945d81 --- /dev/null +++ b/samples/sample-repo/tools/go/store/store.go @@ -0,0 +1,27 @@ +package store + +// Note is a stored note. +type Note struct { + Title string + Body string +} + +// Store keeps notes in memory. +type Store struct { + notes []Note +} + +// New creates an empty store. +func New() *Store { + return &Store{} +} + +// Add appends a note. +func (s *Store) Add(n Note) { + s.notes = append(s.notes, n) +} + +// Count returns the number of notes. +func Count(s *Store) int { + return len(s.notes) +} diff --git a/samples/sample-repo/tools/java/src/com/sample/tools/Exporter.java b/samples/sample-repo/tools/java/src/com/sample/tools/Exporter.java new file mode 100644 index 0000000..f625ba4 --- /dev/null +++ b/samples/sample-repo/tools/java/src/com/sample/tools/Exporter.java @@ -0,0 +1,20 @@ +package com.sample.tools; + +import java.util.List; +import com.sample.tools.JsonFormatter; + +public class Exporter { + private final Formatter formatter = new JsonFormatter(); + + public String export(List notes) { + StringBuilder out = new StringBuilder(); + for (String[] note : notes) { + out.append(formatter.format(note[0], note[1])); + } + return out.toString(); + } + + public static void main(String[] args) { + System.out.println(new Exporter().export(List.of())); + } +} diff --git a/samples/sample-repo/tools/java/src/com/sample/tools/Formatter.java b/samples/sample-repo/tools/java/src/com/sample/tools/Formatter.java new file mode 100644 index 0000000..1aa81df --- /dev/null +++ b/samples/sample-repo/tools/java/src/com/sample/tools/Formatter.java @@ -0,0 +1,6 @@ +package com.sample.tools; + +/** Turns a note into text. */ +public interface Formatter { + String format(String title, String body); +} diff --git a/samples/sample-repo/tools/java/src/com/sample/tools/JsonFormatter.java b/samples/sample-repo/tools/java/src/com/sample/tools/JsonFormatter.java new file mode 100644 index 0000000..03eba94 --- /dev/null +++ b/samples/sample-repo/tools/java/src/com/sample/tools/JsonFormatter.java @@ -0,0 +1,12 @@ +package com.sample.tools; + +public class JsonFormatter implements Formatter { + @Override + public String format(String title, String body) { + return "{title:" + escape(title) + ",body:" + escape(body) + "}"; + } + + private String escape(String value) { + return value.trim(); + } +} diff --git a/samples/sample-repo/tools/rust/Cargo.toml b/samples/sample-repo/tools/rust/Cargo.toml new file mode 100644 index 0000000..8df2704 --- /dev/null +++ b/samples/sample-repo/tools/rust/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "orbit-parser" +version = "0.1.0" + +[dependencies] +serde = "1" diff --git a/samples/sample-repo/tools/rust/src/main.rs b/samples/sample-repo/tools/rust/src/main.rs new file mode 100644 index 0000000..69c6532 --- /dev/null +++ b/samples/sample-repo/tools/rust/src/main.rs @@ -0,0 +1,8 @@ +mod parser; + +use crate::parser::{first_line, Header, Parse}; + +fn main() { + let header = Header::parse("Title"); + println!("{} {}", header.title, first_line("x")); +} diff --git a/samples/sample-repo/tools/rust/src/parser.rs b/samples/sample-repo/tools/rust/src/parser.rs new file mode 100644 index 0000000..3f9ee59 --- /dev/null +++ b/samples/sample-repo/tools/rust/src/parser.rs @@ -0,0 +1,19 @@ +/// A parsed note header. +pub struct Header { + pub title: String, +} + +pub trait Parse { + fn parse(input: &str) -> Self; +} + +impl Parse for Header { + fn parse(input: &str) -> Self { + Header { title: first_line(input) } + } +} + +/// Returns the first line of the input. +pub fn first_line(input: &str) -> String { + input.lines().next().unwrap_or("").to_string() +} diff --git a/samples/sample-repo/web/src/auth/middleware.ts b/samples/sample-repo/web/src/auth/middleware.ts new file mode 100644 index 0000000..a731ded --- /dev/null +++ b/samples/sample-repo/web/src/auth/middleware.ts @@ -0,0 +1,16 @@ +import { type Session, verifyToken } from './session'; + +export interface AuthedRequest { + headers: Record; + session?: Session; +} + +export function requireAuth(req: AuthedRequest, res: { status(code: number): { end(): void } }, next: () => void): void { + const session = verifyToken(req.headers.authorization ?? ''); + if (!session) { + res.status(401).end(); + return; + } + req.session = session; + next(); +} diff --git a/samples/sample-repo/web/src/auth/session.ts b/samples/sample-repo/web/src/auth/session.ts new file mode 100644 index 0000000..d269043 --- /dev/null +++ b/samples/sample-repo/web/src/auth/session.ts @@ -0,0 +1,23 @@ +import { loadConfig } from '../config'; + +export interface Session { + userId: number; + expiresAt: number; +} + +const sessions = new Map(); + +/** Creates a session token for a user. */ +export function createSession(userId: number): string { + const token = 'token-' + userId + '-' + Date.now(); + const ttl = loadConfig().sessionTtlMinutes * 60_000; + sessions.set(token, { userId, expiresAt: Date.now() + ttl }); + return token; +} + +/** Returns the session for a token, or null when it is unknown or expired. */ +export function verifyToken(token: string): Session | null { + const session = sessions.get(token); + if (!session || session.expiresAt < Date.now()) return null; + return session; +} diff --git a/samples/sample-repo/web/src/config.ts b/samples/sample-repo/web/src/config.ts new file mode 100644 index 0000000..c19974f --- /dev/null +++ b/samples/sample-repo/web/src/config.ts @@ -0,0 +1,11 @@ +/** Runtime configuration for the web application. */ +export interface AppConfig { + port: number; + sessionTtlMinutes: number; +} + +export const DEFAULT_PORT = 3000; + +export function loadConfig(): AppConfig { + return { port: DEFAULT_PORT, sessionTtlMinutes: 30 }; +} diff --git a/samples/sample-repo/web/src/cycle/a.ts b/samples/sample-repo/web/src/cycle/a.ts new file mode 100644 index 0000000..41c1ff6 --- /dev/null +++ b/samples/sample-repo/web/src/cycle/a.ts @@ -0,0 +1,5 @@ +import { pong } from './b'; + +export function ping(n: number): number { + return n <= 0 ? 0 : pong(n - 1); +} diff --git a/samples/sample-repo/web/src/cycle/b.ts b/samples/sample-repo/web/src/cycle/b.ts new file mode 100644 index 0000000..a4b6ed6 --- /dev/null +++ b/samples/sample-repo/web/src/cycle/b.ts @@ -0,0 +1,5 @@ +import { ping } from './a'; + +export function pong(n: number): number { + return n <= 0 ? 0 : ping(n - 1); +} diff --git a/samples/sample-repo/web/src/db/client.ts b/samples/sample-repo/web/src/db/client.ts new file mode 100644 index 0000000..0fdb619 --- /dev/null +++ b/samples/sample-repo/web/src/db/client.ts @@ -0,0 +1,3 @@ +import { drizzle } from 'drizzle-orm/better-sqlite3'; + +export const db = drizzle(':memory:'); diff --git a/samples/sample-repo/web/src/db/noteRepository.ts b/samples/sample-repo/web/src/db/noteRepository.ts new file mode 100644 index 0000000..8084e0e --- /dev/null +++ b/samples/sample-repo/web/src/db/noteRepository.ts @@ -0,0 +1,21 @@ +import { db } from './client'; +import { notes } from './schema'; + +export interface NoteRecord { + id: number; + ownerId: number; + title: string; + body: string; +} + +/** Data access for notes. */ +export class NoteRepository { + async findByOwner(ownerId: number): Promise { + const rows = await db.select().from(notes); + return rows.filter((r: NoteRecord) => r.ownerId === ownerId); + } + + async insert(note: Omit): Promise { + await db.insert(notes).values(note); + } +} diff --git a/samples/sample-repo/web/src/db/schema.ts b/samples/sample-repo/web/src/db/schema.ts new file mode 100644 index 0000000..62c3770 --- /dev/null +++ b/samples/sample-repo/web/src/db/schema.ts @@ -0,0 +1,13 @@ +import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'; + +export const users = sqliteTable('users', { + id: integer('id').primaryKey(), + email: text('email').notNull(), +}); + +export const notes = sqliteTable('notes', { + id: integer('id').primaryKey(), + ownerId: integer('owner_id').notNull(), + title: text('title').notNull(), + body: text('body').notNull(), +}); diff --git a/samples/sample-repo/web/src/routes/login.ts b/samples/sample-repo/web/src/routes/login.ts new file mode 100644 index 0000000..6c37260 --- /dev/null +++ b/samples/sample-repo/web/src/routes/login.ts @@ -0,0 +1,8 @@ +import { Router } from 'express'; +import { createSession } from '../auth/session'; + +export const loginRouter = Router(); + +loginRouter.post('/login', (req: { body: { userId: number } }, res: { json(body: unknown): void }) => { + res.json({ token: createSession(req.body.userId) }); +}); diff --git a/samples/sample-repo/web/src/routes/notes.ts b/samples/sample-repo/web/src/routes/notes.ts new file mode 100644 index 0000000..1fa67cb --- /dev/null +++ b/samples/sample-repo/web/src/routes/notes.ts @@ -0,0 +1,17 @@ +import { Router } from 'express'; +import { requireAuth, type AuthedRequest } from '../auth/middleware'; +import { NoteService } from '../services/noteService'; + +const service = new NoteService(); +export const router = Router(); + +export async function listNotes(req: AuthedRequest, res: { json(body: unknown): void }): Promise { + res.json(await service.list(req.session!.userId)); +} + +router.get('/notes', requireAuth, listNotes); + +router.post('/notes', requireAuth, async (req: AuthedRequest & { body: { title: string; body: string } }, res: { status(c: number): { end(): void } }) => { + await service.create(req.session!.userId, req.body.title, req.body.body); + res.status(201).end(); +}); diff --git a/samples/sample-repo/web/src/server.ts b/samples/sample-repo/web/src/server.ts new file mode 100644 index 0000000..2923672 --- /dev/null +++ b/samples/sample-repo/web/src/server.ts @@ -0,0 +1,14 @@ +import express from 'express'; +import { loadConfig } from './config'; +import { loginRouter } from './routes/login'; +import { router as notesRouter } from './routes/notes'; + +export function start(): void { + const config = loadConfig(); + const app = express(); + app.use(loginRouter); + app.use(notesRouter); + app.listen(config.port); +} + +start(); diff --git a/samples/sample-repo/web/src/services/noteService.ts b/samples/sample-repo/web/src/services/noteService.ts new file mode 100644 index 0000000..25e33c9 --- /dev/null +++ b/samples/sample-repo/web/src/services/noteService.ts @@ -0,0 +1,17 @@ +import { NoteRepository, type NoteRecord } from '../db/noteRepository'; + +export class ValidationError extends Error {} + +/** Business rules for notes. */ +export class NoteService { + private repository = new NoteRepository(); + + async list(ownerId: number): Promise { + return this.repository.findByOwner(ownerId); + } + + async create(ownerId: number, title: string, body: string): Promise { + if (!title.trim()) throw new ValidationError('A note needs a title'); + await this.repository.insert({ ownerId, title, body }); + } +} diff --git a/samples/sample-repo/web/src/ui/App.tsx b/samples/sample-repo/web/src/ui/App.tsx new file mode 100644 index 0000000..3b26728 --- /dev/null +++ b/samples/sample-repo/web/src/ui/App.tsx @@ -0,0 +1,10 @@ +import { NoteList } from './NoteList'; + +export const App = () => { + return ( +

+

Orbit Notes

+ +
+ ); +}; diff --git a/samples/sample-repo/web/src/ui/NoteList.tsx b/samples/sample-repo/web/src/ui/NoteList.tsx new file mode 100644 index 0000000..44b92e5 --- /dev/null +++ b/samples/sample-repo/web/src/ui/NoteList.tsx @@ -0,0 +1,11 @@ +import type { NoteRecord } from '../db/noteRepository'; + +export function NoteList({ notes }: { notes: NoteRecord[] }) { + return ( +
    + {notes.map((n) => ( +
  • {n.title}
  • + ))} +
+ ); +} diff --git a/scripts/index-cli.ts b/scripts/index-cli.ts new file mode 100644 index 0000000..b79c2dc --- /dev/null +++ b/scripts/index-cli.ts @@ -0,0 +1,39 @@ +/** + * Development helper: index a directory and print a summary. + * Usage: tsx scripts/index-cli.ts
[--workers] [--edges] [--unresolved] [--verbose] + */ +import path from 'node:path'; +import { indexRepository } from '@vectora/repository-indexer'; + +const dir = process.argv[2] ?? 'samples/sample-repo'; +const result = await indexRepository({ + repositoryId: 'cli', + repositoryName: path.basename(path.resolve(dir)), + rootDir: dir, + inProcess: !process.argv.includes('--workers'), + onProgress: process.argv.includes('--verbose') ? (s, m, p, t) => console.log(`[${s}] ${m} ${p}/${t}`) : undefined, +}); +const { graph, analysis } = result; +console.log( + JSON.stringify( + { + stats: graph.stats, + summary: analysis.summary, + validation: { errors: analysis.validation.errors, warnings: analysis.validation.warnings }, + unresolved: analysis.unresolvedByReason, + languages: analysis.languages.filter((l) => l.tier > 0).map((l) => `${l.name}: ${l.analyzedFiles}/${l.files} files, ${l.symbols} symbols, ${l.parseErrors} issues`), + entryPoints: analysis.entryPoints.map((e) => `${e.path} (${e.reason})`), + flows: analysis.flows.map((f) => `${f.name}: ${f.steps.join(' -> ')}`), + frameworks: analysis.frameworks.map((f) => f.name), + parseIssues: analysis.parseIssues, + }, + null, + 1, + ), +); +if (process.argv.includes('--edges')) + for (const e of graph.edges) + if (!['CONTAINS', 'DEFINED_IN', 'BELONGS_TO', 'EXPORTS'].includes(e.type)) + console.log(`${e.type} ${e.source} -> ${e.target} [${e.extractionMethod} ${e.confidence}${e.verified ? '' : ' unverified'}]`); +if (process.argv.includes('--unresolved')) console.log(analysis.unresolvedSamples); +if (analysis.validation.errors) console.log(analysis.validation.issues); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5d1e553 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2023", + "lib": ["ES2023", "DOM", "DOM.Iterable"], + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "noFallthroughCasesInSwitch": true, + "exactOptionalPropertyTypes": false, + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "isolatedModules": true, + "allowImportingTsExtensions": true, + "noEmit": true, + "types": ["node", "vite/client"], + "baseUrl": ".", + "paths": { + "@/*": ["apps/web/src/*"] + } + }, + "include": ["packages/*/src", "apps/*/src", "scripts", "tests", "*.config.ts", "apps/web/*.config.ts"], + "exclude": ["node_modules", "dist", "samples", "**/dist"] +} From b8d58fc65ac452ee297290f4eef657b0141f2e77 Mon Sep 17 00:00:00 2001 From: Shreyan Bag Date: Thu, 12 Nov 2026 07:53:12 +0530 Subject: [PATCH 2/8] Add local engine: imports, indexing jobs, graph API, exports, security - Fastify API bound to loopback with host/origin checks and CSP - GitHub (archive download via REST), ZIP and local folder imports - safe ZIP inspection/extraction with traversal, symlink and size limits - encrypted credential storage, settings, sessions, data deletion - question explorer endpoint with optional narrative provider adapter - all data kept under the project folder by default Co-Authored-By: Claude Fable 5.2 --- .gitattributes | 5 +- apps/local-engine/package.json | 3 +- apps/local-engine/src/config.ts | 64 +++ apps/local-engine/src/github.ts | 135 ++++++ apps/local-engine/src/main.ts | 21 + apps/local-engine/src/provider.ts | 65 +++ apps/local-engine/src/security.ts | 281 ++++++++++++ apps/local-engine/src/server.ts | 249 +++++++++++ apps/local-engine/src/service.ts | 682 ++++++++++++++++++++++++++++++ package-lock.json | 59 +-- scripts/smoke-engine.ts | 39 ++ 11 files changed, 1552 insertions(+), 51 deletions(-) create mode 100644 apps/local-engine/src/config.ts create mode 100644 apps/local-engine/src/github.ts create mode 100644 apps/local-engine/src/main.ts create mode 100644 apps/local-engine/src/provider.ts create mode 100644 apps/local-engine/src/security.ts create mode 100644 apps/local-engine/src/server.ts create mode 100644 apps/local-engine/src/service.ts create mode 100644 scripts/smoke-engine.ts diff --git a/.gitattributes b/.gitattributes index dfe0770..511187a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ -# Auto detect text files and perform LF normalization -* text=auto +* text=auto eol=lf +*.wasm binary +*.png binary diff --git a/apps/local-engine/package.json b/apps/local-engine/package.json index ac31e56..3711f8a 100644 --- a/apps/local-engine/package.json +++ b/apps/local-engine/package.json @@ -14,12 +14,13 @@ "@fastify/static": "^9.0.0", "@vectora/graph-engine": "*", "@vectora/graph-schema": "*", + "@vectora/language-adapters": "*", "@vectora/repository-indexer": "*", "@vectora/search": "*", "@vectora/shared": "*", "fastify": "^5.12.8", + "ignore": "^7.0.14", "octokit": "^5.0.5", - "simple-git": "^4.0.2", "yauzl": "^3.4.0", "zod": "^4.6.7" }, diff --git a/apps/local-engine/src/config.ts b/apps/local-engine/src/config.ts new file mode 100644 index 0000000..fac697f --- /dev/null +++ b/apps/local-engine/src/config.ts @@ -0,0 +1,64 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { DEFAULT_ENGINE_PORT } from '@vectora/shared'; + +export interface EngineConfig { + host: string; + port: number; + /** Database, imported sources, uploads and temporary files all live here. */ + dataDir: string; + /** Browser origins allowed in addition to the engine's own origin. */ + allowedOrigins: string[]; + logLevel: string; + /** Built web application to serve, when present. */ + webDist: string | null; + sampleDir: string | null; + installRoot: string; + production: boolean; + /** Replaceable network transport (tests supply a stub; nothing else should). */ + fetch?: typeof fetch; +} + +/** Walks up from this file to the VECTORA installation root. */ +export function findInstallRoot(): string { + let dir = path.dirname(fileURLToPath(import.meta.url)); + for (let i = 0; i < 8; i++) { + const pkg = path.join(dir, 'package.json'); + if (fs.existsSync(pkg)) { + try { + if ((JSON.parse(fs.readFileSync(pkg, 'utf8')) as { name?: string }).name === 'vectora') return dir; + } catch { + // keep walking + } + } + const parent = path.dirname(dir); + if (parent === dir) break; + dir = parent; + } + return process.cwd(); +} + +export function loadConfig(overrides: Partial = {}): EngineConfig { + const env = process.env; + const installRoot = overrides.installRoot ?? findInstallRoot(); + const webDist = [path.join(installRoot, 'dist', 'web'), path.join(installRoot, 'apps', 'web', 'dist')].find((d) => fs.existsSync(path.join(d, 'index.html'))) ?? null; + const sampleDir = [path.join(installRoot, 'samples', 'sample-repo'), path.join(installRoot, 'dist', 'samples', 'sample-repo')].find((d) => fs.existsSync(d)) ?? null; + const port = Number(env.VECTORA_PORT ?? DEFAULT_ENGINE_PORT); + return { + host: env.VECTORA_HOST ?? '127.0.0.1', + port: Number.isFinite(port) ? port : DEFAULT_ENGINE_PORT, + // Kept inside the installation folder by default so nothing is written to the system drive. + dataDir: path.resolve(env.VECTORA_DATA_DIR ?? path.join(installRoot, '.vectora-data')), + allowedOrigins: (env.VECTORA_ALLOWED_ORIGINS ?? 'http://localhost:5173,http://127.0.0.1:5173') + .split(',') + .map((s) => s.trim()) + .filter(Boolean), + logLevel: env.VECTORA_LOG_LEVEL ?? 'info', + webDist, + sampleDir, + installRoot, + production: env.NODE_ENV === 'production', + ...overrides, + }; +} diff --git a/apps/local-engine/src/github.ts b/apps/local-engine/src/github.ts new file mode 100644 index 0000000..96cfa90 --- /dev/null +++ b/apps/local-engine/src/github.ts @@ -0,0 +1,135 @@ +/** + * GitHub access through the REST API. Repositories are downloaded as source + * archives, so no git commands or repository hooks ever run. Access tokens + * travel only in the Authorization header. + */ +import fs from 'node:fs'; +import { Octokit } from 'octokit'; + +export interface GitHubRef { + owner: string; + repo: string; + branch: string | null; + subdirectory: string | null; +} + +export class GitHubError extends Error { + constructor( + message: string, + public status: number, + ) { + super(message); + } +} + +const NAME = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,99})$/; + +/** Accepts https URLs, `git@github.com:owner/repo.git` and `owner/repo`. */ +export function parseGitHubUrl(input: string): GitHubRef { + const raw = input.trim(); + if (!raw) throw new GitHubError('Enter a GitHub repository URL', 400); + if (/^[a-z]+:\/\/[^/\s]*@/i.test(raw)) throw new GitHubError('Do not put credentials in the URL. Use the access token field instead.', 400); + let rest: string; + const ssh = /^git@github\.com:(.+)$/i.exec(raw); + if (ssh) rest = ssh[1]!; + else if (/^https?:\/\//i.test(raw)) { + let url: URL; + try { + url = new URL(raw); + } catch { + throw new GitHubError('That is not a valid URL', 400); + } + if (!/^(www\.)?github\.com$/i.test(url.hostname)) throw new GitHubError('Only github.com repositories are supported', 400); + rest = url.pathname.replace(/^\/+/, ''); + } else rest = raw.replace(/^github\.com\//i, ''); + const parts = rest.replace(/\/+$/, '').split('/').filter(Boolean); + const owner = parts[0]; + const repo = parts[1]?.replace(/\.git$/i, ''); + if (!owner || !repo || !NAME.test(owner) || !NAME.test(repo)) throw new GitHubError('Expected a repository in the form owner/name', 400); + let branch: string | null = null; + let subdirectory: string | null = null; + if ((parts[2] === 'tree' || parts[2] === 'blob') && parts[3]) { + // Branch names may contain slashes; the first segment is taken and can be corrected in the form. + branch = decodeURIComponent(parts[3]); + if (parts.length > 4) subdirectory = parts.slice(4).map(decodeURIComponent).join('/'); + } + return { owner, repo, branch, subdirectory }; +} + +export interface GitHubRepoInfo { + owner: string; + repo: string; + fullName: string; + description: string | null; + defaultBranch: string; + branches: string[]; + private: boolean; + sizeKb: number; + htmlUrl: string; +} + +const MAX_REPO_KB = 1024 * 1024; // 1 GB as reported by GitHub + +export class GitHubClient { + private octokit: Octokit; + + constructor(opts: { token?: string | null; fetch?: typeof fetch } = {}) { + this.octokit = new Octokit({ + auth: opts.token || undefined, + userAgent: 'vectora-local-engine', + request: opts.fetch ? { fetch: opts.fetch } : undefined, + retry: { enabled: false }, + throttle: { enabled: false }, + log: { debug: () => undefined, info: () => undefined, warn: () => undefined, error: () => undefined }, + }); + } + + private wrap(err: unknown, hasToken: boolean): GitHubError { + const status = (err as { status?: number }).status ?? 502; + if (status === 404) return new GitHubError(hasToken ? 'Repository not found, or the credential has no access to it' : 'Repository not found. If it is private, add an access token.', 404); + if (status === 401) return new GitHubError('GitHub rejected the access token', 401); + if (status === 403 || status === 429) return new GitHubError('GitHub refused the request (rate limit or insufficient permission). An access token raises the limit.', 403); + return new GitHubError(`GitHub could not be reached (${status})`, 502); + } + + async describe(ref: Pick, hasToken = false): Promise { + try { + const { data } = await this.octokit.rest.repos.get({ owner: ref.owner, repo: ref.repo }); + let branches: string[] = []; + try { + const res = await this.octokit.rest.repos.listBranches({ owner: ref.owner, repo: ref.repo, per_page: 100 }); + branches = res.data.map((b) => b.name); + } catch { + branches = []; + } + if (!branches.includes(data.default_branch)) branches.unshift(data.default_branch); + return { + owner: data.owner.login, + repo: data.name, + fullName: data.full_name, + description: data.description, + defaultBranch: data.default_branch, + branches, + private: data.private, + sizeKb: data.size, + htmlUrl: data.html_url, + }; + } catch (err) { + throw this.wrap(err, hasToken); + } + } + + /** Downloads the source archive of a branch to `destFile`. */ + async downloadArchive(ref: Pick, branch: string, destFile: string, hasToken = false): Promise { + const info = await this.describe(ref, hasToken); + if (info.sizeKb > MAX_REPO_KB) throw new GitHubError('Repository is larger than the 1 GB import limit', 413); + try { + const res = await this.octokit.request('GET /repos/{owner}/{repo}/zipball/{ref}', { owner: ref.owner, repo: ref.repo, ref: branch }); + const buf = Buffer.from(res.data as ArrayBuffer); + fs.writeFileSync(destFile, buf); + return buf.length; + } catch (err) { + throw this.wrap(err, hasToken); + } + } +} diff --git a/apps/local-engine/src/main.ts b/apps/local-engine/src/main.ts new file mode 100644 index 0000000..8f5e148 --- /dev/null +++ b/apps/local-engine/src/main.ts @@ -0,0 +1,21 @@ +import { loadConfig } from './config'; +import { buildServer } from './server'; + +const config = loadConfig(); +const { app } = await buildServer(config); + +const shutdown = async (signal: string) => { + app.log.info(`${signal} received, shutting down`); + await app.close(); + process.exit(0); +}; +process.on('SIGINT', () => void shutdown('SIGINT')); +process.on('SIGTERM', () => void shutdown('SIGTERM')); + +try { + await app.listen({ host: config.host, port: config.port }); + app.log.info(`VECTORA engine ready at http://${config.host}:${config.port} (data: ${config.dataDir}${config.webDist ? ', serving web application' : ''})`); +} catch (err) { + app.log.error(err); + process.exit(1); +} diff --git a/apps/local-engine/src/provider.ts b/apps/local-engine/src/provider.ts new file mode 100644 index 0000000..ebbafca --- /dev/null +++ b/apps/local-engine/src/provider.ts @@ -0,0 +1,65 @@ +/** + * Optional narrative provider. + * + * Disabled by default. When the user enables it and supplies an endpoint that + * speaks the widely used "chat completions" HTTP format, the statements that + * were already retrieved from the graph are sent to it to be rewritten as + * prose. Only those statements (file paths, symbol names, short evidence + * lines) are sent — never whole files — and the provider cannot add facts: + * the evidence list shown to the user always comes from the graph. + */ +import type { ExplorationAnswer } from '@vectora/shared'; + +export interface ProviderConfig { + endpoint: string; + model: string; + apiKey: string | null; + fetch?: typeof fetch; +} + +export interface NarrativeProvider { + summarize(answer: ExplorationAnswer): Promise; +} + +export function createChatCompletionsProvider(cfg: ProviderConfig): NarrativeProvider { + return { + async summarize(answer) { + const url = new URL(cfg.endpoint); + if (url.protocol !== 'https:' && !['localhost', '127.0.0.1', '[::1]'].includes(url.hostname)) throw new Error('The provider endpoint must use HTTPS'); + const facts = answer.statements + .slice(0, 60) + .map((s, i) => `${i + 1}. ${s.verified ? '[verified]' : '[derived]'} ${s.text}${s.evidence[0] ? ` (${s.evidence[0].path}:${s.evidence[0].startLine})` : ''}`) + .join('\n'); + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), 30_000); + try { + const res = await (cfg.fetch ?? fetch)(url, { + method: 'POST', + signal: controller.signal, + headers: { 'content-type': 'application/json', ...(cfg.apiKey ? { authorization: `Bearer ${cfg.apiKey}` } : {}) }, + body: JSON.stringify({ + model: cfg.model, + temperature: 0, + messages: [ + { + role: 'system', + content: + 'Rewrite the numbered findings about a software repository as a short, plain explanation. Use only the findings. Keep file references. Say clearly which points are derived rather than verified. Do not add anything that is not in the findings.', + }, + { role: 'user', content: `Question: ${answer.question}\n\nFindings:\n${facts}\n\nKnown limits:\n${answer.caveats.join('\n') || 'none'}` }, + ], + }), + }); + if (!res.ok) throw new Error(`provider returned ${res.status}`); + const data = (await res.json()) as { choices?: { message?: { content?: string } }[] }; + const text = data.choices?.[0]?.message?.content?.trim(); + if (!text) throw new Error('provider returned no text'); + return text.slice(0, 6000); + } finally { + clearTimeout(timer); + } + }, + }; +} + +export const summarizeWithProvider = (cfg: ProviderConfig, answer: ExplorationAnswer): Promise => createChatCompletionsProvider(cfg).summarize(answer); diff --git a/apps/local-engine/src/security.ts b/apps/local-engine/src/security.ts new file mode 100644 index 0000000..7ac2dfd --- /dev/null +++ b/apps/local-engine/src/security.ts @@ -0,0 +1,281 @@ +/** + * Security helpers: credential encryption at rest, safe archive extraction + * and path containment checks. + */ +import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto'; +import fs from 'node:fs'; +import path from 'node:path'; +import { pipeline } from 'node:stream/promises'; +import ignore from 'ignore'; +import yauzl from 'yauzl'; +import { isBinaryPath } from '@vectora/language-adapters'; + +// --------------------------------------------------------------------------- +// Credentials: AES-256-GCM with a key file kept in the data directory. +// --------------------------------------------------------------------------- + +export class CredentialVault { + private key: Buffer; + + constructor(dataDir: string) { + const file = path.join(dataDir, 'vault.key'); + if (fs.existsSync(file)) { + this.key = Buffer.from(fs.readFileSync(file, 'utf8').trim(), 'base64'); + if (this.key.length !== 32) throw new Error('Credential key file is corrupt'); + } else { + fs.mkdirSync(dataDir, { recursive: true }); + this.key = randomBytes(32); + fs.writeFileSync(file, this.key.toString('base64'), { mode: 0o600 }); + } + } + + encrypt(plain: string): string { + const iv = randomBytes(12); + const cipher = createCipheriv('aes-256-gcm', this.key, iv); + const data = Buffer.concat([cipher.update(plain, 'utf8'), cipher.final()]); + return ['v1', iv.toString('base64'), cipher.getAuthTag().toString('base64'), data.toString('base64')].join(':'); + } + + decrypt(stored: string): string { + const [version, iv, tag, data] = stored.split(':'); + if (version !== 'v1' || !iv || !tag || !data) throw new Error('Unsupported credential format'); + const decipher = createDecipheriv('aes-256-gcm', this.key, Buffer.from(iv, 'base64')); + decipher.setAuthTag(Buffer.from(tag, 'base64')); + return Buffer.concat([decipher.update(Buffer.from(data, 'base64')), decipher.final()]).toString('utf8'); + } +} + +// --------------------------------------------------------------------------- +// Path containment +// --------------------------------------------------------------------------- + +/** Resolves `rel` under `root` and guarantees the result does not escape it. */ +export function resolveInside(root: string, rel: string): string | null { + if (rel.includes('\0')) return null; + const base = path.resolve(root); + const target = path.resolve(base, rel); + const relative = path.relative(base, target); + if (relative.startsWith('..') || path.isAbsolute(relative)) return null; + return target; +} + +// --------------------------------------------------------------------------- +// ZIP handling +// --------------------------------------------------------------------------- + +export interface ZipLimits { + maxEntries: number; + maxTotalBytes: number; + maxFileBytes: number; + /** Uncompressed / compressed ratio above which an entry is rejected as a decompression bomb. */ + maxRatio: number; +} + +export const DEFAULT_ZIP_LIMITS: ZipLimits = { + maxEntries: 100_000, + maxTotalBytes: 2 * 1024 * 1024 * 1024, + maxFileBytes: 8 * 1024 * 1024, + maxRatio: 200, +}; + +export class ArchiveError extends Error { + constructor( + message: string, + public code: 'invalid-archive' | 'too-many-entries' | 'too-large' | 'empty', + ) { + super(message); + } +} + +export interface ZipEntryInfo { + path: string; + size: number; + directory: boolean; +} + +/** Why an archive entry is not safe to extract, or null when it is. */ +export function unsafeEntryReason(name: string): string | null { + if (!name || name.includes('\0')) return 'empty or NUL in name'; + const n = name.replace(/\\/g, '/'); + if (n.startsWith('/') || /^[a-zA-Z]:/.test(n)) return 'absolute path'; + const parts = n.split('/').filter((p) => p !== ''); + if (parts.some((p) => p === '..')) return 'parent directory traversal'; + if (parts.some((p) => /[<>:"|?*\u0000-\u001f]/.test(p))) return 'characters not allowed in file names'; + if (parts.some((p) => /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i.test(p))) return 'reserved device name'; + if (parts.some((p) => p.length > 255) || n.length > 1024) return 'name too long'; + if (parts.some((p) => /[. ]$/.test(p) && p !== '.')) return 'trailing dot or space'; + return null; +} + +const isSymlinkEntry = (entry: yauzl.Entry): boolean => ((entry.externalFileAttributes >>> 16) & 0o170000) === 0o120000; + +function openZip(file: string): Promise { + return new Promise((resolve, reject) => { + // strictFileNames rejects backslashes; decodeStrings + validateEntrySizes are yauzl defaults. + yauzl.open(file, { lazyEntries: true, autoClose: true, validateEntrySizes: true }, (err, zip) => { + if (err || !zip) reject(new ArchiveError(`Not a readable ZIP archive: ${err?.message ?? 'unknown error'}`, 'invalid-archive')); + else resolve(zip); + }); + }); +} + +export function isZipFile(file: string): boolean { + try { + const fd = fs.openSync(file, 'r'); + const buf = Buffer.alloc(4); + fs.readSync(fd, buf, 0, 4, 0); + fs.closeSync(fd); + // Local file header, or end-of-central-directory for an empty archive. + return buf[0] === 0x50 && buf[1] === 0x4b && ((buf[2] === 3 && buf[3] === 4) || (buf[2] === 5 && buf[3] === 6)); + } catch { + return false; + } +} + +export interface ZipInspection { + entries: number; + files: number; + totalBytes: number; + rejected: { path: string; reason: string }[]; + /** Candidate project roots inside the archive ('' is the archive root). */ + roots: { path: string; files: number; markers: string[] }[]; + tree: ZipEntryInfo[]; +} + +const ROOT_MARKERS = new Set([ + 'package.json', 'pyproject.toml', 'setup.py', 'requirements.txt', 'go.mod', 'cargo.toml', 'pom.xml', 'build.gradle', 'build.gradle.kts', + 'cmakelists.txt', 'makefile', '.gitignore', 'readme.md', 'tsconfig.json', +]); + +/** Lists an archive without extracting it and suggests project roots. */ +export async function inspectZip(file: string, limits: ZipLimits = DEFAULT_ZIP_LIMITS): Promise { + if (!isZipFile(file)) throw new ArchiveError('The file is not a ZIP archive', 'invalid-archive'); + const zip = await openZip(file); + const result: ZipInspection = { entries: 0, files: 0, totalBytes: 0, rejected: [], roots: [], tree: [] }; + const dirFiles = new Map(); + const dirMarkers = new Map>(); + const top = new Map(); + await new Promise((resolve, reject) => { + zip.on('error', (e) => reject(new ArchiveError(`Archive is damaged: ${(e as Error).message}`, 'invalid-archive'))); + zip.on('end', resolve); + zip.on('entry', (entry: yauzl.Entry) => { + result.entries++; + if (result.entries > limits.maxEntries) { + zip.close(); + return reject(new ArchiveError(`Archive has more than ${limits.maxEntries} entries`, 'too-many-entries')); + } + const name = entry.fileName.replace(/\\/g, '/'); + const directory = name.endsWith('/'); + const reason = unsafeEntryReason(name) ?? (isSymlinkEntry(entry) ? 'symbolic link' : null); + if (reason) { + if (result.rejected.length < 50) result.rejected.push({ path: name.slice(0, 200), reason }); + } else if (!directory) { + result.files++; + result.totalBytes += entry.uncompressedSize; + if (result.totalBytes > limits.maxTotalBytes) { + zip.close(); + return reject(new ArchiveError('Archive is larger than the allowed uncompressed size', 'too-large')); + } + const parts = name.split('/'); + const base = parts[parts.length - 1]!.toLowerCase(); + for (let d = 0; d < Math.min(parts.length, 4); d++) { + const dir = parts.slice(0, d).join('/'); + dirFiles.set(dir, (dirFiles.get(dir) ?? 0) + 1); + } + const dir = parts.slice(0, -1).join('/'); + if (ROOT_MARKERS.has(base) && parts.length <= 4) (dirMarkers.get(dir) ?? dirMarkers.set(dir, new Set()).get(dir)!).add(parts[parts.length - 1]!); + // Two-level preview of the structure. + const key = parts.slice(0, 2).join('/'); + if (top.size < 300 && !top.has(key)) top.set(key, { path: key, size: parts.length <= 2 ? entry.uncompressedSize : 0, directory: parts.length > 2 }); + if (parts.length > 1 && !top.has(parts[0]!)) top.set(parts[0]!, { path: parts[0]!, size: 0, directory: true }); + } + zip.readEntry(); + }); + zip.readEntry(); + }); + if (result.files === 0) throw new ArchiveError('The archive contains no files', 'empty'); + // A single wrapping directory (as produced by GitHub and most tools) is the natural root. + const topDirs = [...dirFiles.keys()].filter((d) => d && !d.includes('/')); + const rootFiles = dirFiles.get('') ?? 0; + const nested = topDirs.length === 1 && dirFiles.get(topDirs[0]!) === rootFiles ? topDirs[0]! : ''; + const candidates = new Set([nested, ...dirMarkers.keys()]); + result.roots = [...candidates] + .map((p) => ({ path: p, files: dirFiles.get(p) ?? 0, markers: [...(dirMarkers.get(p) ?? [])].sort() })) + .filter((r) => r.files > 0) + .sort((a, b) => (a.path === nested ? -1 : b.path === nested ? 1 : b.markers.length - a.markers.length || a.path.length - b.path.length)) + .slice(0, 12); + result.tree = [...top.values()].sort((a, b) => (a.path < b.path ? -1 : 1)); + return result; +} + +export interface ExtractOptions { + /** Only extract entries under this archive path; it is stripped from the output paths. */ + root?: string; + ignorePatterns?: string[]; + limits?: Partial; +} + +export interface ExtractResult { + files: number; + bytes: number; + skipped: { unsafe: number; symlinks: number; ignored: number; binary: number; oversized: number }; +} + +/** + * Extracts an archive into `destDir`. Entries that would escape the + * destination, symbolic links, ignored paths, binary files and oversized + * files are skipped and counted — they are never written to disk. + */ +export async function extractZip(file: string, destDir: string, opts: ExtractOptions = {}): Promise { + if (!isZipFile(file)) throw new ArchiveError('The file is not a ZIP archive', 'invalid-archive'); + const limits = { ...DEFAULT_ZIP_LIMITS, ...opts.limits }; + const root = (opts.root ?? '').replace(/\\/g, '/').replace(/^\/+|\/+$/g, ''); + const ig = ignore().add(['node_modules/', '.git/', ...(opts.ignorePatterns ?? [])]); + const dest = path.resolve(destDir); + fs.mkdirSync(dest, { recursive: true }); + const zip = await openZip(file); + const result: ExtractResult = { files: 0, bytes: 0, skipped: { unsafe: 0, symlinks: 0, ignored: 0, binary: 0, oversized: 0 } }; + let entries = 0; + await new Promise((resolve, reject) => { + const fail = (e: Error) => { + zip.close(); + reject(e); + }; + zip.on('error', (e) => reject(new ArchiveError(`Archive is damaged: ${(e as Error).message}`, 'invalid-archive'))); + zip.on('end', resolve); + zip.on('entry', (entry: yauzl.Entry) => { + if (++entries > limits.maxEntries) return fail(new ArchiveError(`Archive has more than ${limits.maxEntries} entries`, 'too-many-entries')); + const name = entry.fileName.replace(/\\/g, '/'); + const next = () => zip.readEntry(); + if (name.endsWith('/')) return next(); + if (unsafeEntryReason(name)) return result.skipped.unsafe++, next(); + if (isSymlinkEntry(entry)) return result.skipped.symlinks++, next(); + if (root && !name.startsWith(`${root}/`)) return next(); + const rel = root ? name.slice(root.length + 1) : name; + if (!rel) return next(); + if (ig.ignores(rel)) return result.skipped.ignored++, next(); + if (isBinaryPath(rel)) return result.skipped.binary++, next(); + const tooBig = entry.uncompressedSize > limits.maxFileBytes; + const bomb = entry.compressedSize > 0 && entry.uncompressedSize / entry.compressedSize > limits.maxRatio && entry.uncompressedSize > 1024 * 1024; + if (tooBig || bomb) return result.skipped.oversized++, next(); + if (result.bytes + entry.uncompressedSize > limits.maxTotalBytes) return fail(new ArchiveError('Archive is larger than the allowed uncompressed size', 'too-large')); + const target = resolveInside(dest, rel); + if (!target) return result.skipped.unsafe++, next(); + zip.openReadStream(entry, (err, stream) => { + if (err || !stream) return fail(new ArchiveError(`Archive entry could not be read: ${err?.message ?? ''}`, 'invalid-archive')); + fs.mkdirSync(path.dirname(target), { recursive: true }); + // `wx`: never overwrite; an entry listed twice cannot replace an earlier one. + pipeline(stream, fs.createWriteStream(target, { flags: 'wx', mode: 0o644 })) + .then(() => { + result.files++; + result.bytes += entry.uncompressedSize; + next(); + }) + .catch((e: NodeJS.ErrnoException) => (e.code === 'EEXIST' ? next() : fail(new ArchiveError(`Extraction failed: ${e.message}`, 'invalid-archive')))); + }); + }); + zip.readEntry(); + }); + if (result.files === 0) throw new ArchiveError('No source files could be extracted from the archive', 'empty'); + return result; +} diff --git a/apps/local-engine/src/server.ts b/apps/local-engine/src/server.ts new file mode 100644 index 0000000..abace13 --- /dev/null +++ b/apps/local-engine/src/server.ts @@ -0,0 +1,249 @@ +/** + * HTTP API of the local engine. Listens on the loopback interface only, + * rejects cross-origin and DNS-rebinding requests, and never logs request + * bodies or credentials. + */ +import fs from 'node:fs'; +import { pipeline } from 'node:stream/promises'; +import cors from '@fastify/cors'; +import multipart from '@fastify/multipart'; +import fastifyStatic from '@fastify/static'; +import Fastify, { type FastifyInstance } from 'fastify'; +import { z } from 'zod'; +import { NODE_TYPES } from '@vectora/graph-schema'; +import { SUPPORTED_LANGUAGES, findPython } from '@vectora/language-adapters'; +import { APP_VERSION, type SessionState, redactSecrets } from '@vectora/shared'; +import type { EngineConfig } from './config'; +import { GitHubError } from './github'; +import { Engine, EngineError } from './service'; + +const LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '[::1]']); +const MAX_UPLOAD_BYTES = 512 * 1024 * 1024; + +const hostName = (header: string | undefined): string => { + if (!header) return ''; + const h = header.trim().toLowerCase(); + return h.startsWith('[') ? h.slice(0, h.indexOf(']') + 1) : h.split(':')[0]!; +}; + +export async function buildServer(config: EngineConfig): Promise<{ app: FastifyInstance; engine: Engine }> { + const app = Fastify({ + bodyLimit: 2 * 1024 * 1024, + logger: + config.logLevel === 'silent' + ? false + : { + level: config.logLevel, + // Request bodies are never logged; headers that can carry secrets are removed. + redact: { paths: ['req.headers.authorization', 'req.headers.cookie', 'req.headers["x-api-key"]'], remove: true }, + serializers: { + req: (req) => ({ method: req.method, url: redactSecrets(req.url.split('?')[0] ?? ''), id: req.id }), + // Stack traces are kept out of release logs. + err: (err: Error) => ({ type: err.name, message: redactSecrets(err.message), stack: config.production ? '' : redactSecrets(err.stack ?? '') }), + }, + }, + }); + const engine = new Engine(config, { + info: (m) => app.log.info(redactSecrets(m)), + warn: (m) => app.log.warn(redactSecrets(m)), + error: (m) => app.log.error(redactSecrets(m)), + }); + app.addHook('onClose', async () => engine.close()); + + const allowedOrigins = new Set(config.allowedOrigins); + await app.register(cors, { + origin: (origin, cb) => cb(null, !origin || allowedOrigins.has(origin)), + methods: ['GET', 'POST', 'PUT', 'DELETE'], + credentials: false, + }); + await app.register(multipart, { limits: { fileSize: MAX_UPLOAD_BYTES, files: 1, fields: 4 } }); + + app.addHook('onRequest', async (req, reply) => { + // DNS-rebinding protection: the Host header must name the loopback interface. + const host = hostName(req.headers.host); + if (!LOOPBACK_HOSTS.has(host) && host !== config.host) return reply.code(403).send({ error: 'Forbidden host' }); + // Cross-site request protection: browsers send Origin on cross-origin and state-changing requests. + const origin = req.headers.origin; + if (origin) { + let originHost = ''; + try { + originHost = new URL(origin).host; + } catch { + return reply.code(403).send({ error: 'Forbidden origin' }); + } + if (originHost !== req.headers.host && !allowedOrigins.has(origin)) return reply.code(403).send({ error: 'Forbidden origin' }); + } + if (req.method !== 'GET' && req.method !== 'HEAD' && req.method !== 'OPTIONS' && req.headers['sec-fetch-site'] === 'cross-site') return reply.code(403).send({ error: 'Forbidden origin' }); + }); + app.addHook('onSend', async (_req, reply) => { + reply.header('X-Content-Type-Options', 'nosniff'); + reply.header('Referrer-Policy', 'no-referrer'); + reply.header('X-Frame-Options', 'DENY'); + reply.header('Cross-Origin-Resource-Policy', 'same-origin'); + reply.header( + 'Content-Security-Policy', + "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; worker-src 'self' blob:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'", + ); + }); + + app.setErrorHandler((err: Error & { statusCode?: number; validation?: unknown }, req, reply) => { + if (err instanceof EngineError || err instanceof GitHubError) return reply.code(err.status).send({ error: err.message }); + if (err instanceof z.ZodError) return reply.code(400).send({ error: 'Invalid request', details: err.issues.map((i) => `${i.path.join('.')}: ${i.message}`) }); + if (err.statusCode && err.statusCode < 500) return reply.code(err.statusCode).send({ error: err.message }); + req.log.error({ err }, 'request failed'); + return reply.code(500).send({ error: 'Internal error' }); + }); + + const idParams = z.object({ id: z.string().uuid() }); + + // ---- meta --------------------------------------------------------------- + app.get('/api/health', async () => ({ + status: 'ok', + version: APP_VERSION, + node: process.version, + python: !!findPython(process.env.VECTORA_PYTHON), + sampleAvailable: !!config.sampleDir, + languages: SUPPORTED_LANGUAGES.map((l) => ({ id: l.id, name: l.name, tier: l.tier, extensions: l.extensions })), + })); + + // ---- repositories ------------------------------------------------------- + app.get('/api/repositories', async () => engine.listRepositories()); + app.get('/api/repositories/:id', async (req) => engine.getRepository(idParams.parse(req.params).id)); + app.delete('/api/repositories/:id', async (req, reply) => { + engine.deleteRepository(idParams.parse(req.params).id); + return reply.code(204).send(); + }); + app.post('/api/repositories/:id/reindex', async (req) => { + const body = z.object({ full: z.boolean().optional() }).parse(req.body ?? {}); + return engine.reindex(idParams.parse(req.params).id, body.full ?? false); + }); + + // ---- imports ------------------------------------------------------------ + app.post('/api/import/local', async (req) => { + const body = z.object({ path: z.string().min(1).max(1024), name: z.string().max(120).optional() }).parse(req.body); + return engine.importLocal(body.path, body.name); + }); + app.post('/api/import/sample', async () => engine.importSample()); + app.get('/api/fs/list', async (req) => engine.listDirectory(z.object({ path: z.string().max(1024).optional() }).parse(req.query).path)); + + app.post('/api/import/zip/inspect', async (req) => { + const part = await req.file(); + if (!part) throw new EngineError('No file was uploaded', 400); + const { id, file } = engine.newUploadPath(); + await pipeline(part.file, fs.createWriteStream(file, { flags: 'wx' })); + if (part.file.truncated) { + fs.rmSync(file, { force: true }); + throw new EngineError('The archive is larger than the 512 MB upload limit', 413); + } + return engine.registerUpload(id, file, part.filename ?? 'archive.zip'); + }); + app.post('/api/import/zip', async (req) => { + const body = z.object({ uploadId: z.string().uuid(), root: z.string().max(512).optional(), name: z.string().max(120).optional() }).parse(req.body); + return engine.importZip(body.uploadId, body.root, body.name); + }); + + const githubBody = z.object({ + url: z.string().min(1).max(500), + branch: z.string().max(250).nullish(), + subdirectory: z.string().max(500).nullish(), + token: z.string().max(400).nullish(), + rememberToken: z.boolean().optional(), + }); + app.post('/api/import/github/validate', async (req) => { + const body = githubBody.pick({ url: true, token: true }).parse(req.body); + return engine.validateGitHub(body.url, body.token); + }); + app.post('/api/import/github', async (req) => engine.importGitHub(githubBody.parse(req.body))); + + // ---- jobs --------------------------------------------------------------- + app.get('/api/jobs', async () => engine.activeJobs()); + app.get('/api/jobs/:id', async (req) => engine.getJob(idParams.parse(req.params).id)); + + // ---- graph and analysis ------------------------------------------------- + app.get('/api/repositories/:id/graph', async (req) => { + const q = z.object({ detail: z.enum(['full', 'structure']).optional() }).parse(req.query); + return engine.getGraph(idParams.parse(req.params).id, q.detail ?? 'full'); + }); + app.get('/api/repositories/:id/members', async (req) => { + const q = z.object({ path: z.string().min(1).max(1024) }).parse(req.query); + return engine.getFileMembers(idParams.parse(req.params).id, q.path); + }); + app.get('/api/repositories/:id/overview', async (req) => engine.getOverview(idParams.parse(req.params).id)); + app.get('/api/repositories/:id/analysis', async (req) => engine.getAnalysis(idParams.parse(req.params).id)); + app.get('/api/repositories/:id/source', async (req) => { + const q = z.object({ path: z.string().min(1).max(1024), start: z.coerce.number().int().min(1).optional(), end: z.coerce.number().int().min(1).optional() }).parse(req.query); + return engine.getSource(idParams.parse(req.params).id, q.path, q.start, q.end); + }); + app.get('/api/repositories/:id/docs', async (req) => engine.listDocs(idParams.parse(req.params).id)); + app.get('/api/repositories/:id/search', async (req) => { + const q = z.object({ q: z.string().max(200), types: z.string().max(400).optional(), limit: z.coerce.number().int().min(1).max(100).optional() }).parse(req.query); + const types = q.types?.split(',').filter((t) => (NODE_TYPES as readonly string[]).includes(t)); + return engine.search(idParams.parse(req.params).id, q.q, types?.length ? types : undefined, q.limit); + }); + app.post('/api/repositories/:id/ask', async (req) => { + const body = z.object({ question: z.string().min(2).max(500) }).parse(req.body); + return engine.ask(idParams.parse(req.params).id, body.question); + }); + app.get('/api/repositories/:id/export/:format', async (req, reply) => { + const p = z.object({ id: z.string().uuid(), format: z.enum(['json', 'graphml', 'markdown', 'architecture']) }).parse(req.params); + const q = z.object({ includeSource: z.enum(['true', 'false']).optional() }).parse(req.query); + const out = engine.export(p.id, p.format, q.includeSource === 'true'); + return reply + .header('Content-Type', `${out.contentType}; charset=utf-8`) + .header('Content-Disposition', `attachment; filename="${out.fileName}"`) + .send(out.body); + }); + + // ---- sessions ----------------------------------------------------------- + const sessionBody = z.object({ + view: z.string().max(40), + selectedIds: z.array(z.string().max(1200)).max(500), + focusId: z.string().max(1200).nullable(), + expandedIds: z.array(z.string().max(1200)).max(5000), + hiddenNodeTypes: z.array(z.string().max(40)).max(40), + hiddenEdgeTypes: z.array(z.string().max(40)).max(40), + layouts: z.record(z.string(), z.unknown()), + savedAt: z.string().optional(), + }); + app.get('/api/repositories/:id/session', async (req) => engine.getSession(idParams.parse(req.params).id) ?? null); + app.put('/api/repositories/:id/session', { bodyLimit: 16 * 1024 * 1024 }, async (req, reply) => { + engine.saveSession(idParams.parse(req.params).id, sessionBody.parse(req.body) as unknown as SessionState); + return reply.code(204).send(); + }); + + // ---- settings, credentials, local data --------------------------------- + app.get('/api/settings', async () => engine.getSettings()); + app.put('/api/settings', async (req) => engine.updateSettings(req.body)); + app.get('/api/credentials', async () => engine.listCredentials()); + const credParams = z.object({ name: z.enum(['github', 'exploration-provider']) }); + app.put('/api/credentials/:name', async (req, reply) => { + engine.setCredential(credParams.parse(req.params).name, z.object({ value: z.string().min(1).max(4096) }).parse(req.body).value); + return reply.code(204).send(); + }); + app.delete('/api/credentials/:name', async (req, reply) => { + engine.deleteCredential(credParams.parse(req.params).name); + return reply.code(204).send(); + }); + app.get('/api/data', async () => engine.dataInfo()); + app.delete('/api/data', async (_req, reply) => { + engine.deleteAllData(); + return reply.code(204).send(); + }); + app.delete('/api/cache', async (_req, reply) => { + engine.clearCache(); + return reply.code(204).send(); + }); + + // ---- web application ---------------------------------------------------- + if (config.webDist) { + await app.register(fastifyStatic, { root: config.webDist, wildcard: false, maxAge: '1h', immutable: false }); + app.setNotFoundHandler((req, reply) => { + if (req.method === 'GET' && !req.url.startsWith('/api/')) return reply.header('Cache-Control', 'no-cache').sendFile('index.html'); + return reply.code(404).send({ error: 'Not found' }); + }); + } else { + app.setNotFoundHandler((_req, reply) => reply.code(404).send({ error: 'Not found' })); + } + + return { app, engine }; +} diff --git a/apps/local-engine/src/service.ts b/apps/local-engine/src/service.ts new file mode 100644 index 0000000..3c43925 --- /dev/null +++ b/apps/local-engine/src/service.ts @@ -0,0 +1,682 @@ +/** + * Engine service: repository imports, indexing jobs, graph queries, exports + * and local data management. The HTTP layer in `server.ts` is a thin wrapper. + */ +import { randomUUID } from 'node:crypto'; +import fs from 'node:fs'; +import path from 'node:path'; +import { + type GraphIndex, + type RepositoryAnalysis, + Store, + type StoredRepository, + buildIndex, + buildOverview, + explore, + exportArchitectureDoc, + exportGraphML, + exportJson, + exportMarkdownAnalysis, +} from '@vectora/graph-engine'; +import { type GraphEdge, type GraphNode, type KnowledgeGraph, STRUCTURAL_TYPES, normalizePath } from '@vectora/graph-schema'; +import type { FileFacts } from '@vectora/language-adapters'; +import { indexRepository } from '@vectora/repository-indexer'; +import { SearchIndex, searchDocuments } from '@vectora/search'; +import { + type ExplorationAnswer, + INDEX_STAGES, + INDEX_STAGE_LABELS, + type IndexStage, + type JobProgress, + type RepositoryOverview, + type RepositoryRecord, + type SessionState, + type Settings, + type SourceResponse, + mergeSettings, + redactSecrets, +} from '@vectora/shared'; +import type { EngineConfig } from './config'; +import { GitHubClient, type GitHubRef, type GitHubRepoInfo, parseGitHubUrl } from './github'; +import { summarizeWithProvider } from './provider'; +import { ArchiveError, CredentialVault, type ZipInspection, extractZip, inspectZip, resolveInside } from './security'; + +export class EngineError extends Error { + constructor( + message: string, + public status = 400, + ) { + super(message); + } +} + +interface LoadedRepo { + graph: KnowledgeGraph; + index: GraphIndex; + search: SearchIndex; + analysis: RepositoryAnalysis | null; + docs: { path: string; content: string }[] | null; +} + +const MAX_SOURCE_BYTES = 2 * 1024 * 1024; +const toRecord = (r: StoredRepository): RepositoryRecord => { + // The absolute path of managed copies is an implementation detail; local paths are shown as the origin already. + const { rootPath: _rootPath, managedSource: _managed, ...rest } = r; + return rest; +}; + +export class Engine { + readonly store: Store; + readonly vault: CredentialVault; + private jobs = new Map(); + private queue: Promise = Promise.resolve(); + private loaded = new Map(); + private uploads = new Map(); + readonly sourcesDir: string; + readonly uploadsDir: string; + + constructor( + readonly config: EngineConfig, + private log: { info: (msg: string) => void; warn: (msg: string) => void; error: (msg: string) => void } = console, + ) { + fs.mkdirSync(config.dataDir, { recursive: true }); + this.sourcesDir = path.join(config.dataDir, 'sources'); + this.uploadsDir = path.join(config.dataDir, 'uploads'); + fs.mkdirSync(this.sourcesDir, { recursive: true }); + fs.mkdirSync(this.uploadsDir, { recursive: true }); + this.store = new Store(path.join(config.dataDir, 'vectora.db')); + this.vault = new CredentialVault(config.dataDir); + // Jobs do not survive a restart: anything left mid-index is marked as failed. + for (const r of this.store.listRepositories()) + if (r.status === 'indexing' || r.status === 'pending') this.store.updateRepository(r.id, { status: 'failed', error: 'Indexing was interrupted. Re-index to continue.' }); + this.cleanUploads(0); + } + + close(): void { + this.store.close(); + } + + // ---- repositories ------------------------------------------------------- + + listRepositories(): RepositoryRecord[] { + return this.store.listRepositories().map(toRecord); + } + + private repo(id: string): StoredRepository { + const r = this.store.getRepository(id); + if (!r) throw new EngineError('Repository not found', 404); + return r; + } + + getRepository(id: string): RepositoryRecord { + return toRecord(this.repo(id)); + } + + deleteRepository(id: string): void { + const r = this.repo(id); + this.store.deleteRepository(id); + this.loaded.delete(id); + if (r.managedSource) this.removeManagedDir(r.rootPath); + } + + /** Deletes a directory only when it lies inside VECTORA's own sources folder. */ + private removeManagedDir(dir: string): void { + const rel = path.relative(this.sourcesDir, path.resolve(dir)); + if (!rel || rel.startsWith('..') || path.isAbsolute(rel)) return; + const top = path.join(this.sourcesDir, rel.split(path.sep)[0]!); + fs.rmSync(top, { recursive: true, force: true }); + } + + private createRepository(fields: Pick & { id?: string }): StoredRepository { + const repo: StoredRepository = { + id: fields.id ?? randomUUID(), + name: fields.name, + sourceKind: fields.sourceKind, + origin: fields.origin, + branch: fields.branch, + subdirectory: fields.subdirectory, + rootPath: fields.rootPath, + managedSource: fields.managedSource, + status: 'pending', + createdAt: new Date().toISOString(), + lastIndexedAt: null, + fileCount: 0, + symbolCount: 0, + relationshipCount: 0, + error: null, + }; + this.store.insertRepository(repo); + return repo; + } + + // ---- jobs --------------------------------------------------------------- + + getJob(id: string): JobProgress { + const j = this.jobs.get(id); + if (!j) throw new EngineError('Job not found', 404); + return j; + } + + activeJobs(): JobProgress[] { + return [...this.jobs.values()].filter((j) => j.status === 'running'); + } + + private newJob(repositoryId: string | null): JobProgress { + const job: JobProgress = { + id: randomUUID(), + repositoryId, + status: 'running', + stage: 'acquire', + stageIndex: 0, + message: 'Waiting to start', + processed: 0, + total: 0, + startedAt: new Date().toISOString(), + finishedAt: null, + error: null, + summary: null, + }; + this.jobs.set(job.id, job); + // Keep the job table small. + if (this.jobs.size > 50) for (const [id, j] of this.jobs) if (j.status !== 'running' && this.jobs.size > 40) this.jobs.delete(id); + return job; + } + + private setStage(job: JobProgress, stage: IndexStage, message?: string, processed = 0, total = 0): void { + job.stage = stage; + job.stageIndex = INDEX_STAGES.indexOf(stage); + job.message = message ?? INDEX_STAGE_LABELS[stage]; + job.processed = processed; + job.total = total; + } + + /** Runs jobs one at a time so indexing never competes with itself for memory. */ + private enqueue(job: JobProgress, work: () => Promise): void { + this.queue = this.queue.then(async () => { + try { + await work(); + job.status = 'completed'; + } catch (err) { + const message = redactSecrets(err instanceof Error ? err.message : String(err)); + job.status = 'failed'; + job.error = message; + if (job.repositoryId && this.store.getRepository(job.repositoryId)) this.store.updateRepository(job.repositoryId, { status: 'failed', error: message }); + this.log.error(`Job ${job.id} failed: ${message}`); + } finally { + job.finishedAt = new Date().toISOString(); + } + }); + } + + /** Resolves when all queued jobs have finished (used by tests and shutdown). */ + idle(): Promise { + return this.queue; + } + + private async runIndex(repo: StoredRepository, job: JobProgress, forceFull = false): Promise { + const settings = this.store.getSettings(); + if (!fs.existsSync(repo.rootPath) || !fs.statSync(repo.rootPath).isDirectory()) throw new EngineError('The repository folder no longer exists on this machine', 410); + this.store.updateRepository(repo.id, { status: 'indexing', error: null }); + const useCache = settings.performance.indexingCache && settings.repository.incrementalIndexing && !forceFull; + const previous = useCache ? (this.store.loadFacts(repo.id) as Map) : undefined; + const result = await indexRepository({ + repositoryId: repo.id, + repositoryName: repo.name, + rootDir: repo.rootPath, + ignorePatterns: settings.repository.ignorePatterns, + maxFileSizeBytes: settings.repository.maxFileSizeKb * 1024, + maxFiles: settings.performance.maxFiles, + disabledLanguages: settings.repository.disabledLanguages, + concurrency: settings.performance.workerConcurrency, + previous: previous && previous.size ? previous : undefined, + pythonCommand: process.env.VECTORA_PYTHON, + onProgress: (stage, message, processed, total) => this.setStage(job, stage, message, processed, total), + }); + this.setStage(job, 'persist'); + this.store.saveGraph(repo.id, result.graph); + this.store.setAnalysis(repo.id, result.analysis); + if (settings.performance.indexingCache) this.store.saveFacts(repo.id, result.facts); + else this.store.clearFacts(repo.id); + this.store.updateRepository(repo.id, { + status: 'ready', + lastIndexedAt: result.analysis.generatedAt, + fileCount: result.graph.stats.fileCount, + symbolCount: result.graph.stats.symbolCount, + relationshipCount: result.graph.stats.edgeCount, + error: null, + }); + this.loaded.delete(repo.id); + job.summary = result.analysis.summary; + job.message = 'Workspace ready'; + this.log.info(`Indexed ${repo.name}: ${result.graph.stats.nodeCount} nodes, ${result.graph.stats.edgeCount} relationships in ${result.analysis.summary.durationMs} ms`); + } + + reindex(id: string, full = false): JobProgress { + const repo = this.repo(id); + if (this.activeJobs().some((j) => j.repositoryId === id)) throw new EngineError('This repository is already being indexed', 409); + const job = this.newJob(id); + this.enqueue(job, () => this.runIndex(repo, job, full)); + return job; + } + + // ---- imports ------------------------------------------------------------ + + importLocal(dirPath: string, name?: string, kind: 'local' | 'sample' = 'local'): JobProgress { + const abs = path.resolve(dirPath); + let stat: fs.Stats; + try { + stat = fs.statSync(abs); + } catch { + throw new EngineError('That folder does not exist', 404); + } + if (!stat.isDirectory()) throw new EngineError('The path is not a folder', 400); + const inside = path.relative(this.config.dataDir, abs); + if (!inside.startsWith('..') && !path.isAbsolute(inside)) throw new EngineError("VECTORA's own data folder cannot be imported", 400); + const repo = this.createRepository({ + name: (name?.trim() || path.basename(abs) || 'repository').slice(0, 120), + sourceKind: kind, + origin: kind === 'sample' ? 'Bundled sample repository' : abs, + branch: readGitBranch(abs), + subdirectory: null, + rootPath: abs, + managedSource: false, + }); + const job = this.newJob(repo.id); + this.enqueue(job, async () => { + this.setStage(job, 'acquire', 'Reading local folder'); + await this.runIndex(repo, job); + }); + return job; + } + + importSample(): JobProgress { + if (!this.config.sampleDir) throw new EngineError('The sample repository is not part of this installation', 404); + return this.importLocal(this.config.sampleDir, 'Orbit Notes (sample)', 'sample'); + } + + private cleanUploads(maxAgeMs: number): void { + try { + for (const f of fs.readdirSync(this.uploadsDir)) { + const file = path.join(this.uploadsDir, f); + if (maxAgeMs === 0 || Date.now() - fs.statSync(file).mtimeMs > maxAgeMs) fs.rmSync(file, { force: true }); + } + } catch { + // nothing to clean + } + for (const [id, u] of this.uploads) if (maxAgeMs === 0 || Date.now() - u.createdAt > maxAgeMs) this.uploads.delete(id); + } + + newUploadPath(): { id: string; file: string } { + this.cleanUploads(60 * 60 * 1000); + const id = randomUUID(); + return { id, file: path.join(this.uploadsDir, `${id}.zip`) }; + } + + async registerUpload(id: string, file: string, originalName: string): Promise<{ uploadId: string; fileName: string } & ZipInspection> { + try { + const inspection = await inspectZip(file); + // Only the base name is kept; a client-supplied path is never used. + const name = path.basename(originalName.replace(/\\/g, '/')).replace(/[^\w .()-]/g, '_').slice(0, 120) || 'archive.zip'; + this.uploads.set(id, { file, name, inspection, createdAt: Date.now() }); + return { uploadId: id, fileName: name, ...inspection }; + } catch (err) { + fs.rmSync(file, { force: true }); + if (err instanceof ArchiveError) throw new EngineError(err.message, err.code === 'too-large' || err.code === 'too-many-entries' ? 413 : 400); + throw err; + } + } + + importZip(uploadId: string, root: string | undefined, name?: string): JobProgress { + const upload = this.uploads.get(uploadId); + if (!upload) throw new EngineError('The uploaded archive has expired. Upload it again.', 404); + const chosen = normalizePath(root ?? upload.inspection.roots[0]?.path ?? ''); + if (chosen && !upload.inspection.roots.some((r) => r.path === chosen) && !upload.inspection.tree.some((t) => t.directory && (t.path === chosen || t.path.startsWith(`${chosen}/`)))) + throw new EngineError('That folder does not exist in the archive', 400); + const id = randomUUID(); + const dest = path.join(this.sourcesDir, id); + const repo = this.createRepository({ + id, + name: (name?.trim() || (chosen ? chosen.split('/').pop()! : upload.name.replace(/\.zip$/i, ''))).slice(0, 120), + sourceKind: 'zip', + origin: upload.name, + branch: null, + subdirectory: chosen || null, + rootPath: dest, + managedSource: true, + }); + const job = this.newJob(repo.id); + this.enqueue(job, async () => { + this.setStage(job, 'acquire', 'Extracting archive'); + try { + const settings = this.store.getSettings(); + const r = await extractZip(upload.file, dest, { root: chosen, ignorePatterns: settings.repository.ignorePatterns, limits: { maxFileBytes: settings.repository.maxFileSizeKb * 1024 } }); + this.setStage(job, 'acquire', `Extracted ${r.files} files`, r.files, r.files); + } finally { + fs.rmSync(upload.file, { force: true }); + this.uploads.delete(uploadId); + } + await this.runIndex(repo, job); + }); + return job; + } + + private githubToken(explicit?: string | null): string | null { + if (explicit?.trim()) return explicit.trim(); + const stored = this.store.getCredential('github'); + if (!stored) return null; + try { + return this.vault.decrypt(stored); + } catch { + return null; + } + } + + async validateGitHub(url: string, token?: string | null): Promise { + const ref = parseGitHubUrl(url); + const tok = this.githubToken(token); + const client = new GitHubClient({ token: tok, fetch: this.config.fetch }); + const info = await client.describe(ref, !!tok); + return { ...info, requested: ref, usingStoredCredential: !token?.trim() && !!tok }; + } + + importGitHub(input: { url: string; branch?: string | null; subdirectory?: string | null; token?: string | null; rememberToken?: boolean }): JobProgress { + const ref = parseGitHubUrl(input.url); + const token = this.githubToken(input.token); + if (input.rememberToken && input.token?.trim()) this.setCredential('github', input.token.trim()); + const sub = normalizePath(input.subdirectory ?? ref.subdirectory ?? ''); + if (sub.split('/').some((p) => p === '..')) throw new EngineError('Invalid subdirectory', 400); + const id = randomUUID(); + const dest = path.join(this.sourcesDir, id); + const repo = this.createRepository({ + id, + name: sub ? `${ref.repo}/${sub}` : ref.repo, + sourceKind: 'github', + origin: `https://github.com/${ref.owner}/${ref.repo}`, + branch: input.branch ?? ref.branch, + subdirectory: sub || null, + rootPath: sub ? path.join(dest, ...sub.split('/')) : dest, + managedSource: true, + }); + const job = this.newJob(repo.id); + this.enqueue(job, async () => { + const client = new GitHubClient({ token, fetch: this.config.fetch }); + this.setStage(job, 'acquire', 'Contacting GitHub'); + const info = await client.describe(ref, !!token); + const branch = input.branch ?? ref.branch ?? info.defaultBranch; + this.store.updateRepository(repo.id, { branch }); + const archive = path.join(this.uploadsDir, `${id}.zip`); + try { + this.setStage(job, 'acquire', `Downloading ${info.fullName}@${branch}`); + await client.downloadArchive(ref, branch, archive, !!token); + this.setStage(job, 'acquire', 'Extracting archive'); + const inspection = await inspectZip(archive); + const settings = this.store.getSettings(); + // GitHub archives wrap everything in one `-` directory. + await extractZip(archive, dest, { root: inspection.roots[0]?.path ?? '', ignorePatterns: settings.repository.ignorePatterns, limits: { maxFileBytes: settings.repository.maxFileSizeKb * 1024 } }); + } finally { + fs.rmSync(archive, { force: true }); + } + if (sub && !fs.existsSync(repo.rootPath)) throw new EngineError(`The folder "${sub}" does not exist on branch ${branch}`, 404); + await this.runIndex({ ...repo, branch }, job); + }); + return job; + } + + // ---- filesystem browsing for the local import dialog ------------------- + + listDirectory(dir?: string): { path: string; parent: string | null; entries: { name: string; path: string; repository: boolean }[]; roots: string[] } { + const roots: string[] = []; + if (process.platform === 'win32') { + for (const letter of 'CDEFGHIJKLMNOPQRSTUVWXYZAB') if (fs.existsSync(`${letter}:\\`)) roots.push(`${letter}:\\`); + } else roots.push('/'); + const start = dir?.trim() ? path.resolve(dir) : this.config.installRoot; + let entries: { name: string; path: string; repository: boolean }[] = []; + try { + entries = fs + .readdirSync(start, { withFileTypes: true }) + .filter((d) => d.isDirectory() && !d.name.startsWith('$') && d.name !== 'System Volume Information') + .map((d) => { + const p = path.join(start, d.name); + let repository = false; + try { + repository = ['.git', 'package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml', 'pom.xml'].some((m) => fs.existsSync(path.join(p, m))); + } catch { + repository = false; + } + return { name: d.name, path: p, repository }; + }) + .sort((a, b) => a.name.localeCompare(b.name)); + } catch { + throw new EngineError('That folder cannot be read', 403); + } + const parent = path.dirname(start); + return { path: start, parent: parent === start ? null : parent, entries, roots }; + } + + // ---- graph access ------------------------------------------------------- + + private load(id: string): LoadedRepo { + const cached = this.loaded.get(id); + if (cached) return cached; + this.repo(id); + const graph = this.store.loadGraph(id); + const entry: LoadedRepo = { graph, index: buildIndex(graph), search: new SearchIndex(graph.nodes), analysis: this.store.getAnalysis(id), docs: null }; + // Memory-aware: keep at most two repositories in memory. + while (this.loaded.size >= 2) this.loaded.delete(this.loaded.keys().next().value!); + this.loaded.set(id, entry); + return entry; + } + + getGraph(id: string, detail: 'full' | 'structure' = 'full'): KnowledgeGraph & { partial: boolean } { + const { graph } = this.load(id); + if (detail === 'full') return { ...graph, partial: false }; + const keep = new Set(STRUCTURAL_TYPES); + const nodes = graph.nodes.filter((n) => keep.has(n.type)); + const ids = new Set(nodes.map((n) => n.id)); + return { ...graph, nodes, edges: graph.edges.filter((e) => ids.has(e.source) && ids.has(e.target)), partial: true }; + } + + /** Symbols of one file with every relationship touching them (lazy expansion). */ + getFileMembers(id: string, filePath: string): { nodes: GraphNode[]; edges: GraphEdge[] } { + const { graph, index } = this.load(id); + const p = normalizePath(filePath); + const nodes = graph.nodes.filter((n) => n.filePath === p && n.type !== 'File' && n.type !== 'Configuration'); + const edges = new Map(); + for (const n of nodes) for (const e of [...(index.out.get(n.id) ?? []), ...(index.in.get(n.id) ?? [])]) edges.set(e.id, e); + return { nodes, edges: [...edges.values()] }; + } + + getOverview(id: string): RepositoryOverview { + const l = this.load(id); + return buildOverview(this.getRepository(id), l.graph, l.analysis, l.index); + } + + getAnalysis(id: string): RepositoryAnalysis | null { + return this.load(id).analysis; + } + + getSource(id: string, filePath: string, startLine?: number, endLine?: number): SourceResponse { + const repo = this.repo(id); + const { index } = this.load(id); + const p = normalizePath(filePath); + // Only files that are part of the index can be read. + const node = index.nodes.get(`file:${p}`); + if (!node) throw new EngineError('That file is not part of the indexed repository', 404); + const abs = resolveInside(repo.rootPath, p); + if (!abs) throw new EngineError('Invalid path', 400); + let real: string; + try { + real = fs.realpathSync(abs); + } catch { + throw new EngineError('The file no longer exists on disk. Re-index the repository.', 410); + } + const rootReal = fs.realpathSync(repo.rootPath); + const rel = path.relative(rootReal, real); + if (rel.startsWith('..') || path.isAbsolute(rel)) throw new EngineError('Invalid path', 400); + const stat = fs.statSync(real); + if (!stat.isFile()) throw new EngineError('Not a file', 400); + const truncated = stat.size > MAX_SOURCE_BYTES; + const fd = fs.openSync(real, 'r'); + const buf = Buffer.alloc(Math.min(stat.size, MAX_SOURCE_BYTES)); + fs.readSync(fd, buf, 0, buf.length, 0); + fs.closeSync(fd); + const all = buf.toString('utf8').split(/\r?\n/); + const s = Math.max(1, Math.min(startLine ?? 1, all.length)); + const e = Math.max(s, Math.min(endLine ?? all.length, all.length)); + return { path: p, language: node.language, content: all.slice(s - 1, e).join('\n'), startLine: s, endLine: e, totalLines: all.length, truncated }; + } + + private docs(id: string): { path: string; content: string }[] { + const l = this.load(id); + if (l.docs) return l.docs; + const repo = this.repo(id); + const docs: { path: string; content: string }[] = []; + for (const n of l.graph.nodes) { + if (n.type !== 'File' || !n.filePath || !['markdown', 'restructuredtext', 'text'].includes(n.language ?? '')) continue; + if (docs.length >= 300) break; + const abs = resolveInside(repo.rootPath, n.filePath); + try { + if (abs && fs.statSync(abs).size <= 512 * 1024) docs.push({ path: n.filePath, content: fs.readFileSync(abs, 'utf8') }); + } catch { + // file vanished since indexing + } + } + l.docs = docs; + return docs; + } + + listDocs(id: string): { path: string; title: string; lines: number }[] { + return this.docs(id) + .map((d) => ({ path: d.path, title: /^#\s+(.+)$/m.exec(d.content)?.[1]?.trim() ?? d.path.split('/').pop()!, lines: d.content.split('\n').length })) + .sort((a, b) => { + const rank = (p: string) => (/^readme/i.test(p) ? 0 : p.includes('/') ? 2 : 1); + return rank(a.path) - rank(b.path) || (a.path < b.path ? -1 : 1); + }); + } + + search(id: string, query: string, types?: string[], limit = 30) { + const l = this.load(id); + const hits = l.search.search(query, { types: types as never, limit: Math.min(limit, 100) }); + return { + query, + results: hits.map((h) => ({ id: h.node.id, name: h.node.name, type: h.node.type, filePath: h.node.filePath, line: h.node.location?.startLine ?? null, description: h.node.description ?? null, score: h.score, match: h.match })), + documents: searchDocuments(this.docs(id), query, 12), + }; + } + + async ask(id: string, question: string): Promise { + const l = this.load(id); + const answer = explore(question.slice(0, 500), l.index, l.analysis, (q, limit = 10) => l.search.search(q, { limit }).map((h) => h.node)); + const settings = this.store.getSettings(); + if (settings.exploration.providerEnabled && settings.exploration.providerEndpoint && answer.statements.length) { + const stored = this.store.getCredential('exploration-provider'); + try { + answer.narrative = await summarizeWithProvider( + { endpoint: settings.exploration.providerEndpoint, model: settings.exploration.providerModel, apiKey: stored ? this.vault.decrypt(stored) : null, fetch: this.config.fetch }, + answer, + ); + answer.narrativeSource = new URL(settings.exploration.providerEndpoint).host; + } catch (err) { + answer.narrative = null; + answer.caveats.push(`The optional narrative service did not respond (${redactSecrets((err as Error).message)}). The evidence above is unaffected.`); + } + } + return answer; + } + + export(id: string, format: string, includeSource: boolean): { body: string; contentType: string; fileName: string } { + const l = this.load(id); + const repo = this.getRepository(id); + const base = repo.name.replace(/[^\w.-]+/g, '-').slice(0, 60) || 'repository'; + switch (format) { + case 'json': + return { body: exportJson(repo, l.graph, { includeSource }), contentType: 'application/json', fileName: `${base}.vectora.json` }; + case 'graphml': + return { body: exportGraphML(repo, l.graph, { includeSource }), contentType: 'application/xml', fileName: `${base}.graphml` }; + case 'markdown': + return { body: exportMarkdownAnalysis(this.getOverview(id), l.graph, l.analysis), contentType: 'text/markdown', fileName: `${base}-analysis.md` }; + case 'architecture': + return { body: exportArchitectureDoc(this.getOverview(id), l.graph, l.analysis), contentType: 'text/markdown', fileName: `${base}-architecture.md` }; + default: + throw new EngineError('Unknown export format', 400); + } + } + + // ---- sessions, settings, credentials, data ----------------------------- + + getSession(id: string): SessionState | null { + this.repo(id); + return this.store.getSession(id); + } + + saveSession(id: string, session: SessionState): void { + this.repo(id); + this.store.saveSession(id, { ...session, savedAt: new Date().toISOString() }); + } + + getSettings(): Settings { + return this.store.getSettings(); + } + + updateSettings(patch: unknown): Settings { + const next = mergeSettings(this.store.getSettings(), patch); + this.store.saveSettings(next); + return next; + } + + setCredential(name: string, value: string): void { + if (!/^[a-z][a-z0-9-]{1,40}$/.test(name)) throw new EngineError('Invalid credential name', 400); + if (!value || value.length > 4096) throw new EngineError('Invalid credential value', 400); + this.store.setCredential(name, this.vault.encrypt(value)); + } + + /** Names and dates only — stored values are never returned. */ + listCredentials(): { name: string; updatedAt: string }[] { + return this.store.listCredentials(); + } + + deleteCredential(name: string): void { + this.store.deleteCredential(name); + } + + clearCache(): void { + this.store.clearFacts(); + } + + dataInfo(): { dataDir: string; databaseBytes: number; sourcesBytes: number; repositories: number; credentials: number } { + const size = (p: string): number => { + try { + const st = fs.statSync(p); + if (st.isFile()) return st.size; + return fs.readdirSync(p).reduce((a, f) => a + size(path.join(p, f)), 0); + } catch { + return 0; + } + }; + const db = ['vectora.db', 'vectora.db-wal', 'vectora.db-shm'].reduce((a, f) => a + size(path.join(this.config.dataDir, f)), 0); + return { dataDir: this.config.dataDir, databaseBytes: db, sourcesBytes: size(this.sourcesDir), repositories: this.store.listRepositories().length, credentials: this.store.listCredentials().length }; + } + + deleteAllData(): void { + if (this.activeJobs().length) throw new EngineError('Wait for indexing to finish before deleting data', 409); + this.store.deleteAllData(false); + this.loaded.clear(); + this.jobs.clear(); + for (const dir of [this.sourcesDir, this.uploadsDir]) { + fs.rmSync(dir, { recursive: true, force: true }); + fs.mkdirSync(dir, { recursive: true }); + } + this.uploads.clear(); + } +} + +/** Reads the checked-out branch from `.git/HEAD` without running git. */ +export function readGitBranch(dir: string): string | null { + try { + const head = fs.readFileSync(path.join(dir, '.git', 'HEAD'), 'utf8').trim(); + const m = /^ref:\s+refs\/heads\/(.+)$/.exec(head); + return m ? m[1]! : head.slice(0, 12); + } catch { + return null; + } +} diff --git a/package-lock.json b/package-lock.json index f5a52a1..aeb1e8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,12 +44,13 @@ "@fastify/static": "^9.0.0", "@vectora/graph-engine": "*", "@vectora/graph-schema": "*", + "@vectora/language-adapters": "*", "@vectora/repository-indexer": "*", "@vectora/search": "*", "@vectora/shared": "*", "fastify": "^5.12.8", + "ignore": "^7.0.14", "octokit": "^5.0.5", - "simple-git": "^4.0.2", "yauzl": "^3.4.0", "zod": "^4.6.7" }, @@ -58,6 +59,15 @@ "fflate": "^0.8.3" } }, + "apps/local-engine/node_modules/ignore": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.14.tgz", + "integrity": "sha512-wCBiZ77u1tuWde6G/nfOtLaCTYcFDU5yCzARzK10y+rLhzYoL7a7yEemcopcc2Mzow7gZOIjnV2ym1NYmdiJOQ==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "apps/web": { "name": "@vectora/web", "version": "0.1.0", @@ -1772,21 +1782,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.1" - } - }, - "node_modules/@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "license": "MIT" - }, "node_modules/@lezer/common": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.5.tgz", @@ -4505,21 +4500,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@simple-git/args-pathspec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@simple-git/args-pathspec/-/args-pathspec-1.0.4.tgz", - "integrity": "sha512-EtMX6XjRWSastG2SdkmSQByPtJ9dx/NIjnHbpQPCYt62j4RmSx5rgLTGpw0YCjF5h191gZOmBfheOT23cRSFdw==", - "license": "MIT" - }, - "node_modules/@simple-git/argv-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@simple-git/argv-parser/-/argv-parser-2.0.1.tgz", - "integrity": "sha512-M++IaVWrN+vYalilOHfwvT2IL3wYZtVEBQpmX6DLSOJLtxbZ+SUeIDE3IiPogzhPACLajwtxfa5rp+ZX1FczzQ==", - "license": "MIT", - "dependencies": { - "@simple-git/args-pathspec": "^1.0.4" - } - }, "node_modules/@tailwindcss/node": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.5.tgz", @@ -10033,23 +10013,6 @@ "graphology-utils": "^2.5.2" } }, - "node_modules/simple-git": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-4.0.2.tgz", - "integrity": "sha512-l0sIsv9VrPwovKELFDBOj/lhmIcbMvxBk2B+hRhsMM4/VL3gKtuZvYnBNixVo+N/0HnqQx2cBdLvxnAbygHpqA==", - "license": "MIT", - "dependencies": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "@simple-git/args-pathspec": "1.0.4", - "@simple-git/argv-parser": "2.0.1", - "debug": "^4.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/steveukx/git-js?sponsor=1" - } - }, "node_modules/sonic-boom": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", diff --git a/scripts/smoke-engine.ts b/scripts/smoke-engine.ts new file mode 100644 index 0000000..96e2306 --- /dev/null +++ b/scripts/smoke-engine.ts @@ -0,0 +1,39 @@ +/** Development smoke test: start the engine in-process, import the sample and query it. */ +import fs from 'node:fs'; +import path from 'node:path'; +import { loadConfig } from '../apps/local-engine/src/config'; +import { buildServer } from '../apps/local-engine/src/server'; + +const dataDir = path.resolve('.bench-tmp/smoke-data'); +fs.rmSync(dataDir, { recursive: true, force: true }); +const { app, engine } = await buildServer(loadConfig({ dataDir, logLevel: 'silent' })); +const call = async (method: string, url: string, payload?: unknown) => { + const res = await app.inject({ method: method as 'GET', url, payload: payload as object, headers: { host: 'localhost:4317' } }); + return { status: res.statusCode, body: res.headers['content-type']?.toString().includes('json') ? res.json() : res.body }; +}; +const job = await call('POST', '/api/import/sample'); +console.log('import', job.status, job.body.stage); +await engine.idle(); +const done = await call('GET', `/api/jobs/${job.body.id}`); +console.log('job', done.body.status, done.body.error, done.body.summary); +const id = done.body.repositoryId; +const ov = await call('GET', `/api/repositories/${id}/overview`); +console.log('overview', ov.status, ov.body.architectureSummary?.map((s: { statement: string }) => s.statement)); +const s = await call('GET', `/api/repositories/${id}/search?q=verifyToken`); +console.log('search', s.body.results?.slice(0, 3).map((r: { id: string }) => r.id)); +for (const q of ['What calls verifyToken?', 'Identify circular dependencies', 'Explain authentication', 'What could be affected if I change NoteRepository?', 'Trace GET /notes', 'Show the complete database access path', 'Explain the application startup sequence', 'What is frobnicate?']) { + const a = await call('POST', `/api/repositories/${id}/ask`, { question: q }); + console.log(`\nQ: ${q}\n [${a.body.intent}] ${a.body.title}`); + for (const st of a.body.statements.slice(0, 5)) console.log(` - ${st.text} ${st.evidence[0] ? `<${st.evidence[0].path}:${st.evidence[0].startLine}>` : ''}`); + if (a.body.caveats.length) console.log(` ! ${a.body.caveats[0]}`); +} +const src = await call('GET', `/api/repositories/${id}/source?path=web/src/auth/session.ts&start=12&end=14`); +console.log('\nsource', src.status, JSON.stringify(src.body.content)); +console.log('traversal', (await call('GET', `/api/repositories/${id}/source?path=../../package.json`)).status); +console.log('bad host', (await app.inject({ method: 'GET', url: '/api/health', headers: { host: 'evil.example' } })).statusCode); +console.log('bad origin', (await app.inject({ method: 'GET', url: '/api/health', headers: { host: 'localhost:4317', origin: 'https://evil.example' } })).statusCode); +for (const f of ['json', 'graphml', 'markdown', 'architecture']) console.log('export', f, (await call('GET', `/api/repositories/${id}/export/${f}`)).body.length); +const re = await call('POST', `/api/repositories/${id}/reindex`, {}); +await engine.idle(); +console.log('reindex', (await call('GET', `/api/jobs/${re.body.id}`)).body.summary); +await app.close(); From 74553247bcdb410a1b1c917d0774dcf681b94de9 Mon Sep 17 00:00:00 2001 From: Shreyan Bag Date: Thu, 12 Nov 2026 12:53:38 +0530 Subject: [PATCH 3/8] Add web application: landing, import, workspace and three exploration views - Kanso/Ma design system: tokens, light and dark themes, bundled typefaces - landing, About, repository import (GitHub, ZIP, local folder, sample) - workspace shell with shared selection, session restore and autosave - 2D Graph Explorer (Sigma + Graphology), 3D Atlas (React Three Fiber, instanced nodes, worker layout), hierarchical Mind Map (React Flow + dagre) - inspector with CodeMirror source preview and evidence per relationship - command palette, search, question exploration, dependency explorer, documentation, settings, exports - dev and engine build scripts Co-Authored-By: Claude Fable 5.2 --- .gitignore | 1 + apps/local-engine/src/server.ts | 11 +- apps/web/index.html | 16 + apps/web/package.json | 2 +- apps/web/public/mark.svg | 1 + apps/web/src/App.tsx | 63 ++ apps/web/src/components/CodePreview.tsx | 13 + apps/web/src/components/CodePreviewImpl.tsx | 104 +++ apps/web/src/components/CommandPalette.tsx | 130 ++++ apps/web/src/components/ExportDialog.tsx | 49 ++ apps/web/src/components/Inspector.tsx | 343 ++++++++++ apps/web/src/components/Site.tsx | 203 ++++++ apps/web/src/components/ViewControls.tsx | 120 ++++ apps/web/src/components/ui.tsx | 168 +++++ apps/web/src/lib/api.ts | 199 ++++++ apps/web/src/lib/graphView.ts | 171 +++++ apps/web/src/lib/store.ts | 122 ++++ apps/web/src/lib/theme.ts | 45 ++ apps/web/src/lib/tokens.ts | 180 ++++++ apps/web/src/main.tsx | 17 + apps/web/src/pages/About.tsx | 166 +++++ apps/web/src/pages/ImportPage.tsx | 435 +++++++++++++ apps/web/src/pages/Landing.tsx | 174 +++++ apps/web/src/styles.css | 524 +++++++++++++++ apps/web/src/theme-init.ts | 4 + apps/web/src/workers/layout3d.worker.ts | 20 + apps/web/src/workspace/Atlas.tsx | 676 ++++++++++++++++++++ apps/web/src/workspace/Dependencies.tsx | 317 +++++++++ apps/web/src/workspace/Documentation.tsx | 125 ++++ apps/web/src/workspace/GraphExplorer.tsx | 541 ++++++++++++++++ apps/web/src/workspace/MindMap.tsx | 462 +++++++++++++ apps/web/src/workspace/Overview.tsx | 258 ++++++++ apps/web/src/workspace/SearchView.tsx | 256 ++++++++ apps/web/src/workspace/SettingsView.tsx | 362 +++++++++++ apps/web/src/workspace/WorkspaceLayout.tsx | 318 +++++++++ apps/web/src/workspace/context.tsx | 31 + apps/web/vite.config.ts | 25 + package-lock.json | 22 +- packages/graph-layout/src/d3-force-3d.d.ts | 38 ++ packages/graph-layout/src/index.ts | 207 ++++++ packages/graph-schema/src/index.ts | 2 +- scripts/build-engine.mjs | 37 ++ scripts/dev.mjs | 21 + 43 files changed, 6963 insertions(+), 16 deletions(-) create mode 100644 apps/web/index.html create mode 100644 apps/web/public/mark.svg create mode 100644 apps/web/src/App.tsx create mode 100644 apps/web/src/components/CodePreview.tsx create mode 100644 apps/web/src/components/CodePreviewImpl.tsx create mode 100644 apps/web/src/components/CommandPalette.tsx create mode 100644 apps/web/src/components/ExportDialog.tsx create mode 100644 apps/web/src/components/Inspector.tsx create mode 100644 apps/web/src/components/Site.tsx create mode 100644 apps/web/src/components/ViewControls.tsx create mode 100644 apps/web/src/components/ui.tsx create mode 100644 apps/web/src/lib/api.ts create mode 100644 apps/web/src/lib/graphView.ts create mode 100644 apps/web/src/lib/store.ts create mode 100644 apps/web/src/lib/theme.ts create mode 100644 apps/web/src/lib/tokens.ts create mode 100644 apps/web/src/main.tsx create mode 100644 apps/web/src/pages/About.tsx create mode 100644 apps/web/src/pages/ImportPage.tsx create mode 100644 apps/web/src/pages/Landing.tsx create mode 100644 apps/web/src/styles.css create mode 100644 apps/web/src/theme-init.ts create mode 100644 apps/web/src/workers/layout3d.worker.ts create mode 100644 apps/web/src/workspace/Atlas.tsx create mode 100644 apps/web/src/workspace/Dependencies.tsx create mode 100644 apps/web/src/workspace/Documentation.tsx create mode 100644 apps/web/src/workspace/GraphExplorer.tsx create mode 100644 apps/web/src/workspace/MindMap.tsx create mode 100644 apps/web/src/workspace/Overview.tsx create mode 100644 apps/web/src/workspace/SearchView.tsx create mode 100644 apps/web/src/workspace/SettingsView.tsx create mode 100644 apps/web/src/workspace/WorkspaceLayout.tsx create mode 100644 apps/web/src/workspace/context.tsx create mode 100644 apps/web/vite.config.ts create mode 100644 packages/graph-layout/src/d3-force-3d.d.ts create mode 100644 packages/graph-layout/src/index.ts create mode 100644 scripts/build-engine.mjs create mode 100644 scripts/dev.mjs diff --git a/.gitignore b/.gitignore index 07ce1bf..6371c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ Thumbs.db *.tsbuildinfo .bench-tmp/ .npm-cache/ +.claude/ diff --git a/apps/local-engine/src/server.ts b/apps/local-engine/src/server.ts index abace13..607cac5 100644 --- a/apps/local-engine/src/server.ts +++ b/apps/local-engine/src/server.ts @@ -8,7 +8,7 @@ import { pipeline } from 'node:stream/promises'; import cors from '@fastify/cors'; import multipart from '@fastify/multipart'; import fastifyStatic from '@fastify/static'; -import Fastify, { type FastifyInstance } from 'fastify'; +import Fastify, { type FastifyInstance, type FastifyReply } from 'fastify'; import { z } from 'zod'; import { NODE_TYPES } from '@vectora/graph-schema'; import { SUPPORTED_LANGUAGES, findPython } from '@vectora/language-adapters'; @@ -236,9 +236,14 @@ export async function buildServer(config: EngineConfig): Promise<{ app: FastifyI // ---- web application ---------------------------------------------------- if (config.webDist) { - await app.register(fastifyStatic, { root: config.webDist, wildcard: false, maxAge: '1h', immutable: false }); + await app.register(fastifyStatic, { root: config.webDist, wildcard: true, index: false, maxAge: '1h', immutable: false }); + // The application shell must never be cached: it points at content-hashed assets that change with every build. + const shell = (reply: FastifyReply) => reply.sendFile('index.html', { cacheControl: false }).header('Cache-Control', 'no-cache'); + app.get('/', (_req, reply) => shell(reply)); app.setNotFoundHandler((req, reply) => { - if (req.method === 'GET' && !req.url.startsWith('/api/')) return reply.header('Cache-Control', 'no-cache').sendFile('index.html'); + // Client-side routes fall back to the application shell; missing assets and API paths are real 404s. + const path = req.url.split('?')[0] ?? ''; + if (req.method === 'GET' && !path.startsWith('/api/') && !path.startsWith('/assets/') && !/\.[a-z0-9]{2,5}$/i.test(path)) return shell(reply); return reply.code(404).send({ error: 'Not found' }); }); } else { diff --git a/apps/web/index.html b/apps/web/index.html new file mode 100644 index 0000000..310138b --- /dev/null +++ b/apps/web/index.html @@ -0,0 +1,16 @@ + + + + + + + + + VECTORA — Understand what connects. + + +
+ + + + diff --git a/apps/web/package.json b/apps/web/package.json index 04ee320..033147c 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -46,7 +46,7 @@ "react-dom": "^19.3.1", "react-markdown": "^10.0.0", "react-router": "^8.5.1", - "sigma": "^4.0.6", + "sigma": "^3.0.3", "three": "^0.187.0", "zustand": "^5.1.0" }, diff --git a/apps/web/public/mark.svg b/apps/web/public/mark.svg new file mode 100644 index 0000000..5bed6b5 --- /dev/null +++ b/apps/web/public/mark.svg @@ -0,0 +1 @@ + diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx new file mode 100644 index 0000000..5174af7 --- /dev/null +++ b/apps/web/src/App.tsx @@ -0,0 +1,63 @@ +import { Suspense, lazy } from 'react'; +import { BrowserRouter, Link, Route, Routes } from 'react-router'; +import { SitePage } from './components/Site'; +import { Empty, Loading } from './components/ui'; +import { About } from './pages/About'; +import { ImportPage } from './pages/ImportPage'; +import { Landing } from './pages/Landing'; +import { Dependencies } from './workspace/Dependencies'; +import { Documentation, SourceView } from './workspace/Documentation'; +import { Overview } from './workspace/Overview'; +import { SearchView } from './workspace/SearchView'; +import { SettingsView } from './workspace/SettingsView'; +import { WorkspaceLayout } from './workspace/WorkspaceLayout'; + +// The three renderers are loaded on demand: each pulls in a sizeable graphics library. +const GraphExplorer = lazy(() => import('./workspace/GraphExplorer').then((m) => ({ default: m.GraphExplorer }))); +const Atlas = lazy(() => import('./workspace/Atlas').then((m) => ({ default: m.Atlas }))); +const MindMap = lazy(() => import('./workspace/MindMap').then((m) => ({ default: m.MindMap }))); + +const view = (el: React.ReactNode) => }>{el}; + +export function App() { + return ( + + + } /> + } /> + } /> + + + + } + /> + }> + } /> + )} /> + )} /> + )} /> + } /> + } /> + } /> + } /> + } /> + + + +

+ Return to the start +

+
+ + } + /> +
+
+ ); +} diff --git a/apps/web/src/components/CodePreview.tsx b/apps/web/src/components/CodePreview.tsx new file mode 100644 index 0000000..5fabc36 --- /dev/null +++ b/apps/web/src/components/CodePreview.tsx @@ -0,0 +1,13 @@ +import { Suspense, lazy } from 'react'; +import type { CodePreviewProps } from './CodePreviewImpl'; + +// The editor and its language grammars are loaded when the first source preview is shown. +const Impl = lazy(() => import('./CodePreviewImpl').then((m) => ({ default: m.CodePreview }))); + +export function CodePreview(props: CodePreviewProps) { + return ( + Loading source…

}> + +
+ ); +} diff --git a/apps/web/src/components/CodePreviewImpl.tsx b/apps/web/src/components/CodePreviewImpl.tsx new file mode 100644 index 0000000..0087f48 --- /dev/null +++ b/apps/web/src/components/CodePreviewImpl.tsx @@ -0,0 +1,104 @@ +import { cpp } from '@codemirror/lang-cpp'; +import { go } from '@codemirror/lang-go'; +import { java } from '@codemirror/lang-java'; +import { javascript } from '@codemirror/lang-javascript'; +import { json } from '@codemirror/lang-json'; +import { markdown } from '@codemirror/lang-markdown'; +import { python } from '@codemirror/lang-python'; +import { rust } from '@codemirror/lang-rust'; +import { HighlightStyle, type LanguageSupport, syntaxHighlighting } from '@codemirror/language'; +import { EditorState, type Extension, RangeSetBuilder } from '@codemirror/state'; +import { Decoration, EditorView, lineNumbers } from '@codemirror/view'; +import { tags as t } from '@lezer/highlight'; +import { useEffect, useRef } from 'react'; + +// Syntax colours come from the design tokens, so the preview follows the theme. +const highlight = HighlightStyle.define([ + { tag: [t.keyword, t.modifier, t.controlKeyword, t.operatorKeyword, t.definitionKeyword, t.moduleKeyword], color: 'var(--indigo)' }, + { tag: [t.string, t.special(t.string), t.regexp], color: 'var(--clay)' }, + { tag: [t.comment, t.lineComment, t.blockComment, t.docComment], color: 'var(--text-muted)', fontStyle: 'italic' }, + { tag: [t.number, t.bool, t.null, t.atom], color: 'var(--warning)' }, + { tag: [t.typeName, t.className, t.namespace], color: 'var(--text)', fontWeight: '500' }, + { tag: [t.function(t.variableName), t.function(t.propertyName), t.definition(t.variableName)], color: 'var(--text)' }, + { tag: [t.propertyName, t.variableName], color: 'var(--text-secondary)' }, + { tag: [t.punctuation, t.bracket, t.operator], color: 'var(--text-muted)' }, + { tag: t.heading, fontWeight: '500' }, + { tag: t.invalid, color: 'var(--error)' }, +]); + +function languageFor(language: string | null, path: string): LanguageSupport | null { + switch (language) { + case 'typescript': + return javascript({ typescript: true, jsx: /\.tsx$/.test(path) }); + case 'javascript': + return javascript({ jsx: true }); + case 'python': + return python(); + case 'java': + case 'csharp': + return java(); + case 'go': + return go(); + case 'rust': + return rust(); + case 'c': + case 'cpp': + return cpp(); + case 'json': + return json(); + case 'markdown': + return markdown(); + default: + return null; + } +} + +const rangeMark = Decoration.line({ class: 'cm-vectora-range' }); + +export interface CodePreviewProps { + content: string; + language: string | null; + path: string; + /** Line number of the first line of `content` in the original file. */ + firstLine?: number; + /** Lines (original numbering) to mark as the selected range. */ + highlight?: { start: number; end: number } | null; + maxHeight?: number | string; + scrollToLine?: number; +} + +/** Read-only source preview. Source text is rendered as text only — never interpreted as markup. */ +export function CodePreview({ content, language, path, firstLine = 1, highlight: range, maxHeight = 320, scrollToLine }: CodePreviewProps) { + const host = useRef(null); + useEffect(() => { + if (!host.current) return; + const lang = languageFor(language, path); + const extensions: Extension[] = [ + EditorState.readOnly.of(true), + EditorView.editable.of(false), + EditorView.contentAttributes.of({ 'aria-label': `Source of ${path}`, tabindex: '0' }), + lineNumbers({ formatNumber: (n) => String(n + firstLine - 1) }), + syntaxHighlighting(highlight), + EditorView.theme({ '&': { maxHeight: typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight }, '.cm-scroller': { overflow: 'auto' } }), + ]; + if (lang) extensions.push(lang); + if (range) { + extensions.push( + EditorView.decorations.of((view) => { + const b = new RangeSetBuilder(); + const from = Math.max(1, range.start - firstLine + 1); + const to = Math.min(view.state.doc.lines, range.end - firstLine + 1); + for (let l = from; l <= to; l++) b.add(view.state.doc.line(l).from, view.state.doc.line(l).from, rangeMark); + return b.finish(); + }), + ); + } + const view = new EditorView({ state: EditorState.create({ doc: content, extensions }), parent: host.current }); + if (scrollToLine) { + const l = Math.min(view.state.doc.lines, Math.max(1, scrollToLine - firstLine + 1)); + view.dispatch({ effects: EditorView.scrollIntoView(view.state.doc.line(l).from, { y: 'start', yMargin: 48 }) }); + } + return () => view.destroy(); + }, [content, language, path, firstLine, range?.start, range?.end, maxHeight, scrollToLine]); // eslint-disable-line react-hooks/exhaustive-deps + return
; +} diff --git a/apps/web/src/components/CommandPalette.tsx b/apps/web/src/components/CommandPalette.tsx new file mode 100644 index 0000000..84be849 --- /dev/null +++ b/apps/web/src/components/CommandPalette.tsx @@ -0,0 +1,130 @@ +import { useQuery } from '@tanstack/react-query'; +import { Command } from 'cmdk'; +import { useEffect, useState } from 'react'; +import { useLocation } from 'react-router'; +import { api } from '@/lib/api'; +import { useWorkspace } from '@/lib/store'; +import { useWs } from '@/workspace/context'; +import { TypeMark } from './ui'; + +const VIEWS: { view: Parameters['openView']>[0]; label: string }[] = [ + { view: 'overview', label: 'Overview' }, + { view: 'mindmap', label: 'Mind Map' }, + { view: 'graph', label: 'Graph Explorer' }, + { view: 'atlas', label: '3D Atlas' }, + { view: 'dependencies', label: 'Dependency Explorer' }, + { view: 'search', label: 'Search' }, + { view: 'docs', label: 'Documentation' }, + { view: 'settings', label: 'Settings' }, +]; + +const itemClass = + 'flex cursor-pointer items-baseline gap-3 border-l-2 border-transparent px-5 py-2 text-[0.875rem] data-[selected=true]:border-ink data-[selected=true]:bg-surface'; + +/** Global search (Ctrl/Cmd + K). Enter opens the selected result and highlights it in the graph. */ +export function CommandPalette() { + const { repo, reveal, openView, settings } = useWs(); + const open = useWorkspace((s) => s.paletteOpen); + const setOpen = useWorkspace((s) => s.setPaletteOpen); + const location = useLocation(); + const [input, setInput] = useState(''); + const [query, setQuery] = useState(''); + useEffect(() => { + const t = setTimeout(() => setQuery(input.trim()), 140); + return () => clearTimeout(t); + }, [input]); + useEffect(() => { + if (!open) setInput(''); + }, [open]); + const { data, isFetching } = useQuery({ queryKey: ['search', repo.id, query], queryFn: () => api.search(repo.id, query), enabled: open && query.length >= 2, staleTime: 30_000, placeholderData: (p) => p }); + + const current = location.pathname.split('/')[3] ?? 'overview'; + const openNode = (id: string) => { + setOpen(false); + reveal(id); + // Stay in the current exploration view; otherwise open the default one. + if (!['graph', 'atlas', 'mindmap'].includes(current)) openView(settings.graph.defaultMode); + }; + const results = query.length >= 2 ? (data?.results ?? []) : []; + const documents = query.length >= 2 ? (data?.documents ?? []) : []; + const views = VIEWS.filter((v) => !query || v.label.toLowerCase().includes(query.toLowerCase())); + + return ( + +
+ + Esc +
+ + {query.length >= 2 && !isFetching ? Nothing in this repository matches “{query}”. Try a file path or part of a symbol name. : null} + {results.length ? ( + + {results.map((r) => ( + openNode(r.id)} className={itemClass} data-testid="palette-result"> + + {r.name} + {r.filePath ? ( + + {r.filePath} + {r.line && r.type !== 'File' ? `:${r.line}` : ''} + + ) : r.description ? ( + {r.description} + ) : null} + + + + ))} + + ) : null} + {documents.length ? ( + + {documents.map((d) => ( + { + setOpen(false); + openView('docs', `path=${encodeURIComponent(d.path)}`); + }} + className={itemClass} + > + + {d.snippet} + + {d.path}:{d.line} + {d.heading ? ` — ${d.heading}` : ''} + + + + ))} + + ) : null} + {views.length ? ( + + {views.map((v) => ( + { + setOpen(false); + openView(v.view); + }} + className={itemClass} + > + {v.label} + + ))} + + ) : null} + +

Enter opens the selected result. Arrow keys move through the list.

+
+ ); +} diff --git a/apps/web/src/components/ExportDialog.tsx b/apps/web/src/components/ExportDialog.tsx new file mode 100644 index 0000000..b635c35 --- /dev/null +++ b/apps/web/src/components/ExportDialog.tsx @@ -0,0 +1,49 @@ +import { useEffect, useState } from 'react'; +import { api, downloadUrl } from '@/lib/api'; +import { useWs } from '@/workspace/context'; +import { Dialog, Notice } from './ui'; + +const FORMATS: { id: string; label: string; detail: string; graph: boolean }[] = [ + { id: 'json', label: 'Graph as JSON', detail: 'Every node and relationship with ids, locations, extraction method and confidence.', graph: true }, + { id: 'graphml', label: 'Graph as GraphML', detail: 'For Gephi, yEd, Cytoscape and other graph tools.', graph: true }, + { id: 'markdown', label: 'Repository analysis (Markdown)', detail: 'Languages, subsystems, entry points, dependencies and unresolved references.', graph: false }, + { id: 'architecture', label: 'Architecture documentation (Markdown)', detail: 'Subsystem dependencies, endpoints, models, flows and circular imports.', graph: false }, +]; + +export function ExportDialog({ open, onOpenChange }: { open: boolean; onOpenChange: (o: boolean) => void }) { + const { repo, settings } = useWs(); + const [includeSource, setIncludeSource] = useState(settings.privacy.includeSourceInExports); + useEffect(() => { + if (open) setIncludeSource(settings.privacy.includeSourceInExports); + }, [open, settings.privacy.includeSourceInExports]); + return ( + +
    + {FORMATS.map((f) => ( +
  • +
    +

    {f.label}

    +

    {f.detail}

    +
    + +
  • + ))} +
+ + {includeSource ? ( +
+ The JSON and GraphML files will contain lines of source code from this repository. +
+ ) : null} +

The Mind Map exports SVG and PNG, and the Graph Explorer and 3D Atlas export PNG, from their own toolbars.

+
+ ); +} diff --git a/apps/web/src/components/Inspector.tsx b/apps/web/src/components/Inspector.tsx new file mode 100644 index 0000000..5beb91a --- /dev/null +++ b/apps/web/src/components/Inspector.tsx @@ -0,0 +1,343 @@ +import { ChevronRight, X } from 'lucide-react'; +import { useCallback, useMemo, useRef, useState } from 'react'; +import { EDGE_TYPE_LABELS, type EdgeType, type GraphEdge, type GraphNode, isSymbolType } from '@vectora/graph-schema'; +import { useSource } from '@/lib/api'; +import { fileIdOf, relationsOf } from '@/lib/graphView'; +import { useWorkspace } from '@/lib/store'; +import { useWs } from '@/workspace/context'; +import { CodePreview } from './CodePreview'; +import { IconButton, TypeMark, cx } from './ui'; + +const METHOD_LABEL: Record = { + filesystem: 'file system structure', + manifest: 'package manifest', + 'typescript-compiler': 'TypeScript compiler (syntax)', + 'typescript-checker': 'TypeScript type checker', + 'python-ast': 'Python syntax tree', + 'tree-sitter': 'Tree-sitter syntax tree', + 'scope-resolution': 'import and scope resolution', + 'name-resolution': 'name match within visible files', + pattern: 'framework pattern', + 'structural-grouping': 'repository layout', + 'keyword-evidence': 'identifier and path evidence', + aggregation: 'aggregated relationships', +}; + +function copy(text: string, done: (label: string) => void, label: string): void { + void navigator.clipboard.writeText(text).then( + () => done(label), + () => done('Copy failed'), + ); +} + +export function Inspector() { + const { adj, repo, reveal, expandFile, openView } = useWs(); + const primaryId = useWorkspace((s) => s.primaryId); + const selectedCount = useWorkspace((s) => s.selectedIds.length); + const width = useWorkspace((s) => s.inspectorWidth); + const setInspector = useWorkspace((s) => s.setInspector); + const setFocus = useWorkspace((s) => s.setFocus); + const focusId = useWorkspace((s) => s.focusId); + const [toast, setToast] = useState(null); + const toastTimer = useRef | null>(null); + const notify = useCallback((label: string) => { + setToast(label); + if (toastTimer.current) clearTimeout(toastTimer.current); + toastTimer.current = setTimeout(() => setToast(null), 1600); + }, []); + + const node = primaryId ? adj.nodes.get(primaryId) : undefined; + const rel = useMemo(() => (node ? relationsOf(node.id, adj) : null), [node, adj]); + + // Source range: the symbol itself, or the head of a file. + const isFileLike = node?.type === 'File' || node?.type === 'Configuration'; + const loc = node?.location ?? null; + const start = loc ? (isFileLike ? 1 : Math.max(1, loc.startLine - 2)) : undefined; + const end = loc ? (isFileLike ? Math.min(loc.endLine, 80) : Math.min(loc.endLine + 2, loc.startLine + 120)) : undefined; + const hasSource = !!node?.filePath && !!loc && (isFileLike || isSymbolType(node.type)); + const source = useSource(repo.id, hasSource ? node!.filePath : null, start, end); + + const onResize = (e: React.PointerEvent) => { + const startX = e.clientX; + const startW = width; + const el = e.currentTarget; + el.setPointerCapture(e.pointerId); + const move = (ev: PointerEvent) => setInspector(true, Math.max(280, Math.min(720, startW + (startX - ev.clientX)))); + const up = () => { + el.removeEventListener('pointermove', move); + el.removeEventListener('pointerup', up); + }; + el.addEventListener('pointermove', move); + el.addEventListener('pointerup', up); + }; + + if (!node || !rel) return null; + const dependencyText = () => { + const lines = [`${node.name} (${node.type}) — ${node.filePath ?? ''}${loc ? `:${loc.startLine}` : ''}`, '', 'Depends on:']; + for (const e of rel.outgoing) lines.push(` ${e.type} ${adj.nodes.get(e.target)?.name ?? e.target}${e.location ? ` (${e.location.path}:${e.location.startLine})` : ''}`); + lines.push('', 'Used by:'); + for (const e of rel.incoming) lines.push(` ${e.type} ${adj.nodes.get(e.source)?.name ?? e.source}${e.location ? ` (${e.location.path}:${e.location.startLine})` : ''}`); + return lines.join('\n'); + }; + const expandRelationships = () => { + const files = new Set(); + const self = fileIdOf(node); + if (self) files.add(self); + for (const e of [...rel.incoming, ...rel.outgoing]) { + const other = adj.nodes.get(e.source === node.id ? e.target : e.source); + const fid = other ? fileIdOf(other) : null; + if (fid) files.add(fid); + } + for (const f of files) expandFile(f, true); + notify(`${files.size} file${files.size === 1 ? '' : 's'} expanded`); + }; + + return ( + + ); +} + +function Section({ title, count, children }: { title: string; count?: number; children: React.ReactNode }) { + return ( +
+

+ {title} + {count !== undefined ? {count} : null} +

+ {children} +
+ ); +} + +function NodeRow({ node, onClick, derived }: { node: GraphNode; onClick: () => void; derived?: boolean }) { + return ( + + ); +} + +function Relationships({ title, hint, edges, side }: { title: string; hint: string; edges: GraphEdge[]; side: 'source' | 'target' }) { + const { adj, reveal } = useWs(); + const [open, setOpen] = useState(null); + const groups = useMemo(() => { + const m = new Map(); + for (const e of edges) (m.get(e.type) ?? m.set(e.type, []).get(e.type)!).push(e); + return [...m.entries()].sort((a, b) => b[1].length - a[1].length); + }, [edges]); + return ( +
+ {edges.length === 0 ?

None resolved — {hint}.

: null} + {groups.map(([type, list]) => ( +
+

+ {EDGE_TYPE_LABELS[type]} ({list.length}) +

+
    + {list.slice(0, 30).map((e) => { + const other = adj.nodes.get(e[side]); + const isOpen = open === e.id; + return ( +
  • +
    + + + {!e.verified ? derived : null} + {other ? : null} +
    + {isOpen ? ( +
    +

    {e.evidence}

    +

    + {e.location ? `${e.location.path}:${e.location.startLine}` : 'no single location'} — {METHOD_LABEL[e.extractionMethod] ?? e.extractionMethod}, {Math.round(e.confidence * 100)}% + {e.metadata?.occurrences ? `, ${String(e.metadata.occurrences)} occurrences` : ''} +

    +
    + ) : null} +
  • + ); + })} +
+ {list.length > 30 ?

{list.length - 30} more not shown

: null} +
+ ))} +
+ ); +} diff --git a/apps/web/src/components/Site.tsx b/apps/web/src/components/Site.tsx new file mode 100644 index 0000000..a719b4b --- /dev/null +++ b/apps/web/src/components/Site.tsx @@ -0,0 +1,203 @@ +import { Moon, Sun } from 'lucide-react'; +import { type ReactNode, useEffect, useRef, useState } from 'react'; +import { Link, NavLink } from 'react-router'; +import { APP_VERSION } from '@vectora/shared'; +import { useSettings } from '@/lib/api'; +import { useReducedMotion, useTheme } from '@/lib/theme'; +import { type Palette, mix, paletteFor } from '@/lib/tokens'; +import { IconButton, Wordmark, cx } from './ui'; + +/** Theme for pages outside a workspace. Works even when the local engine is not running. */ +export function useSiteTheme(): { theme: 'light' | 'dark'; palette: Palette; toggle: () => void; reducedMotion: boolean } { + const { settings, update } = useSettings(); + const [local, setLocal] = useState<'light' | 'dark' | 'system' | undefined>(undefined); + const theme = useTheme(settings?.appearance.theme ?? local); + const reducedMotion = useReducedMotion(settings); + return { + theme, + palette: paletteFor(theme), + reducedMotion, + toggle: () => { + const next = theme === 'dark' ? 'light' : 'dark'; + if (settings) update({ appearance: { theme: next } }); + else setLocal(next); + }, + }; +} + +export function SiteHeader() { + const { theme, toggle } = useSiteTheme(); + const link = ({ isActive }: { isActive: boolean }) => cx('text-[0.875rem] no-underline transition-colors duration-200', isActive ? 'text-ink' : 'text-ink-2 hover:text-ink'); + return ( +
+ + Skip to content + + + + + +
+ ); +} + +export function SiteFooter() { + return ( +
+
+
+ +

Understand what connects.

+
+ +

Version {APP_VERSION}, MIT licence

+
+
+ ); +} + +export function SitePage({ children }: { children: ReactNode }) { + return ( +
+ +
+ {children} +
+ +
+ ); +} + +/** + * Illustration of the 3D Atlas: a fixed, generated structure (a centre, six + * regions, points around them) drawn in perspective. It is a drawing of the + * idea, not data from a repository, and is captioned as such where used. + */ +export function AtlasIllustration({ className }: { className?: string }) { + const ref = useRef(null); + const { palette, reducedMotion } = useSiteTheme(); + useEffect(() => { + const canvas = ref.current; + if (!canvas) return; + const ctx = canvas.getContext('2d'); + if (!ctx) return; + // Deterministic pseudo-random numbers so the drawing is identical on every visit. + let seed = 7; + const rnd = () => ((seed = (seed * 16807) % 2147483647) - 1) / 2147483646; + type P = { x: number; y: number; z: number; r: number; kind: 0 | 1 | 2 }; + const points: P[] = [{ x: 0, y: 0, z: 0, r: 7, kind: 0 }]; + const links: [number, number, boolean][] = []; + const hubs: number[] = []; + for (let h = 0; h < 6; h++) { + const a = (h / 6) * Math.PI * 2 + 0.4; + const hub: P = { x: Math.cos(a) * 150, y: (rnd() - 0.5) * 110, z: Math.sin(a) * 150, r: 4.5, kind: 1 }; + hubs.push(points.length); + links.push([0, points.length, false]); + points.push(hub); + const count = 9 + Math.floor(rnd() * 9); + for (let i = 0; i < count; i++) { + const t = rnd() * Math.PI * 2; + const u = Math.acos(2 * rnd() - 1); + const d = 26 + rnd() * 42; + links.push([hubs[h]!, points.length, false]); + points.push({ x: hub.x + Math.sin(u) * Math.cos(t) * d, y: hub.y + Math.cos(u) * d, z: hub.z + Math.sin(u) * Math.sin(t) * d, r: 1.4 + rnd() * 1.4, kind: 2 }); + } + } + for (let i = 0; i < 14; i++) { + const a = 7 + Math.floor(rnd() * (points.length - 7)); + const b = 7 + Math.floor(rnd() * (points.length - 7)); + if (a !== b) links.push([a, b, true]); + } + + let angle = 0.6; + let raf = 0; + let visible = true; + const draw = () => { + const dpr = Math.min(2, window.devicePixelRatio || 1); + const w = canvas.clientWidth; + const h = canvas.clientHeight; + if (canvas.width !== w * dpr || canvas.height !== h * dpr) { + canvas.width = w * dpr; + canvas.height = h * dpr; + } + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + ctx.clearRect(0, 0, w, h); + const s = Math.min(w, h) / 470; + const cos = Math.cos(angle); + const sin = Math.sin(angle); + const proj = points.map((p) => { + const x = p.x * cos - p.z * sin; + const z = p.x * sin + p.z * cos; + const y = p.y * 0.94 - z * 0.2; + const k = 620 / (620 + z); + return { x: w / 2 + x * k * s, y: h / 2 + y * k * s, k, z }; + }); + for (const [a, b, cross] of links) { + const pa = proj[a]!; + const pb = proj[b]!; + const depth = Math.max(0, Math.min(1, ((pa.z + pb.z) / 2 + 220) / 440)); + ctx.strokeStyle = mix(cross ? palette.clay : palette.textMuted, palette.canvas, 0.35 + depth * 0.5); + ctx.lineWidth = cross ? 0.9 : 0.7; + ctx.setLineDash(cross ? [3, 4] : []); + ctx.beginPath(); + ctx.moveTo(pa.x, pa.y); + ctx.lineTo(pb.x, pb.y); + ctx.stroke(); + } + ctx.setLineDash([]); + points + .map((p, i) => ({ p, q: proj[i]! })) + .sort((a, b) => b.q.z - a.q.z) + .forEach(({ p, q }) => { + const depth = Math.max(0, Math.min(1, (q.z + 220) / 440)); + const base = p.kind === 0 ? palette.text : p.kind === 1 ? palette.indigo : palette.textSecondary; + ctx.fillStyle = mix(base, palette.canvas, depth * 0.6); + const r = p.r * q.k * s * 1.25; + ctx.beginPath(); + if (p.kind === 1) ctx.rect(q.x - r, q.y - r, r * 2, r * 2); + else ctx.arc(q.x, q.y, r, 0, Math.PI * 2); + ctx.fill(); + }); + }; + const loop = () => { + angle += 0.0011; + draw(); + if (visible && !reducedMotion) raf = requestAnimationFrame(loop); + }; + draw(); + // Animate only while the drawing is on screen and motion is allowed. + const io = new IntersectionObserver(([e]) => { + visible = !!e?.isIntersecting; + cancelAnimationFrame(raf); + if (visible && !reducedMotion) raf = requestAnimationFrame(loop); + }); + io.observe(canvas); + const ro = new ResizeObserver(draw); + ro.observe(canvas); + return () => { + cancelAnimationFrame(raf); + io.disconnect(); + ro.disconnect(); + }; + }, [palette, reducedMotion]); + return ; +} diff --git a/apps/web/src/components/ViewControls.tsx b/apps/web/src/components/ViewControls.tsx new file mode 100644 index 0000000..ba20ae2 --- /dev/null +++ b/apps/web/src/components/ViewControls.tsx @@ -0,0 +1,120 @@ +import { SlidersHorizontal, X } from 'lucide-react'; +import { Popover } from 'radix-ui'; +import { type ReactNode, useMemo } from 'react'; +import { EDGE_TYPES, EDGE_TYPE_LABELS, NODE_TYPES, NODE_TYPE_LABELS, type NodeType } from '@vectora/graph-schema'; +import { useWorkspace } from '@/lib/store'; +import { FAMILY_GLYPH, NODE_FAMILY, nodeColor } from '@/lib/tokens'; +import { useWs } from '@/workspace/context'; +import { cx } from './ui'; + +/** Toolbar shown above every exploration view: filters, legend, focus and highlight state. */ +export function ViewToolbar({ children, status }: { children?: ReactNode; status?: ReactNode }) { + const { adj, view } = useWs(); + const focusId = useWorkspace((s) => s.focusId); + const setFocus = useWorkspace((s) => s.setFocus); + const highlight = useWorkspace((s) => s.highlight); + const setHighlight = useWorkspace((s) => s.setHighlight); + return ( +
+
+ + {children} + {focusId ? ( + + ) : null} + {highlight ? ( + + ) : null} +
+

+ {view.nodes.length.toLocaleString()} nodes, {view.edges.length.toLocaleString()} relationships + {view.collapsedSymbols ? `, ${view.collapsedSymbols.toLocaleString()} symbols folded into their files` : ''} + {view.truncated ? ' (limited by the node limit in Settings)' : ''} + {status ? <> — {status} : null} +

+
+ ); +} + +function FilterPopover() { + const { graph, palette } = useWs(); + const hiddenNodeTypes = useWorkspace((s) => s.hiddenNodeTypes); + const hiddenEdgeTypes = useWorkspace((s) => s.hiddenEdgeTypes); + const setHiddenNodeTypes = useWorkspace((s) => s.setHiddenNodeTypes); + const setHiddenEdgeTypes = useWorkspace((s) => s.setHiddenEdgeTypes); + const counts = useMemo(() => ({ nodes: graph.stats.nodesByType, edges: graph.stats.edgesByType }), [graph]); + const toggle = (list: string[], v: string, set: (l: string[]) => void) => set(list.includes(v) ? list.filter((x) => x !== v) : [...list, v]); + const nodeTypes = NODE_TYPES.filter((t) => (counts.nodes[t] ?? 0) > 0 && t !== 'Repository'); + const edgeTypes = EDGE_TYPES.filter((t) => (counts.edges[t] ?? 0) > 0); + const active = hiddenNodeTypes.length + hiddenEdgeTypes.length; + return ( + + + + + +
+
+ Node types + {nodeTypes.map((t) => ( + toggle(hiddenNodeTypes, t, setHiddenNodeTypes)} + label={NODE_TYPE_LABELS[t]} + count={counts.nodes[t] ?? 0} + swatch={ + + } + /> + ))} +
+
+ Relationships + {edgeTypes.map((t) => ( + toggle(hiddenEdgeTypes, t, setHiddenEdgeTypes)} label={EDGE_TYPE_LABELS[t]} count={counts.edges[t] ?? 0} /> + ))} +
+
+
+

+ + Solid line: relationship verified from source +

+

+ + Dashed or thin line: derived, not verified +

+

Each node type has its own glyph and size; names are shown as you zoom in.

+
+
+
+
+ ); +} + +function FilterRow({ checked, onChange, label, count, swatch }: { checked: boolean; onChange: () => void; label: string; count: number; swatch?: ReactNode }) { + return ( + + ); +} diff --git a/apps/web/src/components/ui.tsx b/apps/web/src/components/ui.tsx new file mode 100644 index 0000000..e881973 --- /dev/null +++ b/apps/web/src/components/ui.tsx @@ -0,0 +1,168 @@ +import { type ComponentProps, type ReactNode, useId } from 'react'; +import { Dialog as RDialog, Switch as RSwitch } from 'radix-ui'; +import { X } from 'lucide-react'; +import type { GraphNode } from '@vectora/graph-schema'; +import { NODE_TYPE_LABELS } from '@vectora/graph-schema'; +import { FAMILY_GLYPH, NODE_FAMILY } from '@/lib/tokens'; + +export const cx = (...parts: (string | false | null | undefined)[]): string => parts.filter(Boolean).join(' '); + +/** The brand wordmark. */ +export function Wordmark({ className }: { className?: string }) { + return ( + + VECTORA + + ); +} + +export function Dialog({ open, onOpenChange, title, description, children, wide }: { open: boolean; onOpenChange: (o: boolean) => void; title: string; description?: string; children: ReactNode; wide?: boolean }) { + return ( + + + + +
+
+ {title} + {description ? {description} : {title}} +
+ + + +
+
{children}
+
+
+
+ ); +} + +export function Toggle({ checked, onChange, label, hint }: { checked: boolean; onChange: (v: boolean) => void; label: string; hint?: string }) { + const id = useId(); + return ( +
+ + + + +
+ ); +} + +export function SelectField({ label, hint, value, onChange, options }: { label: string; hint?: string; value: T; onChange: (v: T) => void; options: { value: T; label: string }[] }) { + const id = useId(); + return ( +
+ + +
+ ); +} + +export function NumberField({ label, hint, value, onChange, min, max, step = 1, unit }: { label: string; hint?: string; value: number; onChange: (v: number) => void; min: number; max: number; step?: number; unit?: string }) { + const id = useId(); + return ( +
+ + + { + const v = Number(e.target.value); + if (Number.isFinite(v) && v >= min && v <= max) onChange(v); + }} + /> + {unit ? {unit} : null} + +
+ ); +} + +/** Type marker: a glyph plus the type name, so the type never depends on colour alone. */ +export function TypeMark({ node, showLabel = true }: { node: Pick; showLabel?: boolean }) { + return ( + + + {showLabel ? NODE_TYPE_LABELS[node.type] : {NODE_TYPE_LABELS[node.type]}} + + ); +} + +export function Notice({ tone = 'info', children, action }: { tone?: 'info' | 'error' | 'warning' | 'success'; children: ReactNode; action?: ReactNode }) { + const color = tone === 'error' ? 'var(--error)' : tone === 'warning' ? 'var(--warning)' : tone === 'success' ? 'var(--success)' : 'var(--indigo)'; + const word = tone === 'error' ? 'Error' : tone === 'warning' ? 'Note' : tone === 'success' ? 'Done' : 'Info'; + return ( +
+

+ + {word}. + {' '} + {children} +

+ {action} +
+ ); +} + +export function Empty({ title, children }: { title: string; children?: ReactNode }) { + return ( +
+

{title}

+
{children}
+
+ ); +} + +export function Loading({ label = 'Loading' }: { label?: string }) { + return ( +
+ {label}… +
+ ); +} + +export function SectionHeading({ children, aside, id }: { children: ReactNode; aside?: ReactNode; id?: string }) { + return ( +
+

+ {children} +

+ {aside ? {aside} : null} +
+ ); +} + +export function IconButton({ label, children, className, ...rest }: { label: string; children: ReactNode } & ComponentProps<'button'>) { + return ( + + ); +} diff --git a/apps/web/src/lib/api.ts b/apps/web/src/lib/api.ts new file mode 100644 index 0000000..f728d43 --- /dev/null +++ b/apps/web/src/lib/api.ts @@ -0,0 +1,199 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import type { GraphEdge, GraphNode, KnowledgeGraph } from '@vectora/graph-schema'; +import type { ExplorationAnswer, JobProgress, RepositoryOverview, RepositoryRecord, SessionState, Settings, SourceResponse } from '@vectora/shared'; + +export class ApiError extends Error { + constructor( + message: string, + public status: number, + ) { + super(message); + } +} + +async function request(url: string, init?: RequestInit): Promise { + let res: Response; + try { + res = await fetch(url, init); + } catch { + throw new ApiError('The local engine is not reachable. Start it with “npm start” (or “npm run dev”).', 0); + } + if (res.status === 204) return undefined as T; + const isJson = res.headers.get('content-type')?.includes('application/json'); + if (!res.ok) { + const body = isJson ? ((await res.json()) as { error?: string }) : null; + throw new ApiError(body?.error ?? (res.status >= 500 ? 'The local engine is not reachable or failed to answer.' : `Request failed (${res.status})`), res.status); + } + return (isJson ? res.json() : res.text()) as Promise; +} + +const json = (method: string, body?: unknown): RequestInit => ({ method, headers: { 'content-type': 'application/json' }, body: JSON.stringify(body ?? {}) }); + +export interface Health { + status: string; + version: string; + node: string; + python: boolean; + sampleAvailable: boolean; + languages: { id: string; name: string; tier: number; extensions: string[] }[]; +} +export interface GitHubInfo { + fullName: string; + description: string | null; + defaultBranch: string; + branches: string[]; + private: boolean; + sizeKb: number; + requested: { branch: string | null; subdirectory: string | null }; + usingStoredCredential: boolean; +} +export interface ZipInspection { + uploadId: string; + fileName: string; + entries: number; + files: number; + totalBytes: number; + rejected: { path: string; reason: string }[]; + roots: { path: string; files: number; markers: string[] }[]; + tree: { path: string; size: number; directory: boolean }[]; +} +export interface DirListing { + path: string; + parent: string | null; + entries: { name: string; path: string; repository: boolean }[]; + roots: string[]; +} +export interface SearchResponse { + query: string; + results: { id: string; name: string; type: GraphNode['type']; filePath: string | null; line: number | null; description: string | null; score: number; match: string }[]; + documents: { path: string; line: number; snippet: string; heading: string | null }[]; +} +export interface AnalysisResponse { + generatedAt: string; + flows: { id: string; name: string; kind: string; steps: string[]; reachesData: boolean }[]; + entryPoints: { path: string; nodeId: string; reason: string }[]; + declaredDependencies: { name: string; version: string | null; manifest: string; ecosystem: string; dev: boolean; line: number }[]; + unresolvedCount: number; + unresolvedByReason: Record; + unresolvedSamples: { fromPath: string; fromSymbol: string | null; kind: string; name: string; line: number; reason: string }[]; + parseIssues: { path: string; message: string; line?: number; severity: string }[]; + skipped: Record; + truncated: boolean; + validation: { errors: number; warnings: number }; + communities: number; +} +export type GraphResponse = KnowledgeGraph & { partial: boolean }; + +export const api = { + health: () => request('/api/health'), + repositories: () => request('/api/repositories'), + repository: (id: string) => request(`/api/repositories/${id}`), + deleteRepository: (id: string) => request(`/api/repositories/${id}`, { method: 'DELETE' }), + reindex: (id: string, full = false) => request(`/api/repositories/${id}/reindex`, json('POST', { full })), + job: (id: string) => request(`/api/jobs/${id}`), + importLocal: (path: string, name?: string) => request('/api/import/local', json('POST', { path, name })), + importSample: () => request('/api/import/sample', json('POST')), + listDir: (path?: string) => request(`/api/fs/list${path ? `?path=${encodeURIComponent(path)}` : ''}`), + inspectZip: (file: File) => { + const form = new FormData(); + form.append('file', file); + return request('/api/import/zip/inspect', { method: 'POST', body: form }); + }, + importZip: (uploadId: string, root?: string, name?: string) => request('/api/import/zip', json('POST', { uploadId, root, name })), + // The token travels in the request body over the loopback interface only; it is never put in a URL. + validateGitHub: (url: string, token?: string) => request('/api/import/github/validate', json('POST', { url, token: token || undefined })), + importGitHub: (body: { url: string; branch?: string; subdirectory?: string; token?: string; rememberToken?: boolean }) => request('/api/import/github', json('POST', body)), + graph: (id: string, detail: 'full' | 'structure') => request(`/api/repositories/${id}/graph?detail=${detail}`), + members: (id: string, path: string) => request<{ nodes: GraphNode[]; edges: GraphEdge[] }>(`/api/repositories/${id}/members?path=${encodeURIComponent(path)}`), + overview: (id: string) => request(`/api/repositories/${id}/overview`), + analysis: (id: string) => request(`/api/repositories/${id}/analysis`), + source: (id: string, path: string, start?: number, end?: number) => + request(`/api/repositories/${id}/source?path=${encodeURIComponent(path)}${start ? `&start=${start}` : ''}${end ? `&end=${end}` : ''}`), + docs: (id: string) => request<{ path: string; title: string; lines: number }[]>(`/api/repositories/${id}/docs`), + search: (id: string, q: string, types?: string[]) => request(`/api/repositories/${id}/search?q=${encodeURIComponent(q)}${types?.length ? `&types=${types.join(',')}` : ''}`), + ask: (id: string, question: string) => request(`/api/repositories/${id}/ask`, json('POST', { question })), + session: (id: string) => request(`/api/repositories/${id}/session`), + saveSession: (id: string, s: SessionState) => request(`/api/repositories/${id}/session`, json('PUT', s)), + settings: () => request('/api/settings'), + updateSettings: (patch: unknown) => request('/api/settings', json('PUT', patch)), + credentials: () => request<{ name: string; updatedAt: string }[]>('/api/credentials'), + setCredential: (name: string, value: string) => request(`/api/credentials/${name}`, json('PUT', { value })), + deleteCredential: (name: string) => request(`/api/credentials/${name}`, { method: 'DELETE' }), + dataInfo: () => request<{ dataDir: string; databaseBytes: number; sourcesBytes: number; repositories: number; credentials: number }>('/api/data'), + deleteAllData: () => request('/api/data', { method: 'DELETE' }), + clearCache: () => request('/api/cache', { method: 'DELETE' }), + exportUrl: (id: string, format: string, includeSource: boolean) => `/api/repositories/${id}/export/${format}${includeSource ? '?includeSource=true' : ''}`, +}; + +// ---- hooks --------------------------------------------------------------- + +export const useHealth = () => useQuery({ queryKey: ['health'], queryFn: api.health, staleTime: 60_000, retry: 1 }); +export const useRepositories = () => useQuery({ queryKey: ['repositories'], queryFn: api.repositories }); +export const useRepository = (id: string) => + useQuery({ queryKey: ['repository', id], queryFn: () => api.repository(id), refetchInterval: (q) => (q.state.data?.status === 'indexing' || q.state.data?.status === 'pending' ? 1000 : false) }); +export const useOverview = (id: string, enabled = true) => useQuery({ queryKey: ['overview', id], queryFn: () => api.overview(id), enabled }); +export const useAnalysis = (id: string) => useQuery({ queryKey: ['analysis', id], queryFn: () => api.analysis(id) }); +export const useSource = (id: string, path: string | null, start?: number, end?: number) => + useQuery({ queryKey: ['source', id, path, start, end], queryFn: () => api.source(id, path!, start, end), enabled: !!path, staleTime: 5 * 60_000 }); +export const useJob = (jobId: string | null) => + useQuery({ queryKey: ['job', jobId], queryFn: () => api.job(jobId!), enabled: !!jobId, refetchInterval: (q) => (q.state.data && q.state.data.status !== 'running' ? false : 400) }); + +export function useSettings() { + const qc = useQueryClient(); + const query = useQuery({ queryKey: ['settings'], queryFn: api.settings, staleTime: Infinity }); + const mutation = useMutation({ + mutationFn: api.updateSettings, + onMutate: async (patch: Record>) => { + // Optimistic: settings take effect immediately and are then confirmed by the engine. + const prev = qc.getQueryData(['settings']); + if (prev) { + const next = structuredClone(prev) as unknown as Record>; + for (const [section, values] of Object.entries(patch)) next[section] = { ...next[section], ...values }; + qc.setQueryData(['settings'], next); + } + return { prev }; + }, + onError: (_e, _p, ctx) => ctx?.prev && qc.setQueryData(['settings'], ctx.prev), + onSuccess: (data) => qc.setQueryData(['settings'], data), + }); + return { settings: query.data ?? null, update: mutation.mutate, error: mutation.error ?? query.error, saving: mutation.isPending }; +} + +/** + * Loads the knowledge graph. Large repositories are loaded progressively: + * the structural skeleton first, symbols of a file when it is expanded. + */ +export function useGraph(id: string, symbolCount: number, maxNodes: number, enabled = true) { + const qc = useQueryClient(); + const detail: 'full' | 'structure' = symbolCount > maxNodes ? 'structure' : 'full'; + const query = useQuery({ queryKey: ['graph', id, detail], queryFn: () => api.graph(id, detail), enabled, staleTime: Infinity, gcTime: 10 * 60_000 }); + const loadMembers = async (path: string): Promise => { + const current = qc.getQueryData(['graph', id, detail]); + if (!current?.partial) return; + const extra = await qc.fetchQuery({ queryKey: ['members', id, path], queryFn: () => api.members(id, path), staleTime: Infinity }); + qc.setQueryData(['graph', id, detail], (g) => { + if (!g) return g; + const ids = new Set(g.nodes.map((n) => n.id)); + const nodes = [...g.nodes, ...extra.nodes.filter((n) => !ids.has(n.id))]; + const all = new Set(nodes.map((n) => n.id)); + const eids = new Set(g.edges.map((e) => e.id)); + const edges = [...g.edges, ...extra.edges.filter((e) => !eids.has(e.id) && all.has(e.source) && all.has(e.target))]; + return { ...g, nodes, edges }; + }); + }; + return { graph: query.data ?? null, isLoading: query.isLoading, error: query.error, partial: query.data?.partial ?? false, loadMembers }; +} + +export function downloadText(fileName: string, text: string, type = 'text/plain'): void { + const url = URL.createObjectURL(new Blob([text], { type })); + downloadUrl(fileName, url); + setTimeout(() => URL.revokeObjectURL(url), 2000); +} +export function downloadUrl(fileName: string, url: string): void { + const a = document.createElement('a'); + a.href = url; + a.download = fileName; + document.body.appendChild(a); + a.click(); + a.remove(); +} diff --git a/apps/web/src/lib/graphView.ts b/apps/web/src/lib/graphView.ts new file mode 100644 index 0000000..5e19087 --- /dev/null +++ b/apps/web/src/lib/graphView.ts @@ -0,0 +1,171 @@ +/** + * Derives what the visualisations show from the full knowledge graph and the + * current filters. All three views call this with the same inputs, so they + * always present the same underlying graph. + */ +import { type EdgeType, type GraphEdge, type GraphNode, type KnowledgeGraph, type NodeType, isSymbolType } from '@vectora/graph-schema'; + +export interface ViewOptions { + density: 'structure' | 'balanced' | 'full'; + expandedIds: readonly string[]; + hiddenNodeTypes: readonly string[]; + hiddenEdgeTypes: readonly string[]; + showUnverified: boolean; + focusId: string | null; + focusDepth?: number; + maxNodes: number; + /** Nodes that must stay visible (selection, highlights). */ + pinnedIds?: readonly string[]; +} + +export interface GraphView { + nodes: GraphNode[]; + edges: GraphEdge[]; + /** Symbols left out by the density setting (they appear when their file is expanded). */ + collapsedSymbols: number; + truncated: boolean; +} + +export interface Adjacency { + nodes: Map; + out: Map; + in: Map; +} + +export function buildAdjacency(graph: Pick): Adjacency { + const nodes = new Map(); + const out = new Map(); + const inn = new Map(); + for (const n of graph.nodes) nodes.set(n.id, n); + for (const e of graph.edges) { + (out.get(e.source) ?? out.set(e.source, []).get(e.source)!).push(e); + (inn.get(e.target) ?? inn.set(e.target, []).get(e.target)!).push(e); + } + return { nodes, out, in: inn }; +} + +const PROMINENT: ReadonlySet = new Set(['Class', 'DatabaseModel', 'ApiEndpoint', 'Component', 'Interface']); +const BALANCED_LIMIT = 1200; + +export const fileIdOf = (n: GraphNode): string | null => (n.filePath ? `file:${n.filePath}` : null); + +export function deriveView(graph: Pick, adj: Adjacency, o: ViewOptions): GraphView { + const hiddenTypes = new Set(o.hiddenNodeTypes); + const hiddenEdges = new Set(o.hiddenEdgeTypes); + const expanded = new Set(o.expandedIds); + const pinned = new Set(o.pinnedIds ?? []); + const symbolTotal = graph.nodes.reduce((a, n) => a + (isSymbolType(n.type) ? 1 : 0), 0); + + let focusSet: Set | null = null; + if (o.focusId && adj.nodes.has(o.focusId)) { + focusSet = new Set([o.focusId]); + let frontier = [o.focusId]; + for (let d = 0; d < (o.focusDepth ?? 1); d++) { + const next: string[] = []; + for (const id of frontier) + for (const e of [...(adj.out.get(id) ?? []), ...(adj.in.get(id) ?? [])]) { + if (hiddenEdges.has(e.type)) continue; + const other = e.source === id ? e.target : e.source; + if (!focusSet.has(other)) { + focusSet.add(other); + next.push(other); + } + } + frontier = next; + } + // Keep the containing file of every focused symbol for context. + for (const id of [...focusSet]) { + const f = adj.nodes.get(id); + const fid = f ? fileIdOf(f) : null; + if (fid && adj.nodes.has(fid)) focusSet.add(fid); + } + } + + let collapsedSymbols = 0; + const visible: GraphNode[] = []; + for (const n of graph.nodes) { + if (focusSet) { + if (focusSet.has(n.id)) visible.push(n); + continue; + } + if (pinned.has(n.id)) { + visible.push(n); + continue; + } + if (hiddenTypes.has(n.type)) continue; + if (isSymbolType(n.type)) { + const fid = fileIdOf(n); + const fileExpanded = !!fid && expanded.has(fid); + const show = + fileExpanded || + o.density === 'full' || + (o.density === 'balanced' && (symbolTotal <= BALANCED_LIMIT || PROMINENT.has(n.type))); + if (!show) { + collapsedSymbols++; + continue; + } + } + visible.push(n); + } + + let truncated = false; + let nodes = visible; + if (nodes.length > o.maxNodes) { + truncated = true; + // Keep structure first, then the best-connected symbols. + const degree = (id: string) => (adj.out.get(id)?.length ?? 0) + (adj.in.get(id)?.length ?? 0); + const rank = (n: GraphNode) => (pinned.has(n.id) ? 0 : isSymbolType(n.type) ? 2 : 1); + nodes = [...nodes].sort((a, b) => rank(a) - rank(b) || degree(b.id) - degree(a.id)).slice(0, o.maxNodes); + } + const ids = new Set(nodes.map((n) => n.id)); + const edges: GraphEdge[] = []; + for (const e of graph.edges) { + if (hiddenEdges.has(e.type)) continue; + if (!o.showUnverified && !e.verified) continue; + if (ids.has(e.source) && ids.has(e.target)) edges.push(e); + } + return { nodes, edges, collapsedSymbols, truncated }; +} + +/** Node ids within one hop of `id` over the given edges (the node itself included). */ +export function neighbourhood(id: string, edges: readonly GraphEdge[]): { nodes: Set; edges: Set } { + const nodes = new Set([id]); + const edgeIds = new Set(); + for (const e of edges) { + if (e.source === id || e.target === id) { + nodes.add(e.source); + nodes.add(e.target); + edgeIds.add(e.id); + } + } + return { nodes, edges: edgeIds }; +} + +export interface Relations { + incoming: GraphEdge[]; + outgoing: GraphEdge[]; + parent: GraphNode | null; + children: GraphNode[]; + concepts: GraphNode[]; + subsystem: GraphNode | null; +} + +const HIERARCHY: ReadonlySet = new Set(['CONTAINS', 'DEFINED_IN', 'BELONGS_TO']); + +export function relationsOf(id: string, adj: Adjacency): Relations { + const node = adj.nodes.get(id); + const out = adj.out.get(id) ?? []; + const inn = adj.in.get(id) ?? []; + const parentEdge = inn.find((e) => e.type === 'CONTAINS'); + const fileNode = node && isSymbolType(node.type) ? adj.nodes.get(fileIdOf(node) ?? '') : node; + const conceptIds = (fileNode?.metadata.concepts as string[] | undefined) ?? []; + const subsystemId = (node?.metadata.subsystem as string | undefined) ?? (fileNode?.metadata.subsystem as string | undefined); + return { + incoming: inn.filter((e) => !HIERARCHY.has(e.type)), + outgoing: out.filter((e) => !HIERARCHY.has(e.type)), + parent: parentEdge ? (adj.nodes.get(parentEdge.source) ?? null) : null, + children: out.filter((e) => e.type === 'CONTAINS').map((e) => adj.nodes.get(e.target)).filter((n): n is GraphNode => !!n), + concepts: conceptIds.map((c) => adj.nodes.get(c)).filter((n): n is GraphNode => !!n), + subsystem: subsystemId ? (adj.nodes.get(subsystemId) ?? null) : null, + }; +} diff --git a/apps/web/src/lib/store.ts b/apps/web/src/lib/store.ts new file mode 100644 index 0000000..7701438 --- /dev/null +++ b/apps/web/src/lib/store.ts @@ -0,0 +1,122 @@ +/** + * Workspace state shared by all three exploration views: selection, focus, + * expansion and filters live here so that selecting a node in one view shows + * it selected in the others. + */ +import { create } from 'zustand'; +import type { SessionState } from '@vectora/shared'; + +export interface Highlight { + label: string; + nodeIds: string[]; + edgeIds: string[]; +} + +interface WorkspaceState { + repoId: string | null; + selectedIds: string[]; + /** Most recently selected node — the one shown in the inspector. */ + primaryId: string | null; + hoverId: string | null; + /** Focus mode: only this node and its neighbourhood are shown. */ + focusId: string | null; + /** Files whose symbols are shown. */ + expandedIds: string[]; + hiddenNodeTypes: string[]; + hiddenEdgeTypes: string[]; + highlight: Highlight | null; + inspectorOpen: boolean; + inspectorWidth: number; + paletteOpen: boolean; + layouts: SessionState['layouts']; + /** Bumped whenever a view should re-centre on the primary selection. */ + revealTick: number; + sessionLoaded: boolean; + + select: (id: string, opts?: { additive?: boolean; reveal?: boolean }) => void; + clearSelection: () => void; + setHover: (id: string | null) => void; + setFocus: (id: string | null) => void; + toggleExpanded: (id: string, force?: boolean) => void; + setHiddenNodeTypes: (t: string[]) => void; + setHiddenEdgeTypes: (t: string[]) => void; + setHighlight: (h: Highlight | null) => void; + setInspector: (open: boolean, width?: number) => void; + setPaletteOpen: (open: boolean) => void; + setLayout: (key: K, value: SessionState['layouts'][K]) => void; + hydrate: (repoId: string, session: SessionState | null, defaults: { hiddenEdgeTypes: string[] }) => void; + snapshot: (view: string) => SessionState; +} + +export const DEFAULT_HIDDEN_NODE_TYPES = ['Directory', 'Module', 'Package', 'Configuration']; + +export const useWorkspace = create((set, get) => ({ + repoId: null, + selectedIds: [], + primaryId: null, + hoverId: null, + focusId: null, + expandedIds: [], + hiddenNodeTypes: DEFAULT_HIDDEN_NODE_TYPES, + hiddenEdgeTypes: ['DEFINED_IN', 'EXPORTS'], + highlight: null, + inspectorOpen: true, + inspectorWidth: 380, + paletteOpen: false, + layouts: {}, + revealTick: 0, + sessionLoaded: false, + + select: (id, opts) => + set((s) => { + if (opts?.additive) { + const has = s.selectedIds.includes(id); + const selectedIds = has ? s.selectedIds.filter((x) => x !== id) : [...s.selectedIds, id]; + return { selectedIds, primaryId: has ? (selectedIds[selectedIds.length - 1] ?? null) : id, inspectorOpen: true }; + } + return { selectedIds: [id], primaryId: id, inspectorOpen: true, revealTick: opts?.reveal ? s.revealTick + 1 : s.revealTick }; + }), + clearSelection: () => set({ selectedIds: [], primaryId: null }), + setHover: (hoverId) => set((s) => (s.hoverId === hoverId ? s : { hoverId })), + setFocus: (focusId) => set((s) => ({ focusId, revealTick: s.revealTick + 1 })), + toggleExpanded: (id, force) => + set((s) => { + const has = s.expandedIds.includes(id); + const want = force ?? !has; + if (want === has) return s; + return { expandedIds: want ? [...s.expandedIds, id] : s.expandedIds.filter((x) => x !== id) }; + }), + setHiddenNodeTypes: (hiddenNodeTypes) => set({ hiddenNodeTypes }), + setHiddenEdgeTypes: (hiddenEdgeTypes) => set({ hiddenEdgeTypes }), + setHighlight: (highlight) => set({ highlight }), + setInspector: (inspectorOpen, width) => set((s) => ({ inspectorOpen, inspectorWidth: width ?? s.inspectorWidth })), + setPaletteOpen: (paletteOpen) => set({ paletteOpen }), + setLayout: (key, value) => set((s) => ({ layouts: { ...s.layouts, [key]: value } })), + hydrate: (repoId, session, defaults) => + set({ + repoId, + selectedIds: session?.selectedIds ?? [], + primaryId: session?.selectedIds?.[session.selectedIds.length - 1] ?? null, + focusId: session?.focusId ?? null, + expandedIds: session?.expandedIds ?? [], + hiddenNodeTypes: session?.hiddenNodeTypes ?? DEFAULT_HIDDEN_NODE_TYPES, + hiddenEdgeTypes: session?.hiddenEdgeTypes ?? defaults.hiddenEdgeTypes, + layouts: session?.layouts ?? {}, + highlight: null, + hoverId: null, + sessionLoaded: true, + }), + snapshot: (view) => { + const s = get(); + return { + view, + selectedIds: s.selectedIds.slice(0, 200), + focusId: s.focusId, + expandedIds: s.expandedIds.slice(0, 2000), + hiddenNodeTypes: s.hiddenNodeTypes, + hiddenEdgeTypes: s.hiddenEdgeTypes, + layouts: s.layouts, + savedAt: new Date().toISOString(), + }; + }, +})); diff --git a/apps/web/src/lib/theme.ts b/apps/web/src/lib/theme.ts new file mode 100644 index 0000000..3d94658 --- /dev/null +++ b/apps/web/src/lib/theme.ts @@ -0,0 +1,45 @@ +import { useEffect, useSyncExternalStore } from 'react'; +import type { Settings } from '@vectora/shared'; +import { type Palette, paletteFor } from './tokens'; + +const media = (q: string) => ({ + subscribe: (cb: () => void) => { + const m = window.matchMedia(q); + m.addEventListener('change', cb); + return () => m.removeEventListener('change', cb); + }, + get: () => window.matchMedia(q).matches, +}); +const darkMedia = media('(prefers-color-scheme: dark)'); +const motionMedia = media('(prefers-reduced-motion: reduce)'); + +export type ThemeSetting = 'light' | 'dark' | 'system'; + +/** Resolves the theme setting against the system preference and applies it to the document. */ +export function useTheme(setting: ThemeSetting | undefined): 'light' | 'dark' { + const systemDark = useSyncExternalStore(darkMedia.subscribe, darkMedia.get, () => false); + const stored = (typeof localStorage !== 'undefined' ? localStorage.getItem('vectora-theme') : null) as ThemeSetting | null; + const effective = setting ?? stored ?? 'system'; + const theme = effective === 'system' ? (systemDark ? 'dark' : 'light') : effective; + useEffect(() => { + document.documentElement.dataset.theme = theme; + if (setting) localStorage.setItem('vectora-theme', setting); + }, [theme, setting]); + return theme; +} + +/** True when motion should be reduced, from settings or the system preference. */ +export function useReducedMotion(settings: Settings | null): boolean { + const system = useSyncExternalStore(motionMedia.subscribe, motionMedia.get, () => false); + const pref = settings?.performance.reducedMotion ?? 'system'; + const reduced = pref === 'on' || settings?.graph.animationIntensity === 'none' || (pref === 'system' && system); + useEffect(() => { + const el = document.documentElement; + if (pref === 'on' || settings?.graph.animationIntensity === 'none') el.dataset.motion = 'reduced'; + else if (pref === 'off') el.dataset.motion = 'full'; + else delete el.dataset.motion; + }, [pref, settings?.graph.animationIntensity]); + return reduced; +} + +export const usePalette = (theme: 'light' | 'dark'): Palette => paletteFor(theme); diff --git a/apps/web/src/lib/tokens.ts b/apps/web/src/lib/tokens.ts new file mode 100644 index 0000000..8b85602 --- /dev/null +++ b/apps/web/src/lib/tokens.ts @@ -0,0 +1,180 @@ +/** + * Design tokens — the single source of truth for colour. `styles.css` mirrors + * these values as CSS custom properties (a unit test keeps the two in step); + * WebGL renderers read them from here because they cannot use CSS variables. + */ +import type { EdgeType, NodeType } from '@vectora/graph-schema'; + +export interface Palette { + canvas: string; + surface: string; + elevated: string; + text: string; + textSecondary: string; + textMuted: string; + line: string; + indigo: string; + clay: string; + ash: string; + success: string; + warning: string; + error: string; + selection: string; + relationActive: string; + relationUnverified: string; +} + +export const LIGHT: Palette = { + canvas: '#F8F7F2', + surface: '#F3F1EA', // Washi + elevated: '#FBFAF6', + text: '#20211F', // Sumi + textSecondary: '#5F5D55', + textMuted: '#8C897F', // Stone + line: '#DCD8CE', + indigo: '#34445C', + clay: '#A18C72', + ash: '#B8B3A7', + success: '#55704F', + warning: '#8F6B25', + error: '#964436', + selection: '#34445C', + relationActive: '#34445C', + relationUnverified: '#A18C72', +}; + +export const DARK: Palette = { + canvas: '#171816', + surface: '#20211F', + elevated: '#272824', + text: '#ECEAE2', + textSecondary: '#A7A499', + textMuted: '#77766D', + line: '#373832', + indigo: '#8292AD', + clay: '#B39A7A', + ash: '#5C5B54', + success: '#8FAE8A', + warning: '#C9A566', + error: '#D08C7C', + selection: '#8292AD', + relationActive: '#8292AD', + relationUnverified: '#B39A7A', +}; + +export const paletteFor = (theme: 'light' | 'dark'): Palette => (theme === 'dark' ? DARK : LIGHT); + +/** Visual family of a node type. Colour is always paired with shape (3D), size and a text label. */ +export type NodeFamily = 'structure' | 'file' | 'type' | 'callable' | 'data' | 'endpoint' | 'concept' | 'external' | 'value'; + +export const NODE_FAMILY: Record = { + Repository: 'structure', + Subsystem: 'structure', + Module: 'structure', + Directory: 'structure', + File: 'file', + Configuration: 'file', + Package: 'external', + Class: 'type', + Interface: 'type', + Type: 'type', + Component: 'type', + Function: 'callable', + Method: 'callable', + Variable: 'value', + Constant: 'value', + ApiEndpoint: 'endpoint', + DatabaseModel: 'data', + Concept: 'concept', +}; + +export const FAMILY_LABEL: Record = { + structure: 'Structure', + file: 'Files', + type: 'Types and classes', + callable: 'Functions and methods', + data: 'Database models', + endpoint: 'API endpoints', + concept: 'Concepts', + external: 'External packages', + value: 'Variables and constants', +}; + +/** Single-character glyph shown next to labels so type never depends on colour alone. */ +export const FAMILY_GLYPH: Record = { + structure: '◼', + file: '▫', + type: '◆', + callable: '●', + data: '▤', + endpoint: '▶', + concept: '◎', + external: '○', + value: '·', +}; + +export function familyColor(family: NodeFamily, p: Palette): string { + switch (family) { + case 'structure': + return p.text; + case 'file': + return p.textMuted; + case 'type': + return p.indigo; + case 'callable': + return p.textSecondary; + case 'data': + return p.clay; + case 'endpoint': + return p.warning; + case 'concept': + return p.success; + case 'external': + return p.ash; + case 'value': + return p.ash; + } +} + +export const nodeColor = (type: NodeType, p: Palette): string => familyColor(NODE_FAMILY[type], p); + +/** Relative node size by type: repository largest, functions smallest. */ +export const NODE_SIZE: Record = { + Repository: 10, + Subsystem: 7, + Concept: 6, + Module: 4.5, + Directory: 3.5, + Package: 3.5, + File: 3.2, + Configuration: 2.8, + Class: 2.8, + DatabaseModel: 2.8, + Component: 2.6, + Interface: 2.4, + ApiEndpoint: 2.4, + Type: 2, + Function: 1.8, + Method: 1.6, + Constant: 1.3, + Variable: 1.3, +}; + +/** Relationship types whose direction expresses a dependency (drawn with arrows). */ +export const STRUCTURE_EDGES: readonly EdgeType[] = ['CONTAINS', 'DEFINED_IN', 'BELONGS_TO', 'EXPORTS']; + +export const hexToRgb = (hex: string): [number, number, number] => { + const n = parseInt(hex.slice(1), 16); + return [(n >> 16) & 255, (n >> 8) & 255, n & 255]; +}; +export const withAlpha = (hex: string, a: number): string => { + const [r, g, b] = hexToRgb(hex); + return `rgba(${r},${g},${b},${a})`; +}; +/** Blends `hex` towards `bg` — used to dim unrelated nodes without transparency sorting issues. */ +export const mix = (hex: string, bg: string, t: number): string => { + const a = hexToRgb(hex); + const b = hexToRgb(bg); + const c = a.map((v, i) => Math.round(v + (b[i]! - v) * t)); + return `#${c.map((v) => v.toString(16).padStart(2, '0')).join('')}`; +}; diff --git a/apps/web/src/main.tsx b/apps/web/src/main.tsx new file mode 100644 index 0000000..42e3a46 --- /dev/null +++ b/apps/web/src/main.tsx @@ -0,0 +1,17 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import { App } from './App'; +import './styles.css'; + +const queryClient = new QueryClient({ + defaultOptions: { queries: { refetchOnWindowFocus: false, retry: (count, err) => count < 1 && (err as { status?: number }).status !== 404 } }, +}); + +createRoot(document.getElementById('root')!).render( + + + + + , +); diff --git a/apps/web/src/pages/About.tsx b/apps/web/src/pages/About.tsx new file mode 100644 index 0000000..7fb5056 --- /dev/null +++ b/apps/web/src/pages/About.tsx @@ -0,0 +1,166 @@ +import type { ReactNode } from 'react'; +import { APP_VERSION } from '@vectora/shared'; +import { SitePage } from '@/components/Site'; +import { useHealth } from '@/lib/api'; + +const CREDITS: [string, string, string][] = [ + ['TypeScript', 'Compiler API used for TypeScript and JavaScript analysis', 'Apache-2.0'], + ['Tree-sitter', 'Parsing for Java, Go, Rust, C, C++ and C#', 'MIT'], + ['Python', 'Standard-library ast module for Python analysis', 'PSF'], + ['SQLite', 'Local graph database (built into Node.js)', 'Public domain'], + ['Fastify', 'Local engine HTTP server', 'MIT'], + ['React and Vite', 'Application framework and build tool', 'MIT'], + ['Sigma.js and Graphology', 'Two-dimensional graph rendering and graph algorithms', 'MIT'], + ['Three.js, React Three Fiber and drei', 'Three-dimensional rendering', 'MIT'], + ['d3-force-3d', 'Force simulation for the 3D layout', 'MIT'], + ['React Flow and dagre', 'Mind map canvas and hierarchical layout', 'MIT'], + ['CodeMirror 6', 'Source preview', 'MIT'], + ['Radix UI, cmdk and Lucide', 'Accessible dialogs, command palette and icons', 'MIT / ISC'], + ['Tailwind CSS', 'Styling', 'MIT'], + ['Zen Kaku Gothic New, Shippori Mincho, IBM Plex Mono', 'Typefaces, bundled with the application', 'SIL OFL 1.1'], +]; + +function Block({ id, title, children }: { id: string; title: string; children: ReactNode }) { + return ( +
+

+ {title} +

+
{children}
+
+ ); +} + +export function About() { + const health = useHealth(); + return ( + +
+
+
+

VECTORA

+

Understand what connects.

+

+ VECTORA is a codebase intelligence platform that transforms software repositories into structured, interactive knowledge maps. It reveals how components, modules, dependencies and concepts connect, giving developers a new way to understand complex software systems. +

+
+
+ + +

+ Software is understood through its connections: what calls what, what depends on what, where a request ends up. Those connections are spread across hundreds of files, and reading the files in order does not reveal them. +

+

VECTORA is built on three commitments.

+

+ Evidence first. Every relationship carries the file, the line and the method that found it. A reference that cannot be tied to a definition is reported as unresolved. It is never drawn as if it were known. +

+

+ Local by default. Analysis, storage and search run on your own machine. The application works with no account and no hosted service. +

+

+ Restraint. The interface follows the Japanese ideas of kanso, simplicity, and ma, the meaningful interval. Space, type and a small palette do the work; decoration does not. +

+
+ + +

A repository goes through a fixed pipeline: discovery of files and manifests, syntax analysis by a language adapter, resolution of references across files, tracing of execution flows, grouping into subsystems and concepts, and generation of a validated knowledge graph that is stored in a local database.

+

The Graph Explorer, the 3D Atlas and the Mind Map all read that one graph and share one selection. Verified structure and derived interpretation are kept apart throughout, and drawn differently.

+
+ + +

Symbol-level analysis is available for the languages below. Other files are indexed as files only, and each repository shows its own language coverage.

+ + + + + + + + + + {(health.data?.languages ?? FALLBACK_LANGUAGES).map((l) => ( + + + + + + ))} + +
LanguageTierTechnique
{l.name}{l.tier}{l.id === 'typescript' || l.id === 'javascript' ? 'TypeScript Compiler API with type-checked resolution' : l.id === 'python' ? 'Python ast module with import and scope resolution' : 'Tree-sitter syntax tree with import and scope resolution'}
+

Tier 1 languages have the most precise relationship resolution. VECTORA does not claim to support every language.

+
+ + +
    +
  • Source code is read and analysed locally. It is not uploaded.
  • +
  • Repository scripts are never executed and repository dependencies are never installed.
  • +
  • Access tokens are stored encrypted on your machine, sent only to GitHub in a request header, and never written to logs, URLs or exports.
  • +
  • Exports contain names, paths and line numbers. Lines of source are included only when you ask for them.
  • +
  • The one optional external service, a narrative summary for answers, is off by default and receives only the findings already shown on screen.
  • +
  • All stored data can be deleted from Settings.
  • +
+
+ + +

VECTORA stands on open-source work. With thanks to the people who maintain it.

+ + + + + + + + + + {CREDITS.map(([name, use, lic]) => ( + + + + + + ))} + +
ProjectUsed forLicence
{name}{use}{lic}
+

+ The full inventory of dependency licences is generated into docs/LICENSES.md in the VECTORA folder. +

+
+ + +
+
Version
+
{APP_VERSION}
+
Local engine
+
{health.data ? `running, version ${health.data.version} on Node.js ${health.data.node}` : health.isLoading ? 'checking' : 'not reachable'}
+
Licence
+
MIT. See the LICENSE file in the VECTORA folder.
+
+
+ + +

The documentation ships with the application, in the docs folder:

+
    + {['USER_GUIDE.md', 'ARCHITECTURE.md', 'DATA_MODEL.md', 'INDEXING_PIPELINE.md', 'VISUALIZATION.md', 'SECURITY.md', 'PERFORMANCE.md', 'TROUBLESHOOTING.md'].map((f) => ( +
  • docs/{f}
  • + ))} +
+

+ Changes between versions are recorded in docs/CHANGELOG.md. +

+
+
+
+ ); +} + +const FALLBACK_LANGUAGES = [ + { id: 'typescript', name: 'TypeScript', tier: 1 }, + { id: 'javascript', name: 'JavaScript', tier: 1 }, + { id: 'python', name: 'Python', tier: 1 }, + { id: 'java', name: 'Java', tier: 2 }, + { id: 'go', name: 'Go', tier: 2 }, + { id: 'rust', name: 'Rust', tier: 2 }, + { id: 'c', name: 'C', tier: 2 }, + { id: 'cpp', name: 'C++', tier: 2 }, + { id: 'csharp', name: 'C#', tier: 2 }, +]; diff --git a/apps/web/src/pages/ImportPage.tsx b/apps/web/src/pages/ImportPage.tsx new file mode 100644 index 0000000..921bb10 --- /dev/null +++ b/apps/web/src/pages/ImportPage.tsx @@ -0,0 +1,435 @@ +import { useQuery, useQueryClient } from '@tanstack/react-query'; +import { Folder, FolderGit2 } from 'lucide-react'; +import { useEffect, useRef, useState } from 'react'; +import { useNavigate } from 'react-router'; +import { formatBytes } from '@vectora/shared'; +import { SitePage } from '@/components/Site'; +import { Dialog, Notice, cx } from '@/components/ui'; +import { ApiError, type GitHubInfo, type ZipInspection, api, useHealth, useJob, useRepositories } from '@/lib/api'; +import { IndexingProgress } from '@/workspace/WorkspaceLayout'; + +type Method = 'github' | 'zip' | 'local'; + +export function ImportPage() { + const navigate = useNavigate(); + const qc = useQueryClient(); + const health = useHealth(); + const repos = useRepositories(); + const [method, setMethod] = useState('github'); + const [jobId, setJobId] = useState(null); + const [error, setError] = useState(null); + const job = useJob(jobId).data; + + useEffect(() => { + if (!job || job.status === 'running') return; + void qc.invalidateQueries({ queryKey: ['repositories'] }); + if (job.status === 'completed' && job.repositoryId) navigate(`/w/${job.repositoryId}`); + else if (job.status === 'failed') { + setError(job.error ?? 'Indexing failed'); + setJobId(null); + } + }, [job, navigate, qc]); + + const start = async (fn: () => Promise<{ id: string }>) => { + setError(null); + try { + setJobId((await fn()).id); + } catch (e) { + setError((e as Error).message); + } + }; + const offline = health.error && (health.error as ApiError).status === 0; + + if (jobId) + return ( + +
+ +
+
+ ); + + return ( + +
+
+

+ Explore a repository +

+

The source is analysed on this machine. Nothing in the repository is installed or run.

+ + {offline ? ( +
+ The local engine is not running, so repositories cannot be imported. Start it with npm start in the VECTORA folder and reload this page. +
+ ) : null} + {error ? ( +
+ setError(null)}>Dismiss}> + {error} + +
+ ) : null} + +
+ {( + [ + ['github', 'GitHub repository'], + ['zip', 'ZIP archive'], + ['local', 'Local folder'], + ] as const + ).map(([id, label]) => ( + + ))} +
+
+ {method === 'github' ? : method === 'zip' ? : } +
+
+ + +
+
+ ); +} + +type Start = (fn: () => Promise<{ id: string }>) => Promise; + +function GitHubForm({ onStart }: { onStart: Start }) { + const [url, setUrl] = useState(''); + const [token, setToken] = useState(''); + const [remember, setRemember] = useState(false); + const [info, setInfo] = useState(null); + const [branch, setBranch] = useState(''); + const [subdir, setSubdir] = useState(''); + const [busy, setBusy] = useState(false); + const [error, setError] = useState(null); + const validate = async () => { + setBusy(true); + setError(null); + setInfo(null); + try { + const i = await api.validateGitHub(url, token); + setInfo(i); + setBranch(i.requested.branch && i.branches.includes(i.requested.branch) ? i.requested.branch : i.defaultBranch); + setSubdir(i.requested.subdirectory ?? ''); + } catch (e) { + setError((e as Error).message); + } finally { + setBusy(false); + } + }; + return ( +
{ + e.preventDefault(); + if (info) void onStart(() => api.importGitHub({ url, branch, subdirectory: subdir || undefined, token: token || undefined, rememberToken: remember })); + else void validate(); + }} + className="grid gap-5" + > +
+ + { + setUrl(e.target.value); + setInfo(null); + }} + required + autoComplete="off" + spellCheck={false} + /> +
+
+ Private repository +
+ + setToken(e.target.value)} /> +

A fine-grained token with read-only access to repository contents is enough. It is sent to api.github.com in a request header and never placed in a URL or a log.

+ +
+
+ {error ? {error} : null} + {info ? ( +
+
+

+ {info.fullName} {info.private ? private : null} +

+ {info.description ?

{info.description}

: null} +

+ about {formatBytes(info.sizeKb * 1024)} + {info.usingStoredCredential ? ', using the stored access token' : ''} +

+
+
+ + +
+
+ ) : null} +
+ +
+
+ ); +} + +function ZipForm({ onStart }: { onStart: Start }) { + const input = useRef(null); + const [inspection, setInspection] = useState(null); + const [root, setRoot] = useState(''); + const [busy, setBusy] = useState(false); + const [error, setError] = useState(null); + const [over, setOver] = useState(false); + const upload = async (file: File | undefined) => { + if (!file) return; + setError(null); + setInspection(null); + if (!/\.zip$/i.test(file.name)) return setError('Choose a file that ends in .zip.'); + setBusy(true); + try { + const r = await api.inspectZip(file); + setInspection(r); + setRoot(r.roots[0]?.path ?? ''); + } catch (e) { + setError((e as Error).message); + } finally { + setBusy(false); + } + }; + return ( +
+
{ + e.preventDefault(); + setOver(true); + }} + onDragLeave={() => setOver(false)} + onDrop={(e) => { + e.preventDefault(); + setOver(false); + void upload(e.dataTransfer.files[0]); + }} + className={cx('border border-dashed px-6 py-10 text-center transition-colors duration-200', over ? 'border-indigo bg-surface' : 'border-ash')} + > +

Drop a ZIP archive here

+

up to 512 MB. The archive is checked before anything is extracted.

+ void upload(e.target.files?.[0])} /> + +
+ {error ? {error} : null} + {inspection ? ( +
+
+

{inspection.fileName}

+

+ {inspection.files.toLocaleString()} files, {formatBytes(inspection.totalBytes)} uncompressed +

+
+ {inspection.rejected.length ? ( + + {inspection.rejected.length} entr{inspection.rejected.length === 1 ? 'y' : 'ies'} will be skipped as unsafe ({[...new Set(inspection.rejected.map((r) => r.reason))].join(', ')}). + + ) : null} +
+ Project root + {inspection.roots.map((r) => ( + + ))} +
+
+ Detected structure +
    + {inspection.tree.slice(0, 200).map((t) => ( +
  • + {t.path.split('/').pop()} + {t.directory ? '/' : ''} +
  • + ))} +
+
+
+ +
+
+ ) : null} +

Ignored folders such as node_modules, binary files, symbolic links and entries that point outside the archive are never extracted.

+
+ ); +} + +function LocalForm({ onStart }: { onStart: Start }) { + const [path, setPath] = useState(''); + const [browse, setBrowse] = useState(false); + return ( +
{ + e.preventDefault(); + if (path.trim()) void onStart(() => api.importLocal(path.trim())); + }} + > +
+ +
+ setPath(e.target.value)} autoComplete="off" spellCheck={false} /> + +
+

The folder is read in place by the local engine. .gitignore files and the ignore patterns from Settings are respected; nothing is copied or changed.

+
+
+ +
+ + + ); +} + +function FolderBrowser({ open, onOpenChange, initial, onPick }: { open: boolean; onOpenChange: (o: boolean) => void; initial: string; onPick: (p: string) => void }) { + const [dir, setDir] = useState(initial || undefined); + const list = useQuery({ queryKey: ['fs', dir], queryFn: () => api.listDir(dir), enabled: open, retry: false }); + return ( + +
+ {list.data?.roots.map((r) => ( + + ))} + {list.data?.parent ? ( + + ) : null} +
+

{list.data?.path ?? dir ?? ''}

+ {list.error ? ( +
+ setDir(undefined)}>Start over}> + {(list.error as Error).message} + +
+ ) : null} +
    + {list.data?.entries.length === 0 ?
  • No folders here.
  • : null} + {list.data?.entries.map((e) => ( +
  • + +
  • + ))} +
+
+ + +
+
+ ); +} diff --git a/apps/web/src/pages/Landing.tsx b/apps/web/src/pages/Landing.tsx new file mode 100644 index 0000000..7064ec4 --- /dev/null +++ b/apps/web/src/pages/Landing.tsx @@ -0,0 +1,174 @@ +import { Link } from 'react-router'; +import { AtlasIllustration, SitePage } from '@/components/Site'; + +const STEPS = [ + { mark: '一', title: 'Import', body: 'Point VECTORA at a GitHub repository, a ZIP archive or a folder on your machine. Ignore rules are respected and nothing in the repository is ever run.' }, + { mark: '二', title: 'Index', body: 'Source files are parsed into syntax trees. Classes, functions, imports, routes and data models are extracted with the file and line they came from.' }, + { mark: '三', title: 'Resolve', body: 'References are tied to definitions only when there is scope evidence for it. What cannot be resolved is reported, not guessed.' }, + { mark: '四', title: 'Explore', body: 'The result is one knowledge graph, shown three ways. Select a node anywhere and the other views follow.' }, +]; + +const VIEWS = [ + { name: 'Graph Explorer', dimension: 'Two dimensions', body: 'Pan and zoom through files and symbols. Selecting a node highlights what it depends on and what depends on it, and dims the rest.' }, + { name: '3D Atlas', dimension: 'Three dimensions', body: 'The repository at the centre, subsystems as regions around it, files and symbols inside their regions. Fly to a node, unfold it, return to the whole.' }, + { name: 'Mind Map', dimension: 'Hierarchy', body: 'Subsystems, folders, files and symbols as a tree you can expand, rearrange and export. Concepts sit beside the structure they were found in.' }, +]; + +const LANGUAGES: [string, string][] = [ + ['TypeScript and JavaScript', 'type-checked symbol resolution'], + ['Python', 'syntax-tree analysis'], + ['Java, Go, Rust, C, C++, C#', 'syntax-tree analysis'], +]; + +export function Landing() { + return ( + + {/* Hero — text held to a narrow left column, the drawing bleeding off the right edge */} +
+ +
+

+ Understand what connects. +

+

Explore the hidden architecture of software. Transform repositories into structured, interactive knowledge maps.

+
+ + Explore a repository + + + Learn about VECTORA + +
+
+
+ +
Illustration of the 3D Atlas: a repository, its subsystems and their contents.
+
+
+ +
+ + {/* Product visualisation */} +
+

+ A repository is a set of relationships. Reading files one by one hides them. +

+
+

VECTORA reads the source, records which function calls which, which class extends which, which route leads to which handler, and keeps the line of code that proves it.

+

Every relationship in the graph can be opened to show its evidence. Groupings that are interpretations, such as concepts, are marked as derived and drawn differently from verified structure.

+
+
+ + {/* How it works — a real sequence, so it is numbered */} +
+
+

+ How it works +

+
    + {STEPS.map((s, i) => ( +
  1. + + Step {i + 1}: +

    {s.title}

    +

    {s.body}

    +
  2. + ))} +
+
+
+ + {/* Exploration capabilities */} +
+
+

+ One graph, three ways to read it +

+
    + {VIEWS.map((v) => ( +
  • +

    {v.dimension}

    +
    +

    {v.name}

    +

    {v.body}

    +
    +
  • + ))} +
  • + Around them: an inspector with the original source, search across files, symbols and documentation, a dependency explorer with circular imports and unresolved references, and questions answered with file and line citations. +
  • +
+
+
+ + {/* Supported source formats */} +
+
+
+

+ Supported sources +

+
+ {[ + ['GitHub repository', 'Public repositories by URL. Private repositories with an access token you provide; it is stored encrypted on your machine.'], + ['ZIP archive', 'Checked before extraction. Nested project folders are detected and you choose the root.'], + ['Local folder', 'Read in place through the local engine. .gitignore and your own exclusion rules apply.'], + ].map(([k, v]) => ( +
+
{k}
+
{v}
+
+ ))} +
+
+
+

Languages analysed

+
    + {LANGUAGES.map(([k, v]) => ( +
  • +

    {k}

    +

    {v}

    +
  • + ))} +
+

Files in other languages are listed and searchable but not analysed at symbol level. Language coverage is shown for every repository.

+
+
+
+ + {/* Privacy */} +
+
+

+ Your code stays on your machine +

+
    +
  • Indexing, the graph database and search all run in a local engine. No source code is uploaded.
  • +
  • Repository dependencies are never installed and repository scripts are never executed.
  • +
  • The only network requests are the ones you start: downloading a repository from GitHub, and an optional narrative service that is off by default.
  • +
  • Exports leave out source text unless you ask for it, and everything can be deleted from Settings.
  • +
+
+
+ + {/* About */} +
+

+ About +

+
+

+ VECTORA is a codebase intelligence platform that transforms software repositories into structured, interactive knowledge maps. It reveals how components, modules, dependencies and concepts connect, giving developers a new way to understand complex software systems. +

+

+ Philosophy, supported languages, credits and licence +

+
+
+
+ ); +} diff --git a/apps/web/src/styles.css b/apps/web/src/styles.css new file mode 100644 index 0000000..09ef722 --- /dev/null +++ b/apps/web/src/styles.css @@ -0,0 +1,524 @@ +/* Latin subsets only: the three faces are bundled, nothing is fetched from a font service. + The few Japanese glyphs used as marks fall back to the system mincho / gothic. */ +@import '@fontsource/zen-kaku-gothic-new/latin-400.css'; +@import '@fontsource/zen-kaku-gothic-new/latin-500.css'; +@import '@fontsource/zen-kaku-gothic-new/latin-700.css'; +@import '@fontsource/zen-kaku-gothic-new/latin-ext-400.css'; +@import '@fontsource/shippori-mincho/latin-400.css'; +@import '@fontsource/shippori-mincho/latin-600.css'; +@import '@fontsource/shippori-mincho/latin-ext-400.css'; +@import '@fontsource/ibm-plex-mono/latin-400.css'; +@import '@fontsource/ibm-plex-mono/latin-500.css'; +@import 'tailwindcss'; + +/* --------------------------------------------------------------------------- + Tokens. Values mirror src/lib/tokens.ts (checked by a unit test). + --------------------------------------------------------------------------- */ +:root { + --canvas: #f8f7f2; + --surface: #f3f1ea; + --elevated: #fbfaf6; + --text: #20211f; + --text-secondary: #5f5d55; + --text-muted: #8c897f; + --line: #dcd8ce; + --indigo: #34445c; + --clay: #a18c72; + --ash: #b8b3a7; + --success: #55704f; + --warning: #8f6b25; + --error: #964436; + --selection: #34445c; + --relation-active: #34445c; + --relation-unverified: #a18c72; + --on-accent: #f8f7f2; + --duration-ui: 200ms; + --duration-panel: 380ms; + --ease: cubic-bezier(0.2, 0, 0, 1); + color-scheme: light; +} + +:root[data-theme='dark'] { + --canvas: #171816; + --surface: #20211f; + --elevated: #272824; + --text: #eceae2; + --text-secondary: #a7a499; + --text-muted: #77766d; + --line: #373832; + --indigo: #8292ad; + --clay: #b39a7a; + --ash: #5c5b54; + --success: #8fae8a; + --warning: #c9a566; + --error: #d08c7c; + --selection: #8292ad; + --relation-active: #8292ad; + --relation-unverified: #b39a7a; + --on-accent: #171816; + color-scheme: dark; +} + +:root[data-motion='reduced'] { + --duration-ui: 0ms; + --duration-panel: 0ms; +} + +@theme inline { + --color-canvas: var(--canvas); + --color-surface: var(--surface); + --color-elevated: var(--elevated); + --color-ink: var(--text); + --color-ink-2: var(--text-secondary); + --color-ink-3: var(--text-muted); + --color-line: var(--line); + --color-indigo: var(--indigo); + --color-clay: var(--clay); + --color-ash: var(--ash); + --color-success: var(--success); + --color-warning: var(--warning); + --color-error: var(--error); + --color-on-accent: var(--on-accent); + --font-sans: 'Zen Kaku Gothic New', 'Hiragino Kaku Gothic ProN', 'Yu Gothic', system-ui, sans-serif; + --font-serif: 'Shippori Mincho', 'Hiragino Mincho ProN', 'Yu Mincho', serif; + --font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace; + /* Type scale */ + --text-meta: 0.75rem; + --text-label: 0.8125rem; + --text-body: 0.9375rem; + --text-section: 1.375rem; + --text-page: clamp(1.875rem, 1.4rem + 1.6vw, 2.5rem); + --text-display: clamp(2.75rem, 1.6rem + 4.2vw, 4rem); + --radius-sm: 2px; + --radius-md: 3px; +} + +@layer base { + html { + background: var(--canvas); + color: var(--text); + font-family: var(--font-sans); + font-size: 16px; + line-height: 1.6; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + } + body { + margin: 0; + min-height: 100dvh; + font-size: var(--text-body); + font-feature-settings: 'palt' 1; + } + #root { + min-height: 100dvh; + } + h1, + h2, + h3, + h4 { + font-weight: 500; + line-height: 1.25; + margin: 0; + text-wrap: balance; + } + p { + margin: 0; + text-wrap: pretty; + } + a { + color: inherit; + text-decoration-color: var(--line); + text-underline-offset: 0.22em; + text-decoration-thickness: 1px; + transition: text-decoration-color var(--duration-ui) var(--ease), color var(--duration-ui) var(--ease); + } + a:hover { + text-decoration-color: currentColor; + } + code, + kbd, + pre, + samp { + font-family: var(--font-mono); + font-size: 0.86em; + } + ::selection { + background: color-mix(in srgb, var(--indigo) 24%, transparent); + } + :focus-visible { + outline: 2px solid var(--indigo); + outline-offset: 2px; + } + * { + scrollbar-width: thin; + scrollbar-color: var(--line) transparent; + } + @media (prefers-reduced-motion: reduce) { + :root:not([data-motion='full']) { + --duration-ui: 0ms; + --duration-panel: 0ms; + } + :root:not([data-motion='full']) *, + :root:not([data-motion='full']) *::before, + :root:not([data-motion='full']) *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + scroll-behavior: auto !important; + } + } + :root[data-motion='reduced'] *, + :root[data-motion='reduced'] *::before, + :root[data-motion='reduced'] *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0ms !important; + } +} + +@layer components { + .font-editorial { + font-family: var(--font-serif); + font-weight: 400; + letter-spacing: 0.01em; + } + .meta { + font-family: var(--font-mono); + font-size: var(--text-meta); + color: var(--text-muted); + letter-spacing: 0; + } + .label { + font-size: var(--text-label); + color: var(--text-secondary); + } + .rule { + border: 0; + border-top: 1px solid var(--line); + margin: 0; + } + /* Vertical brand spine — Japanese vertical setting used as the signature element. */ + .spine { + writing-mode: vertical-rl; + text-orientation: mixed; + letter-spacing: 0.42em; + font-size: var(--text-meta); + color: var(--text-muted); + } + .btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + min-height: 36px; + padding: 0 16px; + border: 1px solid var(--line); + border-radius: var(--radius-sm); + background: transparent; + color: var(--text); + font: inherit; + font-size: var(--text-label); + font-weight: 500; + line-height: 1; + cursor: pointer; + text-decoration: none; + white-space: nowrap; + transition: + background var(--duration-ui) var(--ease), + border-color var(--duration-ui) var(--ease), + color var(--duration-ui) var(--ease); + } + .btn:hover:not(:disabled) { + border-color: var(--text-muted); + background: color-mix(in srgb, var(--text) 4%, transparent); + } + .btn:disabled { + opacity: 0.5; + cursor: not-allowed; + } + .btn-primary { + background: var(--text); + border-color: var(--text); + color: var(--canvas); + } + .btn-primary:hover:not(:disabled) { + background: var(--indigo); + border-color: var(--indigo); + color: var(--on-accent); + } + .btn-quiet { + border-color: transparent; + padding: 0 8px; + color: var(--text-secondary); + } + .btn-sm { + min-height: 28px; + padding: 0 10px; + font-size: var(--text-meta); + } + .btn-icon { + min-height: 32px; + width: 32px; + padding: 0; + } + .btn[aria-pressed='true'], + .btn[data-active='true'] { + border-color: var(--text); + background: color-mix(in srgb, var(--text) 6%, transparent); + } + .field { + width: 100%; + min-height: 36px; + padding: 6px 12px; + border: 1px solid var(--line); + border-radius: var(--radius-sm); + background: var(--elevated); + color: var(--text); + font: inherit; + font-size: var(--text-label); + transition: border-color var(--duration-ui) var(--ease); + } + .field::placeholder { + color: var(--text-muted); + } + .field:hover { + border-color: var(--ash); + } + .field:focus-visible { + outline: none; + border-color: var(--indigo); + box-shadow: 0 0 0 1px var(--indigo); + } + textarea.field { + font-family: var(--font-mono); + font-size: var(--text-meta); + line-height: 1.7; + resize: vertical; + } + .panel { + background: var(--surface); + border: 1px solid var(--line); + } + .tag { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 1px 8px; + border: 1px solid var(--line); + border-radius: var(--radius-sm); + font-size: var(--text-meta); + color: var(--text-secondary); + line-height: 1.7; + white-space: nowrap; + } + .tag-derived { + border-style: dashed; + border-color: var(--relation-unverified); + color: var(--text-secondary); + } + .link-row { + display: flex; + width: 100%; + align-items: baseline; + gap: 12px; + padding: 8px 0; + border: 0; + border-bottom: 1px solid var(--line); + background: none; + color: inherit; + font: inherit; + text-align: left; + cursor: pointer; + text-decoration: none; + transition: padding-left var(--duration-ui) var(--ease), color var(--duration-ui) var(--ease); + } + .link-row:hover { + padding-left: 6px; + color: var(--indigo); + } + .prose-doc { + max-width: 68ch; + line-height: 1.75; + } + .prose-doc h1, + .prose-doc h2, + .prose-doc h3 { + font-family: var(--font-serif); + margin: 1.8em 0 0.6em; + } + .prose-doc h1 { + font-size: 1.75rem; + } + .prose-doc h2 { + font-size: 1.3rem; + } + .prose-doc h3 { + font-size: 1.1rem; + } + .prose-doc p, + .prose-doc ul, + .prose-doc ol, + .prose-doc pre, + .prose-doc table, + .prose-doc blockquote { + margin: 0 0 1em; + } + .prose-doc ul, + .prose-doc ol { + padding-left: 1.3em; + } + .prose-doc pre { + padding: 12px 16px; + background: var(--surface); + border: 1px solid var(--line); + overflow-x: auto; + font-size: var(--text-meta); + line-height: 1.7; + } + .prose-doc :not(pre) > code { + padding: 0.1em 0.35em; + background: var(--surface); + border: 1px solid var(--line); + } + .prose-doc blockquote { + padding-left: 16px; + border-left: 2px solid var(--clay); + color: var(--text-secondary); + } + .prose-doc table { + border-collapse: collapse; + font-size: var(--text-label); + display: block; + overflow-x: auto; + } + .prose-doc th, + .prose-doc td { + padding: 6px 12px; + border-bottom: 1px solid var(--line); + text-align: left; + } + .prose-doc img { + max-width: 100%; + } + .data-table { + width: 100%; + border-collapse: collapse; + font-size: var(--text-label); + } + .data-table th { + font-weight: 500; + color: var(--text-muted); + text-align: left; + padding: 6px 12px 6px 0; + border-bottom: 1px solid var(--line); + white-space: nowrap; + } + .data-table td { + padding: 7px 12px 7px 0; + border-bottom: 1px solid var(--line); + vertical-align: baseline; + } + .data-table .num { + text-align: right; + font-family: var(--font-mono); + font-size: var(--text-meta); + font-variant-numeric: tabular-nums; + } + .skip-link { + position: absolute; + left: 8px; + top: -48px; + z-index: 100; + padding: 8px 12px; + background: var(--text); + color: var(--canvas); + } + .skip-link:focus { + top: 8px; + } +} + +/* Overlays */ +@keyframes overlay-in { + from { + opacity: 0; + } +} +@keyframes panel-in { + from { + opacity: 0; + transform: translateY(6px); + } +} +.overlay { + position: fixed; + inset: 0; + z-index: 50; + background: color-mix(in srgb, var(--text) 22%, transparent); + animation: overlay-in var(--duration-ui) var(--ease); +} +:root[data-theme='dark'] .overlay { + background: rgba(0, 0, 0, 0.55); +} +.dialog { + position: fixed; + z-index: 51; + left: 50%; + top: 14vh; + width: min(640px, calc(100vw - 32px)); + max-height: 72vh; + transform: translateX(-50%); + display: flex; + flex-direction: column; + background: var(--elevated); + border: 1px solid var(--line); + box-shadow: 0 24px 60px -30px rgba(0, 0, 0, 0.45); + animation: panel-in var(--duration-panel) var(--ease); +} + +/* Library overrides: React Flow and CodeMirror follow the tokens. */ +.react-flow { + --xy-background-color: transparent; + --xy-edge-stroke: var(--ash); + --xy-edge-stroke-selected: var(--indigo); + --xy-controls-button-background-color: var(--elevated); + --xy-controls-button-background-color-hover: var(--surface); + --xy-controls-button-color: var(--text); + --xy-controls-button-border-color: var(--line); + --xy-minimap-background-color: var(--surface); + --xy-minimap-mask-background-color: color-mix(in srgb, var(--canvas) 70%, transparent); + --xy-attribution-background-color: transparent; + font-family: var(--font-sans); +} +.react-flow__controls { + box-shadow: none; + border: 1px solid var(--line); +} +.react-flow__attribution a { + color: var(--text-muted); +} +.cm-editor { + font-size: 12.5px; + background: transparent; +} +.cm-editor .cm-scroller { + font-family: var(--font-mono); + line-height: 1.65; +} +.cm-editor .cm-gutters { + background: transparent; + color: var(--text-muted); + border-right: 1px solid var(--line); +} +.cm-editor.cm-focused { + outline: none; +} +.cm-editor .cm-activeLine, +.cm-editor .cm-activeLineGutter { + background: transparent; +} +.cm-editor .cm-vectora-range { + background: color-mix(in srgb, var(--indigo) 9%, transparent); +} +.sigma-container canvas { + outline: none; +} diff --git a/apps/web/src/theme-init.ts b/apps/web/src/theme-init.ts new file mode 100644 index 0000000..0590b64 --- /dev/null +++ b/apps/web/src/theme-init.ts @@ -0,0 +1,4 @@ +// Applies the stored theme before the application renders, so there is no flash of the wrong theme. +const stored = localStorage.getItem('vectora-theme'); +const dark = stored === 'dark' || (stored !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches); +document.documentElement.dataset.theme = dark ? 'dark' : 'light'; diff --git a/apps/web/src/workers/layout3d.worker.ts b/apps/web/src/workers/layout3d.worker.ts new file mode 100644 index 0000000..8cd02a4 --- /dev/null +++ b/apps/web/src/workers/layout3d.worker.ts @@ -0,0 +1,20 @@ +/// +import { type LayoutEdge, type LayoutNode, layout3d } from '@vectora/graph-layout'; + +export interface Layout3DRequest { + requestId: number; + nodes: LayoutNode[]; + edges: LayoutEdge[]; + quality: number; +} +export interface Layout3DResponse { + requestId: number; + positions: Float32Array; + radius: number; +} + +self.onmessage = (e: MessageEvent) => { + const { requestId, nodes, edges, quality } = e.data; + const result = layout3d(nodes, edges, { quality }); + (self as unknown as Worker).postMessage({ requestId, positions: result.positions, radius: result.radius } satisfies Layout3DResponse, [result.positions.buffer]); +}; diff --git a/apps/web/src/workspace/Atlas.tsx b/apps/web/src/workspace/Atlas.tsx new file mode 100644 index 0000000..a24747c --- /dev/null +++ b/apps/web/src/workspace/Atlas.tsx @@ -0,0 +1,676 @@ +import { OrbitControls } from '@react-three/drei'; +import { Canvas, type ThreeEvent, useFrame, useThree } from '@react-three/fiber'; +import { ChevronRight, Globe, Image as ImageIcon, RotateCcw } from 'lucide-react'; +import { type MutableRefObject, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; +import * as THREE from 'three'; +import type { OrbitControls as OrbitControlsImpl } from 'three-stdlib'; +import type { LayoutNode, LayoutRole } from '@vectora/graph-layout'; +import { type GraphEdge, type GraphNode, NODE_TYPE_LABELS, isSymbolType } from '@vectora/graph-schema'; +import { ViewToolbar } from '@/components/ViewControls'; +import { Loading } from '@/components/ui'; +import { downloadUrl } from '@/lib/api'; +import { fileIdOf, neighbourhood } from '@/lib/graphView'; +import { useWorkspace } from '@/lib/store'; +import { FAMILY_GLYPH, NODE_FAMILY, NODE_SIZE, type NodeFamily, type Palette, mix, nodeColor } from '@/lib/tokens'; +import type { Layout3DRequest, Layout3DResponse } from '@/workers/layout3d.worker'; +import { useWs } from './context'; + +type Quality = 'low' | 'balanced' | 'high'; + +interface AtlasApi { + reset: () => void; + focusOn: (id: string) => void; + capture: () => string | null; +} + +const roleOf = (n: GraphNode): LayoutRole => { + switch (n.type) { + case 'Repository': + return 'repository'; + case 'Subsystem': + return 'subsystem'; + case 'Concept': + return 'concept'; + case 'Package': + return 'package'; + case 'Directory': + case 'Module': + return 'container'; + case 'File': + case 'Configuration': + return 'file'; + default: + return 'symbol'; + } +}; + +function webglAvailable(): boolean { + try { + const c = document.createElement('canvas'); + return !!(c.getContext('webgl2') ?? c.getContext('webgl')); + } catch { + return false; + } +} + +/** Runs the 3D layout in a Web Worker and returns positions aligned with `nodes`. */ +function useLayout3d(nodes: GraphNode[], edges: GraphEdge[], parentOf: (n: GraphNode) => string | null, quality: Quality) { + const [result, setResult] = useState<{ positions: Float32Array; radius: number; ids: string[] } | null>(null); + const workerRef = useRef(null); + const requestId = useRef(0); + useEffect(() => { + const worker = new Worker(new URL('../workers/layout3d.worker.ts', import.meta.url), { type: 'module' }); + workerRef.current = worker; + return () => worker.terminate(); + }, []); + useEffect(() => { + const worker = workerRef.current; + if (!worker) return; + const id = ++requestId.current; + const ids = nodes.map((n) => n.id); + const layoutNodes: LayoutNode[] = nodes.map((n) => ({ id: n.id, role: roleOf(n), subsystem: (n.metadata.subsystem as string | undefined) ?? null, parent: parentOf(n) })); + const layoutEdges = edges.filter((e) => e.type === 'IMPORTS' || e.type === 'CALLS' || e.type === 'USES' || e.type === 'EXTENDS').map((e) => ({ source: e.source, target: e.target })); + worker.onmessage = (e: MessageEvent) => { + if (e.data.requestId === requestId.current) setResult({ positions: e.data.positions, radius: e.data.radius, ids }); + }; + worker.postMessage({ requestId: id, nodes: layoutNodes, edges: layoutEdges, quality: quality === 'low' ? 0.2 : quality === 'high' ? 1 : 0.6 } satisfies Layout3DRequest); + }, [nodes, edges, parentOf, quality]); + return result; +} + +const FAMILIES: NodeFamily[] = ['structure', 'file', 'type', 'callable', 'data', 'endpoint', 'concept', 'external', 'value']; + +function FamilyGeometry({ family, quality }: { family: NodeFamily; quality: Quality }) { + const d = quality === 'low' ? 0 : 1; + switch (family) { + case 'structure': + return ; + case 'file': + return ; + case 'type': + return ; + case 'data': + return ; + case 'endpoint': + return ; + case 'concept': + return ; + case 'external': + return ; + default: + return ; + } +} + +interface SceneProps { + nodes: GraphNode[]; + edges: GraphEdge[]; + positions: Float32Array; + radius: number; + palette: Palette; + quality: Quality; + labelBudget: number; + reducedMotion: boolean; + focusBehavior: 'neighbourhood' | 'node' | 'none'; + apiRef: MutableRefObject; + onExpand: (id: string) => void; + onLabels: (items: LabelItem[]) => void; + labelEls: MutableRefObject>; +} + +interface LabelItem { + id: string; + text: string; + glyph: string; + major: boolean; + root: boolean; + on: boolean; + dim: boolean; + detail: string | null; +} + +function AtlasScene({ nodes, edges, positions, radius, palette, quality, labelBudget, reducedMotion, focusBehavior, apiRef, onExpand, onLabels, labelEls }: SceneProps) { + const { camera, invalidate, gl, scene } = useThree(); + const controls = useThree((s) => s.controls) as OrbitControlsImpl | null; + const selectedIds = useWorkspace((s) => s.selectedIds); + const primaryId = useWorkspace((s) => s.primaryId); + const hoverId = useWorkspace((s) => s.hoverId); + const highlight = useWorkspace((s) => s.highlight); + const revealTick = useWorkspace((s) => s.revealTick); + const [far, setFar] = useState(false); + const [nearLabels, setNearLabels] = useState([]); + + const indexOf = useMemo(() => new Map(nodes.map((n, i) => [n.id, i])), [nodes]); + const pos = useCallback((i: number) => new THREE.Vector3(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]), [positions]); + const byFamily = useMemo(() => { + const m = new Map(); + nodes.forEach((n, i) => { + const f = NODE_FAMILY[n.type]; + (m.get(f) ?? m.set(f, []).get(f)!).push(i); + }); + return m; + }, [nodes]); + + // ---- which nodes and edges are emphasised ------------------------------ + const active = useMemo(() => { + const centre = hoverId ?? primaryId; + if (centre && indexOf.has(centre)) { + const nb = neighbourhood(centre, edges); + for (const id of selectedIds) nb.nodes.add(id); + return nb; + } + if (highlight) return { nodes: new Set(highlight.nodeIds), edges: new Set(highlight.edgeIds) }; + return null; + }, [hoverId, primaryId, selectedIds, highlight, edges, indexOf]); + + // ---- instanced nodes ---------------------------------------------------- + const meshes = useRef(new Map()); + useLayoutEffect(() => { + const m4 = new THREE.Matrix4(); + const q = new THREE.Quaternion(); + const color = new THREE.Color(); + const selected = new Set(selectedIds); + for (const [family, list] of byFamily) { + const mesh = meshes.current.get(family); + if (!mesh) continue; + list.forEach((ni, k) => { + const n = nodes[ni]!; + const emphasised = selected.has(n.id) || n.id === hoverId; + const s = NODE_SIZE[n.type] * 0.42 * (emphasised ? 1.5 : 1); + m4.compose(pos(ni), q, new THREE.Vector3(s, s, s)); + mesh.setMatrixAt(k, m4); + const base = emphasised ? palette.selection : nodeColor(n.type, palette); + color.set(active && !active.nodes.has(n.id) && !emphasised ? mix(base, palette.canvas, 0.72) : base); + mesh.setColorAt(k, color); + }); + mesh.count = list.length; + mesh.instanceMatrix.needsUpdate = true; + if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true; + mesh.computeBoundingSphere(); + } + invalidate(); + }, [byFamily, nodes, pos, palette, selectedIds, hoverId, active, invalidate]); + + // ---- edges: two buffered line sets (verified solid, derived dashed) ------ + const edgeSets = useMemo(() => { + const build = (list: GraphEdge[]) => { + // Cross-file relationships first, so symbol-level detail can be cut with a draw range when far away. + const coarse: GraphEdge[] = []; + const fine: GraphEdge[] = []; + for (const e of list) { + const a = nodes[indexOf.get(e.source)!]!; + const b = nodes[indexOf.get(e.target)!]!; + (isSymbolType(a.type) && isSymbolType(b.type) && a.filePath === b.filePath) || e.type === 'CONTAINS' ? fine.push(e) : coarse.push(e); + } + const ordered = [...coarse, ...fine]; + const geometry = new THREE.BufferGeometry(); + const p = new Float32Array(ordered.length * 6); + ordered.forEach((e, k) => { + const a = indexOf.get(e.source)! * 3; + const b = indexOf.get(e.target)! * 3; + p.set([positions[a]!, positions[a + 1]!, positions[a + 2]!, positions[b]!, positions[b + 1]!, positions[b + 2]!], k * 6); + }); + geometry.setAttribute('position', new THREE.BufferAttribute(p, 3)); + geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(ordered.length * 6), 3)); + return { geometry, ordered, coarseCount: coarse.length }; + }; + const usable = edges.filter((e) => indexOf.has(e.source) && indexOf.has(e.target)); + return { verified: build(usable.filter((e) => e.verified)), derived: build(usable.filter((e) => !e.verified)) }; + }, [edges, nodes, indexOf, positions]); + useEffect(() => () => { + edgeSets.verified.geometry.dispose(); + edgeSets.derived.geometry.dispose(); + }, [edgeSets]); + const derivedLine = useRef(null); + useLayoutEffect(() => { + const c = new THREE.Color(); + for (const [set, baseHex] of [[edgeSets.verified, palette.textMuted], [edgeSets.derived, palette.relationUnverified]] as const) { + const attr = set.geometry.getAttribute('color') as THREE.BufferAttribute; + set.ordered.forEach((e, k) => { + const on = active?.edges.has(e.id); + c.set(on ? (e.verified ? palette.relationActive : palette.relationUnverified) : mix(baseHex, palette.canvas, active ? 0.88 : e.type === 'CONTAINS' || !e.verified ? 0.72 : 0.5)); + attr.setXYZ(k * 2, c.r, c.g, c.b); + attr.setXYZ(k * 2 + 1, c.r, c.g, c.b); + }); + attr.needsUpdate = true; + // Level of detail: from far away only cross-file relationships are drawn. + set.geometry.setDrawRange(0, (far && !active ? set.coarseCount : set.ordered.length) * 2); + } + derivedLine.current?.computeLineDistances(); + invalidate(); + }, [edgeSets, palette, active, far, invalidate]); + + // ---- camera transitions ------------------------------------------------- + const anim = useRef<{ fromP: THREE.Vector3; fromT: THREE.Vector3; toP: THREE.Vector3; toT: THREE.Vector3; start: number; duration: number } | null>(null); + const flyTo = useCallback( + (toP: THREE.Vector3, toT: THREE.Vector3) => { + const fromT = controls ? controls.target.clone() : new THREE.Vector3(); + anim.current = { fromP: camera.position.clone(), fromT, toP, toT, start: performance.now(), duration: reducedMotion ? 0 : 820 }; + invalidate(); + }, + [camera, controls, invalidate, reducedMotion], + ); + useFrame(() => { + const a = anim.current; + if (!a) return; + const t = a.duration === 0 ? 1 : Math.min(1, (performance.now() - a.start) / a.duration); + const k = t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2; + camera.position.lerpVectors(a.fromP, a.toP, k); + if (controls) { + controls.target.lerpVectors(a.fromT, a.toT, k); + controls.update(); + } else camera.lookAt(a.toT); + if (t >= 1) anim.current = null; + else invalidate(); + }); + const home = useCallback(() => flyTo(new THREE.Vector3(0, radius * 1.25, radius * 3.3), new THREE.Vector3(0, 0, 0)), [flyTo, radius]); + const focusOn = useCallback( + (id: string) => { + const i = indexOf.get(id); + if (i === undefined) return; + const n = nodes[i]!; + const target = pos(i); + const dist = n.type === 'Repository' ? radius * 2.6 : n.type === 'Subsystem' ? radius * 1.3 : n.type === 'Concept' || n.type === 'Package' ? radius * 0.7 : isSymbolType(n.type) ? 13 : 26; + // Look at the node from outside the structure, keeping the current side when the node is central. + const dir = target.lengthSq() > 4 ? target.clone().normalize() : camera.position.clone().sub(target).normalize(); + dir.y += 0.25; + flyTo(target.clone().add(dir.normalize().multiplyScalar(dist)), target); + }, + [indexOf, nodes, pos, radius, camera, flyTo], + ); + useEffect(() => { + apiRef.current = { + reset: home, + focusOn, + capture: () => { + gl.render(scene, camera); + return gl.domElement.toDataURL('image/png'); + }, + }; + return () => { + apiRef.current = null; + }; + }, [apiRef, home, focusOn, gl, scene, camera]); + // Frame the whole structure whenever a new layout arrives. + const framed = useRef(null); + useEffect(() => { + // Runs again once the controls exist, so the first frame is drawn from the home position. + const key = `${radius}:${controls ? 1 : 0}`; + if (framed.current === key) return; + framed.current = key; + camera.position.set(0, radius * 1.25, radius * 3.3); + controls?.target.set(0, 0, 0); + controls?.update(); + invalidate(); + }, [radius, camera, controls, invalidate]); + // With on-demand rendering nothing is drawn until a frame is requested: ask for one whenever the + // scene content is (re)created, and once more after the browser has laid the canvas out. + useEffect(() => { + invalidate(); + const t = setTimeout(() => invalidate(), 150); + return () => clearTimeout(t); + }, [controls, positions, invalidate]); + useEffect(() => { + if (revealTick === 0 || focusBehavior === 'none') return; + const s = useWorkspace.getState(); + const id = s.primaryId ?? s.focusId; + if (id) focusOn(id); + else home(); + }, [revealTick]); // eslint-disable-line react-hooks/exhaustive-deps + + // ---- level of detail and label culling, recomputed when the camera rests -- + const updateDetail = useCallback(() => { + const d = camera.position.length(); + setFar(d > radius * 2.1 && edges.length > 600); + if (labelBudget === 0) return setNearLabels([]); + const scored: [number, string][] = []; + const v = new THREE.Vector3(); + const frustum = new THREE.Frustum().setFromProjectionMatrix(new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)); + for (let i = 0; i < nodes.length; i++) { + const n = nodes[i]!; + if (n.type === 'Repository' || n.type === 'Subsystem' || n.type === 'Concept') continue; + v.set(positions[i * 3]!, positions[i * 3 + 1]!, positions[i * 3 + 2]!); + if (!frustum.containsPoint(v)) continue; + // Larger nodes earn a label from further away. + scored.push([v.distanceTo(camera.position) / (NODE_SIZE[n.type] + 1), n.id]); + } + scored.sort((a, b) => a[0] - b[0]); + const limit = (isSymbol: boolean) => (isSymbol ? 18 : 60); + setNearLabels(scored.filter(([s, id]) => s * (NODE_SIZE[nodes[indexOf.get(id)!]!.type] + 1) < limit(isSymbolType(nodes[indexOf.get(id)!]!.type)) * 1.4).slice(0, labelBudget).map(([, id]) => id)); + }, [camera, radius, edges.length, labelBudget, nodes, positions, indexOf]); + useEffect(() => { + const t = setTimeout(updateDetail, 80); + return () => clearTimeout(t); + }, [updateDetail]); + + // ---- pointer interaction ------------------------------------------------ + const idAt = (family: NodeFamily, instanceId: number | undefined) => (instanceId === undefined ? null : (nodes[byFamily.get(family)?.[instanceId] ?? -1]?.id ?? null)); + const handlers = (family: NodeFamily) => ({ + onClick: (e: ThreeEvent) => { + e.stopPropagation(); + const id = idAt(family, e.instanceId); + if (!id) return; + const additive = e.nativeEvent.ctrlKey || e.nativeEvent.metaKey || e.nativeEvent.shiftKey; + useWorkspace.getState().select(id, { additive }); + if (!additive && focusBehavior !== 'none') focusOn(id); + }, + onDoubleClick: (e: ThreeEvent) => { + e.stopPropagation(); + const id = idAt(family, e.instanceId); + if (id) onExpand(id); + }, + ...(nodes.length <= 20000 + ? { + onPointerMove: (e: ThreeEvent) => { + e.stopPropagation(); + useWorkspace.getState().setHover(idAt(family, e.instanceId)); + gl.domElement.style.cursor = 'pointer'; + }, + onPointerOut: () => { + useWorkspace.getState().setHover(null); + gl.domElement.style.cursor = ''; + }, + } + : {}), + }); + + // ---- labels ------------------------------------------------------------- + const labels = useMemo(() => { + const ids = new Set(); + for (const n of nodes) if (n.type === 'Repository' || n.type === 'Subsystem' || n.type === 'Concept') ids.add(n.id); + for (const id of selectedIds) ids.add(id); + if (hoverId) ids.add(hoverId); + if (active) [...active.nodes].slice(0, 28).forEach((id) => ids.add(id)); + for (const id of nearLabels) ids.add(id); + return [...ids].filter((id) => indexOf.has(id)); + }, [nodes, selectedIds, hoverId, active, nearLabels, indexOf]); + + // Labels are plain DOM elements in an overlay owned by the parent. The parent renders them; + // this scene only moves them, once per rendered frame, by projecting their node to the screen. + const labelItems = useMemo( + () => + labels.map((id) => { + const n = nodes[indexOf.get(id)!]!; + const major = n.type === 'Repository' || n.type === 'Subsystem' || n.type === 'Concept'; + const on = id === hoverId || selectedIds.includes(id); + return { id, text: n.name, glyph: FAMILY_GLYPH[NODE_FAMILY[n.type]], major, root: n.type === 'Repository', on, dim: !!active && !active.nodes.has(id) && !on, detail: id === hoverId && !major ? NODE_TYPE_LABELS[n.type] : null }; + }), + [labels, nodes, indexOf, hoverId, selectedIds, active], + ); + useEffect(() => { + onLabels(labelItems); + invalidate(); + const t = setTimeout(() => invalidate(), 40); + return () => clearTimeout(t); + }, [labelItems, onLabels, invalidate]); + const projected = useMemo(() => new THREE.Vector3(), []); + useFrame(({ size }) => { + for (const item of labelItems) { + const el = labelEls.current.get(item.id); + const i = indexOf.get(item.id); + if (!el || i === undefined) continue; + projected.set(positions[i * 3]!, positions[i * 3 + 1]! + NODE_SIZE[nodes[i]!.type] * 0.42 + 0.6, positions[i * 3 + 2]!).project(camera); + // Behind the camera or outside the view: hide instead of drawing at a mirrored position. + if (projected.z > 1 || Math.abs(projected.x) > 1.1 || Math.abs(projected.y) > 1.1) { + el.style.visibility = 'hidden'; + continue; + } + el.style.visibility = 'visible'; + el.style.transform = `translate(${((projected.x + 1) / 2) * size.width}px, ${((1 - projected.y) / 2) * size.height}px) translate(-50%, -120%)`; + } + }); + + return ( + <> + + {FAMILIES.map((family) => { + const count = byFamily.get(family)?.length ?? 0; + if (!count) return null; + return ( + { + if (m) meshes.current.set(family, m); + else meshes.current.delete(family); + }} + args={[undefined, undefined, count]} + frustumCulled={false} + {...handlers(family)} + > + + + + ); + })} + + + + + + + + ); +} + +export function Atlas() { + const { view, adj, palette, settings, reducedMotion, expandFile, openView, theme } = useWs(); + const primaryId = useWorkspace((s) => s.primaryId); + const focusId = useWorkspace((s) => s.focusId); + const [gl, setGl] = useState<'ok' | 'unsupported' | 'lost'>(() => (webglAvailable() ? 'ok' : 'unsupported')); + const [attempt, setAttempt] = useState(0); + const apiRef = useRef(null); + const [labelItems, setLabelItems] = useState([]); + const labelEls = useRef(new Map()); + const quality = settings.performance.renderingQuality; + + const parentOf = useCallback( + (n: GraphNode): string | null => { + if (!isSymbolType(n.type)) return null; + const parentEdge = (adj.in.get(n.id) ?? []).find((e) => e.type === 'CONTAINS'); + return parentEdge?.source ?? fileIdOf(n); + }, + [adj], + ); + const layout = useLayout3d(view.nodes, view.edges, parentOf, quality); + const current = layout && layout.ids.length === view.nodes.length && layout.ids[0] === view.nodes[0]?.id && layout.ids[layout.ids.length - 1] === view.nodes[view.nodes.length - 1]?.id ? layout : null; + + const onExpand = useCallback( + (id: string) => { + const n = adj.nodes.get(id); + if (!n) return; + if (n.type === 'File' || n.type === 'Configuration') return expandFile(id); + if (n.type === 'Subsystem' || n.type === 'Concept') { + // Unfold the files of a region. + (adj.in.get(id) ?? []).filter((e) => e.type === 'BELONGS_TO').slice(0, 60).forEach((e) => expandFile(e.source, true)); + return; + } + const fid = fileIdOf(n); + if (fid) expandFile(fid, true); + }, + [adj, expandFile], + ); + + const primary = primaryId ? adj.nodes.get(primaryId) : undefined; + const crumbs = useMemo(() => { + const out: GraphNode[] = []; + const repo = adj.nodes.get('repo:root'); + if (repo) out.push(repo); + if (!primary || primary.type === 'Repository') return out; + const sub = adj.nodes.get((primary.metadata.subsystem as string | undefined) ?? ''); + if (sub && sub.id !== primary.id) out.push(sub); + const file = isSymbolType(primary.type) ? adj.nodes.get(fileIdOf(primary) ?? '') : undefined; + if (file) out.push(file); + const parent = isSymbolType(primary.type) ? adj.nodes.get((adj.in.get(primary.id) ?? []).find((e) => e.type === 'CONTAINS')?.source ?? '') : undefined; + if (parent && isSymbolType(parent.type)) out.push(parent); + out.push(primary); + return out; + }, [primary, adj]); + const subsystemId = (primary?.metadata.subsystem as string | undefined) ?? (primary?.type === 'Subsystem' ? primary.id : undefined); + const labelBudget = quality === 'low' ? 0 : { low: 6, medium: 16, high: 40 }[settings.graph.labelDensity]; + + if (gl !== 'ok') + return ( +
+

{gl === 'lost' ? 'The 3D view lost its graphics context' : '3D rendering is not available here'}

+

+ {gl === 'lost' + ? 'The browser reclaimed the graphics memory used by the Atlas. Your selection and filters are kept.' + : 'This browser or device does not provide WebGL. The same graph is available in two dimensions.'} +

+
+ + {gl === 'lost' ? ( + + ) : null} +
+
+ ); + + return ( +
+ + + {subsystemId ? ( + + ) : null} + {primary && focusId !== primary.id ? ( + + ) : null} + + + + {current ? ( + { + renderer.domElement.addEventListener('webglcontextlost', (e) => { + e.preventDefault(); + setGl('lost'); + }); + }} + onPointerMissed={(e) => { + if (e.type === 'click') useWorkspace.getState().clearSelection(); + }} + aria-label="3D knowledge atlas. Drag to orbit, right-drag to pan, scroll to zoom. Use Search to move to a node." + role="application" + > + + + + + + + ) : ( + + )} + {current ? ( + + ) : null} + +

Drag to orbit, right-drag to pan, scroll to zoom, double-click to unfold

+
+ ); +} diff --git a/apps/web/src/workspace/Dependencies.tsx b/apps/web/src/workspace/Dependencies.tsx new file mode 100644 index 0000000..b7a207a --- /dev/null +++ b/apps/web/src/workspace/Dependencies.tsx @@ -0,0 +1,317 @@ +import { useMemo, useState } from 'react'; +import { EDGE_TYPE_LABELS } from '@vectora/graph-schema'; +import { Empty, SectionHeading, cx } from '@/components/ui'; +import { useAnalysis } from '@/lib/api'; +import { useWorkspace } from '@/lib/store'; +import { useWs } from './context'; + +type Tab = 'packages' | 'subsystems' | 'cycles' | 'flows' | 'unresolved'; + +/** Finds groups of files that import each other (strongly connected components, Tarjan). */ +function importCycles(nodes: string[], out: Map): string[][] { + const index = new Map(); + const low = new Map(); + const stack: string[] = []; + const on = new Set(); + const result: string[][] = []; + let counter = 0; + for (const root of nodes) { + if (index.has(root)) continue; + const work: { id: string; i: number }[] = [{ id: root, i: 0 }]; + index.set(root, counter); + low.set(root, counter++); + stack.push(root); + on.add(root); + while (work.length) { + const f = work[work.length - 1]!; + const next = out.get(f.id) ?? []; + if (f.i < next.length) { + const w = next[f.i++]!; + if (!index.has(w)) { + index.set(w, counter); + low.set(w, counter++); + stack.push(w); + on.add(w); + work.push({ id: w, i: 0 }); + } else if (on.has(w)) low.set(f.id, Math.min(low.get(f.id)!, index.get(w)!)); + } else { + work.pop(); + const parent = work[work.length - 1]; + if (parent) low.set(parent.id, Math.min(low.get(parent.id)!, low.get(f.id)!)); + if (low.get(f.id) === index.get(f.id)) { + const comp: string[] = []; + let w: string; + do { + w = stack.pop()!; + on.delete(w); + comp.push(w); + } while (w !== f.id); + if (comp.length > 1) result.push(comp); + } + } + } + } + return result.sort((a, b) => b.length - a.length); +} + +export function Dependencies() { + const { repo, graph, adj, reveal, openView, settings } = useWs(); + const { data: analysis } = useAnalysis(repo.id); + const setHighlight = useWorkspace((s) => s.setHighlight); + const [tab, setTab] = useState('packages'); + const [filter, setFilter] = useState(''); + + const packages = useMemo( + () => + graph.nodes + .filter((n) => n.type === 'Package') + .map((p) => { + const importers = (adj.in.get(p.id) ?? []).filter((e) => e.type === 'IMPORTS'); + const declaredBy = (adj.in.get(p.id) ?? []).filter((e) => e.type === 'DEPENDS_ON'); + return { node: p, importers, declaredBy, files: new Set(importers.map((e) => e.source)).size }; + }) + .sort((a, b) => b.files - a.files || (a.node.name < b.node.name ? -1 : 1)), + [graph, adj], + ); + const subsystemDeps = useMemo(() => graph.edges.filter((e) => e.type === 'DEPENDS_ON' && e.source.startsWith('sub:')).sort((a, b) => Number(b.metadata?.count ?? 0) - Number(a.metadata?.count ?? 0)), [graph]); + const cycles = useMemo(() => { + const out = new Map(); + const files = new Set(); + for (const e of graph.edges) { + if (e.type !== 'IMPORTS' || !e.target.startsWith('file:') || e.source === e.target) continue; + (out.get(e.source) ?? out.set(e.source, []).get(e.source)!).push(e.target); + files.add(e.source); + files.add(e.target); + } + return importCycles([...files], out); + }, [graph]); + + const showIn = (label: string, nodeIds: string[], edgeIds: string[] = []) => { + setHighlight({ label, nodeIds, edgeIds }); + useWorkspace.getState().clearSelection(); + openView(settings.graph.defaultMode === 'mindmap' ? 'graph' : settings.graph.defaultMode); + }; + const q = filter.trim().toLowerCase(); + const tabs: [Tab, string, number][] = [ + ['packages', 'External packages', packages.length], + ['subsystems', 'Between subsystems', subsystemDeps.length], + ['cycles', 'Circular imports', cycles.length], + ['flows', 'Execution flows', analysis?.flows.length ?? 0], + ['unresolved', 'Unresolved references', analysis?.unresolvedCount ?? 0], + ]; + + return ( +
+
+

Dependency Explorer

+
+ {tabs.map(([id, label, count]) => ( + + ))} +
+
+
+ {tab === 'packages' ? ( + packages.length === 0 ? ( + No manifest declares a dependency and no source file imports one. + ) : ( +
+ setFilter(e.target.value)} /> + + + + + + + + + + + {packages + .filter((p) => !q || p.node.name.toLowerCase().includes(q)) + .slice(0, 400) + .map((p) => ( + + + + + + + + ))} + +
PackageVersionDeclared inImporting files +
+ + {p.node.metadata.dev ? dev : null} + {(p.node.metadata.version as string | null) ?? ''} + {p.declaredBy.length ? ( + p.declaredBy.map((e) => `${e.location?.path}:${e.location?.startLine}`).join(', ') + ) : ( + not declared in a manifest + )} + {p.files || not imported} + {p.files ? ( + + ) : null} +
+
+ ) + ) : null} + + {tab === 'subsystems' ? ( + subsystemDeps.length === 0 ? ( + Either the repository has a single subsystem or no relationship crosses a subsystem boundary. + ) : ( +
    + {subsystemDeps.map((e) => ( +
  • +
    +

    + {' '} + depends on{' '} + +

    + + {Object.entries((e.metadata?.kinds as Record) ?? {}) + .map(([k, v]) => `${v} ${EDGE_TYPE_LABELS[k as keyof typeof EDGE_TYPE_LABELS]}`) + .join(', ')} + +
    +

    {e.evidence}

    +
  • + ))} +
+ ) + ) : null} + + {tab === 'cycles' ? ( + cycles.length === 0 ? ( + No group of files imports itself through resolved import relationships. + ) : ( +
    + {cycles.map((c, i) => ( +
  • +
    +

    {c.length} files import each other

    + +
    +
      + {c.slice(0, 12).map((id) => ( +
    • + +
    • + ))} + {c.length > 12 ?
    • {c.length - 12} more
    • : null} +
    +
  • + ))} +
+ ) + ) : null} + + {tab === 'flows' ? ( + !analysis?.flows.length ? ( + No API endpoint or entry point with resolved outgoing calls was found. + ) : ( +
+

Flows follow route and call relationships from an endpoint or entry point. They are derived from static structure; callbacks and runtime wiring are not included.

+
    + {analysis.flows.map((f) => ( +
  • +
    +

    + {f.name} {f.reachesData ? reaches data access : null} +

    + +
    +
      + {f.steps.map((s, i) => ( +
    1. + {i > 0 ? : null} + +
    2. + ))} +
    +
  • + ))} +
+
+ ) + ) : null} + + {tab === 'unresolved' ? ( + !analysis?.unresolvedCount ? ( + Every reference the analysers found was tied to a definition. + ) : ( +
+

+ These references were found in the source but could not be tied to a definition with scope evidence. They are reported here and are not part of the graph. +

+ By reason +
    + {Object.entries(analysis.unresolvedByReason) + .sort((a, b) => b[1] - a[1]) + .map(([reason, count]) => ( +
  • + {reason} + {count.toLocaleString()} +
  • + ))} +
+ Samples + + + + + + + + + + + {analysis.unresolvedSamples.slice(0, 300).map((u, i) => ( + + + + + + + ))} + +
ReferenceKindLocationReason
{u.name}{EDGE_TYPE_LABELS[u.kind as keyof typeof EDGE_TYPE_LABELS] ?? u.kind} + + {u.reason}
+
+ ) + ) : null} +
+
+ ); +} diff --git a/apps/web/src/workspace/Documentation.tsx b/apps/web/src/workspace/Documentation.tsx new file mode 100644 index 0000000..780e5e5 --- /dev/null +++ b/apps/web/src/workspace/Documentation.tsx @@ -0,0 +1,125 @@ +import { useQuery } from '@tanstack/react-query'; +import { useEffect } from 'react'; +import Markdown from 'react-markdown'; +import { useSearchParams } from 'react-router'; +import { CodePreview } from '@/components/CodePreview'; +import { Empty, Loading, cx } from '@/components/ui'; +import { api, useSource } from '@/lib/api'; +import { useWs } from './context'; + +/** Documentation files found in the repository, plus documents generated from the graph. */ +export function Documentation() { + const { repo } = useWs(); + const [params, setParams] = useSearchParams(); + const docs = useQuery({ queryKey: ['docs', repo.id], queryFn: () => api.docs(repo.id) }); + const generated = params.get('generated'); + const path = params.get('path'); + useEffect(() => { + if (!path && !generated && docs.data) setParams(docs.data[0] ? { path: docs.data[0].path } : { generated: 'architecture' }, { replace: true }); + }, [path, generated, docs.data, setParams]); + const source = useSource(repo.id, path); + const gen = useQuery({ + queryKey: ['generated-doc', repo.id, generated], + queryFn: async () => (await fetch(api.exportUrl(repo.id, generated!, false))).text(), + enabled: !!generated, + }); + const content = generated ? gen.data : source.data?.content; + const isMarkdown = !!generated || /\.(md|mdx|markdown)$/i.test(path ?? ''); + + return ( +
+ +
+ {(generated ? gen.isLoading : source.isLoading) ? ( + + ) : (generated ? gen.error : source.error) ? ( + {((generated ? gen.error : source.error) as Error).message} + ) : content === undefined ? null : isMarkdown ? ( +
+ {generated ?

Generated from the knowledge graph. Download it from Export in the header.

:

{path}

} + {/* react-markdown renders to React elements and ignores raw HTML, so repository text cannot inject markup. */} + (/^(https?:|mailto:|#)/i.test(url) ? url : '')} + components={{ + a: ({ href, children }) => (href ? {children} : {children}), + img: ({ alt }) => [image: {alt || 'no description'}], + }} + > + {content} + +
+ ) : ( +
+

{path}

+ +
+ )} + {!generated && source.data?.truncated ?

The file is larger than the preview limit and was shortened.

: null} +
+
+ ); +} + +/** Full-file source viewer, opened from “Open source location”. */ +export function SourceView() { + const { repo, adj, reveal, openView, settings } = useWs(); + const [params] = useSearchParams(); + const path = params.get('path'); + const line = Number(params.get('line') ?? 1) || 1; + const { data, isLoading, error } = useSource(repo.id, path); + if (!path) return Open a source location from the inspector.; + if (isLoading) return ; + if (error || !data) return {(error as Error | null)?.message}; + const fileId = `file:${data.path}`; + return ( +
+
+
+

{data.path}

+

+ {data.totalLines.toLocaleString()} lines{data.language ? `, ${data.language}` : ''} + {data.truncated ? ', shortened to the preview limit' : ''} — line {line} +

+
+ {adj.nodes.has(fileId) ? ( + + ) : null} +
+
+ +
+
+ ); +} diff --git a/apps/web/src/workspace/GraphExplorer.tsx b/apps/web/src/workspace/GraphExplorer.tsx new file mode 100644 index 0000000..bd474f0 --- /dev/null +++ b/apps/web/src/workspace/GraphExplorer.tsx @@ -0,0 +1,541 @@ +import Graph from 'graphology'; +import forceAtlas2 from 'graphology-layout-forceatlas2'; +import FA2Layout from 'graphology-layout-forceatlas2/worker'; +import noverlap from 'graphology-layout-noverlap'; +import { Image as ImageIcon, Maximize, RotateCw } from 'lucide-react'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import Sigma from 'sigma'; +import { seed2d } from '@vectora/graph-layout'; +import { EDGE_TYPE_LABELS, type GraphNode, isSymbolType } from '@vectora/graph-schema'; +import { ViewToolbar } from '@/components/ViewControls'; +import { downloadUrl } from '@/lib/api'; +import { fileIdOf, neighbourhood } from '@/lib/graphView'; +import { useWorkspace } from '@/lib/store'; +import { FAMILY_GLYPH, NODE_FAMILY, NODE_SIZE, STRUCTURE_EDGES, type Palette, mix, nodeColor } from '@/lib/tokens'; +import { useWs } from './context'; + +type Grouping = 'subsystem' | 'community'; + +interface RenderState { + selected: Set; + primary: string | null; + hover: string | null; + activeNodes: Set | null; + activeEdges: Set | null; + palette: Palette; +} + +const LABEL_THRESHOLD = { low: 11, medium: 7.5, high: 4.5 } as const; +const LABEL_DENSITY = { low: 0.4, medium: 0.9, high: 1.8 } as const; + +export function GraphExplorer() { + const { view, adj, palette, settings, reducedMotion, expandFile, theme } = useWs(); + const selectedIds = useWorkspace((s) => s.selectedIds); + const primaryId = useWorkspace((s) => s.primaryId); + const hoverId = useWorkspace((s) => s.hoverId); + const highlight = useWorkspace((s) => s.highlight); + const revealTick = useWorkspace((s) => s.revealTick); + const container = useRef(null); + const minimap = useRef(null); + const sigmaRef = useRef(null); + const graphRef = useRef(null); + const layoutRef = useRef<{ stop: () => void } | null>(null); + const stateRef = useRef({ selected: new Set(), primary: null, hover: null, activeNodes: null, activeEdges: null, palette }); + const viewRef = useRef(view); + viewRef.current = view; + const [grouping, setGrouping] = useState('subsystem'); + const [arranging, setArranging] = useState(false); + const [failed, setFailed] = useState(null); + const groupingRef = useRef(grouping); + groupingRef.current = grouping; + + const saveLayout = useCallback(() => { + const g = graphRef.current; + if (!g) return; + const out: Record = { ...(useWorkspace.getState().layouts.graph ?? {}) }; + g.forEachNode((id, a) => { + out[id] = [Math.round(a.x * 100) / 100, Math.round(a.y * 100) / 100]; + }); + const entries = Object.entries(out); + useWorkspace.getState().setLayout('graph', entries.length > 20000 ? Object.fromEntries(entries.slice(-20000)) : out); + }, []); + + const runLayout = useCallback( + (fromScratch: boolean) => { + const g = graphRef.current; + if (!g || g.order === 0) return; + layoutRef.current?.stop(); + if (fromScratch) { + const seeds = seed2d(viewRef.current.nodes.map((n) => ({ id: n.id, group: groupingRef.current === 'community' ? (n.metadata.community as number | undefined ?? null) : ((n.metadata.subsystem as string | undefined) ?? n.type) }))); + g.forEachNode((id) => { + const p = seeds.get(id); + if (p) g.mergeNodeAttributes(id, { x: p[0], y: p[1] }); + }); + } + const fa2 = { ...forceAtlas2.inferSettings(g), barnesHutOptimize: g.order > 1200, gravity: 0.5, scalingRatio: 8, slowDown: 6 + Math.log(g.order + 1), strongGravityMode: false }; + const finish = () => { + noverlap.assign(g, { maxIterations: g.order > 3000 ? 15 : 60, settings: { margin: 2, ratio: 1.1 } }); + setArranging(false); + saveLayout(); + }; + if (reducedMotion) { + // No animated settling: compute the arrangement in one step. + forceAtlas2.assign(g, { iterations: g.order > 3000 ? 40 : g.order > 800 ? 100 : 220, settings: fa2 }); + finish(); + return; + } + const layout = new FA2Layout(g, { settings: fa2 }); + layout.start(); + setArranging(true); + const base = settings.graph.animationIntensity === 'standard' ? 4200 : 2400; + const timer = setTimeout(() => stop(), base * (g.order > 3000 ? 1.8 : 1)); + let stopped = false; + const stop = () => { + if (stopped) return; + stopped = true; + clearTimeout(timer); + layout.kill(); + if (graphRef.current === g) finish(); + }; + layoutRef.current = { stop }; + }, + [reducedMotion, settings.graph.animationIntensity, saveLayout], + ); + + // ---- create the renderer once ------------------------------------------ + useEffect(() => { + if (!container.current) return; + const g = new Graph({ multi: true, type: 'directed' }); + graphRef.current = g; + let sigma: Sigma; + try { + sigma = new Sigma(g, container.current, { + allowInvalidContainer: true, + defaultEdgeType: 'arrow', + renderEdgeLabels: true, + zIndex: true, + labelFont: '"Zen Kaku Gothic New", system-ui, sans-serif', + labelSize: 12, + labelWeight: '400', + edgeLabelFont: '"IBM Plex Mono", monospace', + edgeLabelSize: 10, + minCameraRatio: 0.015, + maxCameraRatio: 6, + stagePadding: 60, + nodeReducer: (id, data) => { + const s = stateRef.current; + const res = { ...data }; + const isSelected = s.selected.has(id); + if (s.activeNodes && !s.activeNodes.has(id) && !isSelected) { + res.color = mix(data.color as string, s.palette.canvas, 0.8); + res.label = ''; + res.zIndex = 0; + } else if (s.activeNodes) { + res.zIndex = 1; + if (s.activeNodes.size <= 60) res.forceLabel = true; + } + if (isSelected || id === s.hover) { + res.highlighted = true; + res.forceLabel = true; + res.zIndex = 2; + res.size = (data.size as number) * 1.35; + } + return res; + }, + edgeReducer: (id, data) => { + const s = stateRef.current; + const res = { ...data }; + if (s.activeEdges) { + if (s.activeEdges.has(id)) { + res.color = data.verified ? s.palette.relationActive : s.palette.relationUnverified; + res.size = data.verified ? 1.8 : 1; + res.label = `${data.relation as string}${data.verified ? '' : ' (derived)'}`; + res.forceLabel = s.activeEdges.size <= 40; + res.zIndex = 2; + } else { + res.color = mix(data.color as string, s.palette.canvas, 0.75); + res.label = ''; + res.zIndex = 0; + } + } else res.label = ''; + return res; + }, + // Hover label drawn with theme colours instead of the library's white box. + defaultDrawNodeHover: (ctx, data, st) => { + const p = stateRef.current.palette; + const size = st.labelSize; + ctx.font = `${st.labelWeight} ${size}px ${st.labelFont}`; + const label = typeof data.label === 'string' ? data.label : ''; + const w = label ? ctx.measureText(label).width + 12 : 0; + ctx.beginPath(); + ctx.arc(data.x, data.y, data.size + 3, 0, Math.PI * 2); + ctx.strokeStyle = p.selection; + ctx.lineWidth = 1.5; + ctx.stroke(); + if (!label) return; + ctx.fillStyle = p.elevated; + ctx.strokeStyle = p.line; + ctx.lineWidth = 1; + const x = data.x + data.size + 6; + ctx.fillRect(x, data.y - size / 2 - 4, w, size + 8); + ctx.strokeRect(x, data.y - size / 2 - 4, w, size + 8); + ctx.fillStyle = p.text; + ctx.fillText(label, x + 6, data.y + size / 3); + }, + }); + } catch (err) { + setFailed((err as Error).message); + return; + } + sigmaRef.current = sigma; + const ws = useWorkspace.getState; + + sigma.on('clickNode', (e) => { + const ev = e.event.original as MouseEvent; + ws().select(e.node, { additive: ev.ctrlKey || ev.metaKey || ev.shiftKey }); + }); + sigma.on('doubleClickNode', (e) => { + e.preventSigmaDefault(); + expandRef.current(e.node); + }); + sigma.on('enterNode', (e) => { + ws().setHover(e.node); + if (container.current) container.current.style.cursor = 'pointer'; + }); + sigma.on('leaveNode', () => { + ws().setHover(null); + if (container.current) container.current.style.cursor = ''; + }); + sigma.on('clickStage', () => ws().clearSelection()); + + // Dragging nodes to rearrange the layout. + let dragged: string | null = null; + let moved = false; + sigma.on('downNode', (e) => { + dragged = e.node; + moved = false; + if (!sigma.getCustomBBox()) sigma.setCustomBBox(sigma.getBBox()); + }); + sigma.getMouseCaptor().on('mousemovebody', (e) => { + if (!dragged) return; + moved = true; + layoutRef.current?.stop(); + const pos = sigma.viewportToGraph(e); + g.mergeNodeAttributes(dragged, { x: pos.x, y: pos.y }); + e.preventSigmaDefault(); + e.original.preventDefault(); + e.original.stopPropagation(); + }); + const release = () => { + if (dragged && moved) saveLayout(); + dragged = null; + }; + sigma.getMouseCaptor().on('mouseup', release); + + // Minimap, redrawn at most every 120 ms. + let pending = false; + const drawMinimap = () => { + pending = false; + const c = minimap.current; + if (!c || g.order === 0) return; + const ctx = c.getContext('2d'); + if (!ctx) return; + const p = stateRef.current.palette; + let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; + g.forEachNode((_, a) => { + if (a.x < minX) minX = a.x; + if (a.x > maxX) maxX = a.x; + if (a.y < minY) minY = a.y; + if (a.y > maxY) maxY = a.y; + }); + const pad = 8; + const sx = (c.width - pad * 2) / Math.max(1e-6, maxX - minX); + const sy = (c.height - pad * 2) / Math.max(1e-6, maxY - minY); + const k = Math.min(sx, sy); + const ox = (c.width - (maxX - minX) * k) / 2; + const oy = (c.height - (maxY - minY) * k) / 2; + const map = (x: number, y: number): [number, number] => [ox + (x - minX) * k, c.height - (oy + (y - minY) * k)]; + ctx.clearRect(0, 0, c.width, c.height); + const step = Math.max(1, Math.floor(g.order / 2500)); + let i = 0; + g.forEachNode((id, a) => { + if (i++ % step) return; + const [x, y] = map(a.x, a.y); + ctx.fillStyle = stateRef.current.selected.has(id) ? p.selection : p.textMuted; + const r = stateRef.current.selected.has(id) ? 2.5 : 1; + ctx.fillRect(x - r / 2, y - r / 2, r, r); + }); + const dims = sigma.getDimensions(); + const a = sigma.viewportToGraph({ x: 0, y: 0 }); + const b = sigma.viewportToGraph({ x: dims.width, y: dims.height }); + const [x1, y1] = map(a.x, a.y); + const [x2, y2] = map(b.x, b.y); + ctx.strokeStyle = p.selection; + ctx.lineWidth = 1; + ctx.strokeRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1)); + (c as HTMLCanvasElement & { _unmap?: (px: number, py: number) => { x: number; y: number } })._unmap = (px, py) => ({ x: minX + (px - ox) / k, y: minY + (c.height - py - oy) / k }); + }; + sigma.on('afterRender', () => { + if (pending) return; + pending = true; + setTimeout(drawMinimap, 120); + }); + + return () => { + layoutRef.current?.stop(); + sigma.kill(); + sigmaRef.current = null; + graphRef.current = null; + }; + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + /** Double-click: a file unfolds its symbols; any other node unfolds the files around it. */ + const expandAround = (id: string) => { + const n = adj.nodes.get(id); + if (!n) return; + if (n.type === 'File' || n.type === 'Configuration') return expandFile(id); + const files = new Set(); + const own = fileIdOf(n); + if (own) files.add(own); + for (const e of [...(adj.out.get(id) ?? []), ...(adj.in.get(id) ?? [])]) { + const other = adj.nodes.get(e.source === id ? e.target : e.source); + if (!other) continue; + if (other.type === 'File') files.add(other.id); + else if (isSymbolType(other.type)) { + const fid = fileIdOf(other); + if (fid) files.add(fid); + } + } + [...files].slice(0, 40).forEach((f) => expandFile(f, true)); + }; + const expandRef = useRef(expandAround); + expandRef.current = expandAround; + + // ---- sync graph data ---------------------------------------------------- + useEffect(() => { + const g = graphRef.current; + const sigma = sigmaRef.current; + if (!g || !sigma) return; + const saved = useWorkspace.getState().layouts.graph ?? {}; + const wanted = new Set(view.nodes.map((n) => n.id)); + g.forEachNode((id) => { + if (!wanted.has(id)) g.dropNode(id); + }); + const fresh: GraphNode[] = []; + const scale = view.nodes.length > 4000 ? 0.75 : view.nodes.length > 1500 ? 0.9 : 1.15; + for (const n of view.nodes) { + const attrs = { + label: `${FAMILY_GLYPH[NODE_FAMILY[n.type]]} ${n.name}`, + size: NODE_SIZE[n.type] * scale + 1.2, + color: nodeColor(n.type, palette), + nodeType: n.type, + }; + if (g.hasNode(n.id)) g.mergeNodeAttributes(n.id, attrs); + else { + const s = saved[n.id]; + if (!s) fresh.push(n); + g.addNode(n.id, { ...attrs, x: s?.[0] ?? 0, y: s?.[1] ?? 0 }); + } + } + // New nodes start next to something they belong to, so expansion grows outwards from the parent. + const firstRun = fresh.length === view.nodes.length; + if (fresh.length && !firstRun) { + fresh.forEach((n, i) => { + const anchor = [fileIdOf(n), n.metadata.subsystem as string | undefined].find((a) => a && a !== n.id && g.hasNode(a) && !fresh.some((f) => f.id === a)); + const a = anchor ? g.getNodeAttributes(anchor) : { x: 0, y: 0 }; + const t = i * 2.399963; + const r = 2 + Math.sqrt(i + 1) * 1.6; + g.mergeNodeAttributes(n.id, { x: a.x + Math.cos(t) * r, y: a.y + Math.sin(t) * r }); + }); + } + g.clearEdges(); + for (const e of view.edges) { + if (!g.hasNode(e.source) || !g.hasNode(e.target)) continue; + const structural = STRUCTURE_EDGES.includes(e.type); + g.addEdgeWithKey(e.id, e.source, e.target, { + size: !e.verified ? 0.5 : structural ? 0.6 : 1, + color: mix(e.verified ? palette.textMuted : palette.relationUnverified, palette.canvas, structural ? 0.55 : 0.3), + type: structural ? 'line' : 'arrow', + relation: EDGE_TYPE_LABELS[e.type], + verified: e.verified, + weight: structural ? 2 : 1, + }); + } + sigma.setSetting('hideEdgesOnMove', view.edges.length > 5000); + sigma.setSetting('hideLabelsOnMove', view.nodes.length > 5000); + if (sigma.getCustomBBox()) sigma.setCustomBBox(null); + if (firstRun) runLayout(true); + else if (fresh.length) runLayout(false); + else sigma.refresh(); + }, [view, palette, runLayout]); + + // ---- settings and theme ------------------------------------------------- + useEffect(() => { + const sigma = sigmaRef.current; + if (!sigma) return; + sigma.setSetting('labelColor', { color: palette.text }); + sigma.setSetting('edgeLabelColor', { color: palette.textSecondary }); + sigma.setSetting('labelRenderedSizeThreshold', LABEL_THRESHOLD[settings.graph.labelDensity]); + sigma.setSetting('labelDensity', LABEL_DENSITY[settings.graph.labelDensity]); + stateRef.current.palette = palette; + sigma.refresh(); + }, [palette, theme, settings.graph.labelDensity]); + + // ---- selection, hover and highlight ------------------------------------ + useEffect(() => { + const s = stateRef.current; + s.selected = new Set(selectedIds); + s.primary = primaryId; + s.hover = hoverId; + const centre = hoverId ?? primaryId; + if (centre && graphRef.current?.hasNode(centre)) { + const nb = neighbourhood(centre, view.edges); + for (const id of selectedIds) if (id !== centre) for (const x of neighbourhood(id, view.edges).nodes) nb.nodes.add(x); + s.activeNodes = nb.nodes; + s.activeEdges = nb.edges; + } else if (highlight) { + s.activeNodes = new Set(highlight.nodeIds); + s.activeEdges = new Set(highlight.edgeIds); + } else { + s.activeNodes = null; + s.activeEdges = null; + } + sigmaRef.current?.refresh({ skipIndexation: true }); + }, [selectedIds, primaryId, hoverId, highlight, view]); + + // ---- bring the selection into view ------------------------------------- + useEffect(() => { + const sigma = sigmaRef.current; + const id = useWorkspace.getState().primaryId ?? useWorkspace.getState().focusId; + if (!sigma || revealTick === 0) return; + const t = setTimeout(() => { + if (id && graphRef.current?.hasNode(id) && settings.graph.focusBehavior !== 'none') { + const d = sigma.getNodeDisplayData(id); + if (d) void sigma.getCamera().animate({ x: d.x, y: d.y, ratio: Math.min(sigma.getCamera().ratio, 0.4) }, { duration: reducedMotion ? 0 : 700 }); + } else if (!id) void sigma.getCamera().animatedReset({ duration: reducedMotion ? 0 : 600 }); + }, 60); + return () => clearTimeout(t); + }, [revealTick, reducedMotion, settings.graph.focusBehavior]); + + const fit = () => { + const sigma = sigmaRef.current; + if (!sigma) return; + sigma.setCustomBBox(null); + void sigma.getCamera().animatedReset({ duration: reducedMotion ? 0 : 500 }); + }; + const exportPng = () => { + const sigma = sigmaRef.current; + if (!sigma || !container.current) return; + sigma.once('afterRender', () => { + const { width, height } = sigma.getDimensions(); + const ratio = window.devicePixelRatio || 1; + const out = document.createElement('canvas'); + out.width = width * ratio; + out.height = height * ratio; + const ctx = out.getContext('2d')!; + ctx.fillStyle = palette.canvas; + ctx.fillRect(0, 0, out.width, out.height); + container.current!.querySelectorAll('canvas').forEach((c) => { + if (c !== minimap.current) ctx.drawImage(c, 0, 0, out.width, out.height); + }); + downloadUrl('vectora-graph.png', out.toDataURL('image/png')); + }); + sigma.refresh(); + }; + const onKeyDown = (e: React.KeyboardEvent) => { + const sigma = sigmaRef.current; + if (!sigma) return; + const cam = sigma.getCamera(); + const step = 0.12 * cam.ratio; + const dur = { duration: reducedMotion ? 0 : 160 }; + if (e.key === '+' || e.key === '=') void cam.animatedZoom(dur); + else if (e.key === '-') void cam.animatedUnzoom(dur); + else if (e.key === '0') fit(); + else if (e.key === 'ArrowLeft') void cam.animate({ x: cam.x - step }, dur); + else if (e.key === 'ArrowRight') void cam.animate({ x: cam.x + step }, dur); + else if (e.key === 'ArrowUp') void cam.animate({ y: cam.y + step }, dur); + else if (e.key === 'ArrowDown') void cam.animate({ y: cam.y - step }, dur); + else if (e.key === 'n' || e.key === 'p') { + // Step through the neighbours of the selection (or all nodes) without a pointer. + const ws = useWorkspace.getState(); + const pool = ws.primaryId ? [...neighbourhood(ws.primaryId, view.edges).nodes] : view.nodes.map((n) => n.id); + if (!pool.length) return; + const i = pool.indexOf(ws.hoverId ?? ws.primaryId ?? ''); + ws.setHover(pool[(i + (e.key === 'n' ? 1 : -1) + pool.length) % pool.length]!); + } else if (e.key === 'Enter') { + const ws = useWorkspace.getState(); + if (ws.hoverId) ws.select(ws.hoverId, { reveal: true }); + } else return; + e.preventDefault(); + }; + + if (failed) + return ( +
+

The graph renderer could not start

+

WebGL is not available in this browser ({failed}). The Mind Map and Search views work without it.

+
+ ); + + return ( +
+ + + + + + +
+ { + const sigma = sigmaRef.current; + const c = minimap.current as (HTMLCanvasElement & { _unmap?: (px: number, py: number) => { x: number; y: number } }) | null; + if (!sigma || !c?._unmap) return; + const r = c.getBoundingClientRect(); + const gp = c._unmap(((e.clientX - r.left) / r.width) * c.width, ((e.clientY - r.top) / r.height) * c.height); + const framed = sigma.viewportToFramedGraph(sigma.graphToViewport(gp)); + void sigma.getCamera().animate({ x: framed.x, y: framed.y }, { duration: reducedMotion ? 0 : 400 }); + }} + /> +

+ Click to inspect, double-click to unfold, Ctrl-click to add to the selection, drag to rearrange +

+
+ ); +} diff --git a/apps/web/src/workspace/MindMap.tsx b/apps/web/src/workspace/MindMap.tsx new file mode 100644 index 0000000..97ad5b4 --- /dev/null +++ b/apps/web/src/workspace/MindMap.tsx @@ -0,0 +1,462 @@ +import dagre from '@dagrejs/dagre'; +import { Background, Controls, type Edge, Handle, MiniMap, type Node, type NodeProps, Position, ReactFlow, ReactFlowProvider, getNodesBounds, getViewportForBounds, useReactFlow } from '@xyflow/react'; +import '@xyflow/react/dist/style.css'; +import { toPng, toSvg } from 'html-to-image'; +import { ChevronRight, Image as ImageIcon, RotateCcw } from 'lucide-react'; +import { memo, useCallback, useEffect, useMemo, useState } from 'react'; +import { EDGE_TYPES, EDGE_TYPE_LABELS, type EdgeType, type GraphNode, isSymbolType } from '@vectora/graph-schema'; +import { ViewToolbar } from '@/components/ViewControls'; +import { cx } from '@/components/ui'; +import { downloadUrl } from '@/lib/api'; +import { type Adjacency, fileIdOf } from '@/lib/graphView'; +import { useWorkspace } from '@/lib/store'; +import { FAMILY_GLYPH, NODE_FAMILY } from '@/lib/tokens'; +import { useWs } from './context'; + +interface TreeItem { + /** Tree-unique key. A graph node can appear under several branches (e.g. a file under a subsystem and a concept). */ + key: string; + nodeId: string | null; + label: string; + node: GraphNode | null; + children: TreeItem[]; + derived?: boolean; +} + +const dirOf = (p: string): string => (p.includes('/') ? p.slice(0, p.lastIndexOf('/')) : ''); + +/** + * Builds the conceptual hierarchy from the knowledge graph: + * repository → subsystems → folders → files → symbols, plus a branch of concepts. + */ +export function buildTree(adj: Adjacency, hiddenTypes: ReadonlySet): TreeItem | null { + const repo = adj.nodes.get('repo:root'); + if (!repo) return null; + const symbolChildren = (parentId: string, prefix: string, depth = 0): TreeItem[] => + depth > 3 + ? [] + : (adj.out.get(parentId) ?? []) + .filter((e) => e.type === 'CONTAINS') + .map((e) => adj.nodes.get(e.target)) + .filter((n): n is GraphNode => !!n && isSymbolType(n.type) && !hiddenTypes.has(n.type)) + .sort((a, b) => (a.location?.startLine ?? 0) - (b.location?.startLine ?? 0)) + .map((n) => ({ key: `${prefix}>${n.id}`, nodeId: n.id, label: n.name, node: n, children: symbolChildren(n.id, prefix, depth + 1) })); + const fileItem = (f: GraphNode, prefix: string): TreeItem => ({ key: `${prefix}>${f.id}`, nodeId: f.id, label: f.name, node: f, children: symbolChildren(f.id, prefix) }); + + const subsystems = [...adj.nodes.values()].filter((n) => n.type === 'Subsystem').sort((a, b) => Number(b.metadata.files ?? 0) - Number(a.metadata.files ?? 0)); + const subsystemItems: TreeItem[] = subsystems.map((s) => { + const base = String(s.filePath ?? ''); + const files = (adj.in.get(s.id) ?? []) + .filter((e) => e.type === 'BELONGS_TO') + .map((e) => adj.nodes.get(e.source)) + .filter((n): n is GraphNode => !!n && !hiddenTypes.has(n.type)); + // Group files by folder below the subsystem root. + const root: TreeItem = { key: s.id, nodeId: s.id, label: s.name, node: s, children: [] }; + const folders = new Map([['', root]]); + const folder = (rel: string): TreeItem => { + const existing = folders.get(rel); + if (existing) return existing; + const parent = folder(dirOf(rel)); + const full = base ? `${base}/${rel}` : rel; + const dirNode = adj.nodes.get(`dir:${full}`) ?? null; + const item: TreeItem = { key: `${s.id}>dir:${full}`, nodeId: dirNode?.id ?? null, label: rel.slice(rel.lastIndexOf('/') + 1), node: dirNode, children: [] }; + folders.set(rel, item); + parent.children.push(item); + return item; + }; + for (const f of files.sort((a, b) => (a.filePath! < b.filePath! ? -1 : 1))) { + const rel = base && f.filePath!.startsWith(`${base}/`) ? f.filePath!.slice(base.length + 1) : f.filePath!; + folder(dirOf(rel)).children.push(fileItem(f, s.id)); + } + // A folder that only holds one folder is merged into it (`src/app` instead of `src` → `app`). + const squash = (item: TreeItem): TreeItem => { + item.children = item.children.map(squash); + if (item !== root && item.node?.type !== 'File' && item.children.length === 1 && item.children[0]!.children.length && !item.children[0]!.node?.location) { + const only = item.children[0]!; + return { ...only, label: `${item.label}/${only.label}` }; + } + return item; + }; + return squash(root); + }); + + const concepts = [...adj.nodes.values()].filter((n) => n.type === 'Concept'); + const conceptBranch: TreeItem | null = concepts.length + ? { + key: 'branch:concepts', + nodeId: null, + label: 'Concepts', + node: null, + derived: true, + children: concepts + .map((c) => ({ + key: c.id, + nodeId: c.id, + label: c.name, + node: c, + derived: true, + children: (adj.in.get(c.id) ?? []) + .filter((e) => e.type === 'BELONGS_TO') + .sort((a, b) => b.confidence - a.confidence) + .map((e) => adj.nodes.get(e.source)) + .filter((n): n is GraphNode => !!n) + .map((f) => fileItem(f, c.id)), + })) + .sort((a, b) => b.children.length - a.children.length), + } + : null; + return { key: repo.id, nodeId: repo.id, label: repo.name, node: repo, children: [...subsystemItems, ...(conceptBranch ? [conceptBranch] : [])] }; +} + +interface MindData extends Record { + item: TreeItem; + collapsed: boolean; + depth: number; + selected: boolean; + dimmed: boolean; + matched: boolean; + onToggle: (key: string) => void; +} + +const MindNode = memo(function MindNode({ data }: NodeProps>) { + const { item, collapsed, depth, selected, dimmed, matched } = data; + const count = item.children.length; + return ( +
+ + {item.node ? ( + + ) : null} + + {item.label} + + {count ? ( + + ) : null} + +
+ ); +}); + +const nodeTypes = { mind: MindNode }; +const NODE_H = 34; +const widthOf = (item: TreeItem, depth: number) => Math.min(300, Math.max(128, item.label.length * (depth === 0 ? 10.5 : depth === 1 ? 9 : 7.6) + 84)); + +function MindMapInner() { + const { adj, graph, palette, reveal, reducedMotion } = useWs(); + const flow = useReactFlow(); + const selectedIds = useWorkspace((s) => s.selectedIds); + const hiddenNodeTypes = useWorkspace((s) => s.hiddenNodeTypes); + const revealTick = useWorkspace((s) => s.revealTick); + const layouts = useWorkspace((s) => s.layouts); + const setLayout = useWorkspace((s) => s.setLayout); + const [query, setQuery] = useState(''); + const [relation, setRelation] = useState(''); + const [drag, setDrag] = useState<{ id: string; x: number; y: number } | null>(null); + + // Folders are part of the hierarchy here even when hidden in the other views. + const hidden = useMemo(() => new Set(hiddenNodeTypes.filter((t) => t !== 'Directory' && t !== 'Module' && t !== 'Configuration')), [hiddenNodeTypes]); + const tree = useMemo(() => buildTree(adj, hidden), [adj, hidden]); + + // Collapsed state: everything below the second level starts collapsed. + const defaultCollapsed = useMemo(() => { + const out: string[] = []; + const walk = (item: TreeItem, depth: number) => { + if (depth >= 1 && item.children.length) out.push(item.key); + item.children.forEach((c) => walk(c, depth + 1)); + }; + if (tree) walk(tree, 0); + return out; + }, [tree]); + const collapsedList = layouts.mindmapCollapsed ?? defaultCollapsed; + const collapsed = useMemo(() => new Set(collapsedList), [collapsedList]); + const toggle = useCallback( + (key: string) => { + const next = new Set(useWorkspace.getState().layouts.mindmapCollapsed ?? defaultCollapsed); + if (next.has(key)) next.delete(key); + else next.add(key); + setLayout('mindmapCollapsed', [...next]); + }, + [defaultCollapsed, setLayout], + ); + + // Paths from the root to every tree item, for search and reveal. + const index = useMemo(() => { + const pathTo = new Map(); + const byNode = new Map(); + const walk = (item: TreeItem, path: string[]) => { + pathTo.set(item.key, path); + if (item.nodeId) (byNode.get(item.nodeId) ?? byNode.set(item.nodeId, []).get(item.nodeId)!).push(item.key); + item.children.forEach((c) => walk(c, [...path, item.key])); + }; + if (tree) walk(tree, []); + return { pathTo, byNode }; + }, [tree]); + + const expandTo = useCallback( + (key: string) => { + const path = index.pathTo.get(key); + if (!path) return; + const next = new Set(useWorkspace.getState().layouts.mindmapCollapsed ?? defaultCollapsed); + path.forEach((k) => next.delete(k)); + setLayout('mindmapCollapsed', [...next]); + }, + [index, defaultCollapsed, setLayout], + ); + + const matches = useMemo(() => { + const q = query.trim().toLowerCase(); + if (q.length < 2 || !tree) return [] as string[]; + const out: string[] = []; + const walk = (item: TreeItem) => { + if (item.label.toLowerCase().includes(q) || item.node?.filePath?.toLowerCase().includes(q)) out.push(item.key); + item.children.forEach(walk); + }; + walk(tree); + return out.slice(0, 200); + }, [query, tree]); + + // ---- visible items and layout ------------------------------------------ + const { nodes, edges } = useMemo(() => { + if (!tree) return { nodes: [] as Node[], edges: [] as Edge[] }; + const g = new dagre.graphlib.Graph(); + g.setGraph({ rankdir: 'LR', nodesep: 10, ranksep: 56, marginx: 24, marginy: 24 }); + g.setDefaultEdgeLabel(() => ({})); + const visible: { item: TreeItem; depth: number; parent: string | null }[] = []; + const walk = (item: TreeItem, depth: number, parent: string | null) => { + visible.push({ item, depth, parent }); + g.setNode(item.key, { width: widthOf(item, depth), height: depth === 0 ? 42 : NODE_H }); + if (parent) g.setEdge(parent, item.key); + if (!collapsed.has(item.key)) item.children.slice(0, 250).forEach((c) => walk(c, depth + 1, item.key)); + }; + walk(tree, 0, null); + dagre.layout(g); + const selected = new Set(selectedIds); + const matchSet = new Set(matches); + const overrides = layouts.mindmap ?? {}; + const rfNodes: Node[] = visible.map(({ item, depth }) => { + const p = g.node(item.key); + const o = overrides[item.key]; + return { + id: item.key, + type: 'mind', + position: o ? { x: o[0], y: o[1] } : { x: p.x - p.width / 2, y: p.y - p.height / 2 }, + data: { item, collapsed: collapsed.has(item.key), depth, selected: !!item.nodeId && selected.has(item.nodeId), dimmed: matchSet.size > 0 && !matchSet.has(item.key), matched: matchSet.has(item.key), onToggle: toggle }, + width: p.width, + height: p.height, + }; + }); + const rfEdges: Edge[] = visible + .filter((v) => v.parent) + .map((v) => ({ id: `tree:${v.parent}>${v.item.key}`, source: v.parent!, target: v.item.key, type: 'smoothstep', selectable: false, style: { stroke: palette.ash, strokeWidth: 1, strokeDasharray: v.item.derived ? '4 4' : undefined } })); + + // Relationship overlay: draw the chosen relationship between visible items, + // lifting each end to its nearest visible ancestor. + if (relation) { + const visibleByNode = new Map(); + for (const v of visible) if (v.item.nodeId && !visibleByNode.has(v.item.nodeId)) visibleByNode.set(v.item.nodeId, v.item.key); + const lift = (id: string): string | null => { + let cur: GraphNode | undefined = adj.nodes.get(id); + for (let i = 0; cur && i < 6; i++) { + const k = visibleByNode.get(cur.id); + if (k) return k; + const parentEdge = (adj.in.get(cur.id) ?? []).find((e) => e.type === 'CONTAINS'); + cur = parentEdge ? adj.nodes.get(parentEdge.source) : cur.filePath && cur.id !== fileIdOf(cur) ? adj.nodes.get(fileIdOf(cur)!) : undefined; + } + return null; + }; + const seen = new Map(); + for (const e of graph.edges) { + if (e.type !== relation) continue; + const a = lift(e.source); + const b = lift(e.target); + if (!a || !b || a === b) continue; + const k = `${a}|${b}`; + const cur = seen.get(k); + if (cur) cur.count++; + else seen.set(k, { count: 1, verified: e.verified }); + if (seen.size > 400) break; + } + for (const [k, v] of seen) { + const [a, b] = k.split('|') as [string, string]; + rfEdges.push({ + id: `rel:${k}`, + source: a, + target: b, + type: 'default', + selectable: false, + label: v.count > 1 ? `${EDGE_TYPE_LABELS[relation]} ×${v.count}` : EDGE_TYPE_LABELS[relation], + labelStyle: { fontFamily: 'IBM Plex Mono, monospace', fontSize: 10, fill: palette.textSecondary }, + labelBgStyle: { fill: palette.canvas }, + style: { stroke: v.verified ? palette.relationActive : palette.relationUnverified, strokeWidth: 1.2, strokeDasharray: v.verified ? undefined : '5 4' }, + markerEnd: { type: 'arrowclosed' as never, color: v.verified ? palette.relationActive : palette.relationUnverified, width: 14, height: 14 }, + zIndex: 5, + }); + } + } + return { nodes: rfNodes, edges: rfEdges }; + }, [tree, collapsed, selectedIds, matches, layouts.mindmap, palette, relation, adj, graph.edges, toggle]); + + // While a branch is being dragged only its position changes; the layout is not recomputed. + const displayNodes = useMemo(() => (drag ? nodes.map((n) => (n.id === drag.id ? { ...n, position: { x: drag.x, y: drag.y } } : n)) : nodes), [nodes, drag]); + + // ---- focus: bring a node into view ------------------------------------- + const centreOn = useCallback( + (key: string) => { + expandTo(key); + setTimeout(() => { + const n = flow.getNode(key); + if (n) void flow.setCenter(n.position.x + (n.width ?? 120) / 2, n.position.y + NODE_H / 2, { zoom: Math.max(flow.getZoom(), 0.9), duration: reducedMotion ? 0 : 420 }); + }, 60); + }, + [expandTo, flow, reducedMotion], + ); + useEffect(() => { + if (revealTick === 0) return; + const id = useWorkspace.getState().primaryId; + const key = id ? index.byNode.get(id)?.[0] : null; + if (key) centreOn(key); + }, [revealTick]); // eslint-disable-line react-hooks/exhaustive-deps + + const exportImage = async (kind: 'png' | 'svg') => { + const el = document.querySelector('.react-flow__viewport'); + if (!el) return; + const bounds = getNodesBounds(flow.getNodes()); + const width = Math.min(8000, Math.max(800, bounds.width + 160)); + const height = Math.min(8000, Math.max(500, bounds.height + 160)); + const vp = getViewportForBounds(bounds, width, height, 0.2, 2, 0.05); + const options = { + backgroundColor: palette.canvas, + width, + height, + // Fonts are bundled with the application; skipping remote font inlining keeps the export offline. + skipFonts: true, + style: { width: `${width}px`, height: `${height}px`, transform: `translate(${vp.x}px, ${vp.y}px) scale(${vp.zoom})` }, + }; + const url = kind === 'png' ? await toPng(el, options) : await toSvg(el, options); + downloadUrl(`vectora-mindmap.${kind}`, url); + }; + + if (!tree) return null; + return ( +
+ + setQuery(e.target.value)} + onKeyDown={(e) => { + if (e.key === 'Enter' && matches[0]) { + centreOn(matches[0]); + const item = nodes.find((n) => n.id === matches[0])?.data.item; + if (item?.nodeId) useWorkspace.getState().select(item.nodeId); + } + }} + /> + {query.trim().length >= 2 ? {matches.length} found — Enter focuses the first : null} + + + + + + + { + const item = (n.data as MindData).item; + if (item.nodeId) useWorkspace.getState().select(item.nodeId, { additive: e.ctrlKey || e.metaKey || e.shiftKey }); + }} + onNodeDoubleClick={(_e, n) => { + const item = (n.data as MindData).item; + if (item.children.length) toggle(item.key); + else if (item.nodeId) reveal(item.nodeId); + }} + onNodeDrag={(_e, n) => setDrag({ id: n.id, x: n.position.x, y: n.position.y })} + onNodeDragStop={(_e, n) => { + setDrag(null); + // Rearranged branches keep their position for this workspace. + setLayout('mindmap', { ...(useWorkspace.getState().layouts.mindmap ?? {}), [n.id]: [Math.round(n.position.x), Math.round(n.position.y)] }); + }} + onNodesChange={() => undefined} + onPaneClick={() => useWorkspace.getState().clearSelection()} + aria-label="Hierarchical mind map of the repository" + > + + + + +
+ ); +} + +export function MindMap() { + return ( + + + + ); +} diff --git a/apps/web/src/workspace/Overview.tsx b/apps/web/src/workspace/Overview.tsx new file mode 100644 index 0000000..0f3af17 --- /dev/null +++ b/apps/web/src/workspace/Overview.tsx @@ -0,0 +1,258 @@ +import { Empty, Loading, SectionHeading } from '@/components/ui'; +import { useOverview } from '@/lib/api'; +import { useWorkspace } from '@/lib/store'; +import { useWs } from './context'; + +export function Overview() { + const { repo, reveal, openView, settings } = useWs(); + const { data: o, isLoading, error } = useOverview(repo.id); + const setFocus = useWorkspace((s) => s.setFocus); + if (isLoading) return ; + if (error || !o) return {(error as Error | null)?.message}; + + const show = (id: string, view: 'graph' | 'atlas' | 'mindmap' = settings.graph.defaultMode) => { + reveal(id); + openView(view); + }; + const analysed = o.languages.filter((l) => l.tier > 0); + const other = o.languages.filter((l) => l.tier === 0); + const maxFiles = Math.max(1, ...analysed.map((l) => l.files)); + + return ( +
+
+ {/* Lead column, deliberately narrow and offset */} +
+

{repo.sourceKind === 'sample' ? 'Bundled sample repository' : repo.origin}

+

{repo.name}

+ {o.description ? ( +

+ {o.description} — {o.descriptionSource} +

+ ) : ( +

No description was found in the manifests or the README.

+ )} +
+ + + +
+
+ + + +
+ Architecture summary +
    + {o.architectureSummary.map((s, i) => ( +
  • +

    + {s.statement} {!s.verified ? derived : null} +

    +

    Evidence: {s.evidence}

    +
  • + ))} +
+
+ +
+ Languages +
    + {analysed.map((l) => ( +
  • +
    + {l.language} + + {l.analyzedFiles}/{l.files} files, {l.symbols.toLocaleString()} symbols + +
    +
    +
    +
    +

    + {l.adapter ?? 'not analysed'} + {l.parseErrors ? `, ${l.parseErrors} parse notes` : ''} +

    +
  • + ))} +
+ {other.length ? ( +

+ Detected but not analysed at symbol level: {other.map((l) => `${l.language} (${l.files})`).join(', ')}. +

+ ) : null} + {o.frameworks.length ? ( + <> +

Frameworks

+
    + {o.frameworks.map((f) => ( +
  • + {f.name} +
  • + ))} +
+ + ) : null} +
+ +
+ + Major subsystems + + + + + + + + + + + + + {o.subsystems.map((s) => ( + + + + + + + + ))} + +
SubsystemFilesSymbols + Out + + In +
+ + {s.files}{s.symbols}{s.outbound}{s.inbound}
+
+ +
+ Main entry points + {o.entryPoints.length === 0 ?

No entry point could be identified from manifests or file conventions.

: null} + {o.entryPoints.map((e) => ( + + ))} + {o.concepts.length ? ( + <> +
+ Concepts +
+ {o.concepts.map((c) => ( + + ))} + + ) : null} +
+ +
+ Largest modules + + + + + + + + + + {o.largestModules.map((m) => ( + + + + + + ))} + +
FileSymbolsLines
+ + {m.symbols}{m.lines.toLocaleString()}
+
+ +
+ Dependency statistics +
+ {[ + ['Declared', o.dependencies.declared], + ['Imported', o.dependencies.imported], + ['Internal imports', o.dependencies.internalImports], + ].map(([k, v]) => ( +
+
{k}
+
{(v as number).toLocaleString()}
+
+ ))} +
+
    + {o.dependencies.externalPackages + .filter((p) => p.importers > 0) + .slice(0, 8) + .map((p) => ( +
  • + {p.name} + + {p.importers} file{p.importers === 1 ? '' : 's'} + {p.declared ? '' : ', not declared'} + +
  • + ))} +
+

+ +

+
+
+
+ ); +} diff --git a/apps/web/src/workspace/SearchView.tsx b/apps/web/src/workspace/SearchView.tsx new file mode 100644 index 0000000..81ea59c --- /dev/null +++ b/apps/web/src/workspace/SearchView.tsx @@ -0,0 +1,256 @@ +import { useMutation, useQuery } from '@tanstack/react-query'; +import { useEffect, useState } from 'react'; +import { useSearchParams } from 'react-router'; +import { NODE_TYPES, NODE_TYPE_LABELS, type NodeType } from '@vectora/graph-schema'; +import type { ExplorationAnswer } from '@vectora/shared'; +import { Notice, TypeMark, cx } from '@/components/ui'; +import { api } from '@/lib/api'; +import { useWorkspace } from '@/lib/store'; +import { useWs } from './context'; + +const EXAMPLES = [ + 'Explain authentication', + 'Identify circular dependencies', + 'Explain the application startup sequence', + 'Show the complete database access path', +]; + +export function SearchView() { + const { repo, graph, reveal, openView, settings } = useWs(); + const [params, setParams] = useSearchParams(); + const mode = params.get('mode') === 'questions' ? 'questions' : 'search'; + const [input, setInput] = useState(params.get('q') ?? ''); + const [query, setQuery] = useState(input.trim()); + const [types, setTypes] = useState([]); + const [question, setQuestion] = useState(''); + const setHighlight = useWorkspace((s) => s.setHighlight); + useEffect(() => { + const t = setTimeout(() => setQuery(input.trim()), 180); + return () => clearTimeout(t); + }, [input]); + const search = useQuery({ queryKey: ['search', repo.id, query, types.join(',')], queryFn: () => api.search(repo.id, query, types), enabled: mode === 'search' && query.length >= 2, placeholderData: (p) => p }); + const ask = useMutation({ mutationFn: (q: string) => api.ask(repo.id, q) }); + const answer: ExplorationAnswer | undefined = ask.data; + + const present = NODE_TYPES.filter((t) => (graph.stats.nodesByType[t] ?? 0) > 0 && t !== 'Repository'); + const open = (id: string) => { + reveal(id); + openView(settings.graph.defaultMode); + }; + const submit = (q: string) => { + const text = q.trim(); + if (text.length < 2) return; + setQuestion(text); + ask.mutate(text); + }; + + return ( +
+
+

Search

+
+ {( + [ + ['search', 'Find by name or path'], + ['questions', 'Ask about the repository'], + ] as const + ).map(([id, label]) => ( + + ))} +
+
+ + {mode === 'search' ? ( +
+
+ setInput(e.target.value)} + autoFocus + data-testid="search-input" + /> +
+ {present.map((t) => ( + + ))} +
+ {search.error ? ( +
+ {(search.error as Error).message} +
+ ) : null} + {query.length < 2 ? ( +

Type at least two characters. Exact names rank first, then prefixes, partial matches, paths and descriptions.

+ ) : search.data ? ( + <> +

+ {search.data.results.length} graph results{search.data.documents.length ? `, ${search.data.documents.length} documentation matches` : ''} for “{search.data.query}” +

+
    + {search.data.results.map((r) => ( +
  • + +
  • + ))} +
+ {search.data.results.length === 0 && search.data.documents.length === 0 ?

Nothing matches. Check the spelling, or search for part of a file path.

: null} + {search.data.documents.length ? ( + <> +

Documentation

+
    + {search.data.documents.map((d) => ( +
  • + +
  • + ))} +
+ + ) : null} + + ) : null} +
+
+ ) : ( +
+
+

+ Questions are answered from the knowledge graph. Every statement cites the file and line it comes from, and anything the graph cannot establish is listed separately. +

+
{ + e.preventDefault(); + submit(new FormData(e.currentTarget).get('question') as string); + }} + > + + +
+
+ {EXAMPLES.map((e) => ( + + ))} +
+ {ask.error ? ( +
+ {(ask.error as Error).message} +
+ ) : null} + {answer ? ( +
+

{question}

+
+

{answer.title}

+ {answer.nodeIds.length ? ( + + ) : null} +
+ {answer.narrative ? ( +
+

{answer.narrative}

+

Summary written by the optional narrative service at {answer.narrativeSource}. The evidence below comes from the graph.

+
+ ) : null} +
    + {answer.statements.map((s, i) => ( +
  1. +

    + {!s.verified ? derived : null} +

    + {s.evidence.length ? ( +

    + {s.evidence.slice(0, 4).map((ev, j) => ( + + ))} +

    + ) : null} +
  2. + ))} +
+ {answer.caveats.length ? ( +
+

Not established

+
    + {answer.caveats.map((c, i) => ( +
  • {c}
  • + ))} +
+
+ ) : null} +
+ ) : null} +
+
+ )} +
+ ); +} + +/** Renders `code` spans from statement text. The text is inserted as text nodes only. */ +function Formatted({ text }: { text: string }) { + const parts = text.split(/(`[^`]+`)/g); + return ( + <> + {parts.map((p, i) => + p.startsWith('`') && p.endsWith('`') ? ( + + {p.slice(1, -1)} + + ) : ( + {p} + ), + )} + + ); +} diff --git a/apps/web/src/workspace/SettingsView.tsx b/apps/web/src/workspace/SettingsView.tsx new file mode 100644 index 0000000..9f9662a --- /dev/null +++ b/apps/web/src/workspace/SettingsView.tsx @@ -0,0 +1,362 @@ +import { useQuery, useQueryClient } from '@tanstack/react-query'; +import { type ReactNode, useEffect, useState } from 'react'; +import { EDGE_TYPES, EDGE_TYPE_LABELS } from '@vectora/graph-schema'; +import { DEFAULT_IGNORE_PATTERNS, type Settings, formatBytes } from '@vectora/shared'; +import { Dialog, Loading, Notice, NumberField, SelectField, Toggle } from '@/components/ui'; +import { api, useHealth, useSettings } from '@/lib/api'; +import { useWorkspace } from '@/lib/store'; + +function Group({ title, intro, children }: { title: string; intro?: string; children: ReactNode }) { + const id = `settings-${title.toLowerCase().replace(/\s+/g, '-')}`; + return ( +
+
+

+ {title} +

+ {intro ?

{intro}

: null} +
+
{children}
+
+ ); +} + +export function SettingsView() { + const { settings, update, error } = useSettings(); + const health = useHealth(); + const qc = useQueryClient(); + const data = useQuery({ queryKey: ['data-info'], queryFn: api.dataInfo }); + const credentials = useQuery({ queryKey: ['credentials'], queryFn: api.credentials }); + const [ignoreText, setIgnoreText] = useState(null); + const [confirmDelete, setConfirmDelete] = useState(false); + const [message, setMessage] = useState(null); + const [endpoint, setEndpoint] = useState(null); + const [model, setModel] = useState(null); + useEffect(() => { + if (!message) return; + const t = setTimeout(() => setMessage(null), 4000); + return () => clearTimeout(t); + }, [message]); + if (!settings) return ; + + const set = (section: K, values: Partial) => update({ [section]: values } as Record>); + const hasCredential = (name: string) => credentials.data?.some((c) => c.name === name) ?? false; + const saveCredential = async (name: string, value: string) => { + await api.setCredential(name, value); + await qc.invalidateQueries({ queryKey: ['credentials'] }); + setMessage('Credential saved. It is stored encrypted on this machine and is never shown again.'); + }; + const removeCredential = async (name: string) => { + await api.deleteCredential(name); + await qc.invalidateQueries({ queryKey: ['credentials'] }); + setMessage('Credential removed.'); + }; + const toggleRelationship = (t: string) => { + const hidden = settings.graph.hiddenRelationships.includes(t) ? settings.graph.hiddenRelationships.filter((x) => x !== t) : [...settings.graph.hiddenRelationships, t]; + set('graph', { hiddenRelationships: hidden }); + // Apply to the open workspace as well, so the change is visible straight away. + const ws = useWorkspace.getState(); + if (ws.repoId) ws.setHiddenEdgeTypes(hidden.includes(t) ? [...new Set([...ws.hiddenEdgeTypes, t])] : ws.hiddenEdgeTypes.filter((x) => x !== t)); + }; + const ignoreValue = ignoreText ?? settings.repository.ignorePatterns.join('\n'); + + return ( +
+
+

Settings

+

Changes are saved as you make them and are kept by the local engine.

+
+ {error ? {(error as Error).message} : message ? {message} : null} +
+ + + set('appearance', { theme })} + options={[ + { value: 'light', label: 'Light' }, + { value: 'dark', label: 'Dark' }, + { value: 'system', label: 'Follow the system' }, + ]} + /> + + + + set('graph', { defaultMode })} + options={[ + { value: 'graph', label: 'Graph Explorer (2D)' }, + { value: 'atlas', label: '3D Atlas' }, + { value: 'mindmap', label: 'Mind Map' }, + ]} + /> + set('graph', { nodeDensity })} + options={[ + { value: 'structure', label: 'Structure' }, + { value: 'balanced', label: 'Balanced' }, + { value: 'full', label: 'Full' }, + ]} + /> + set('graph', { labelDensity })} + options={[ + { value: 'low', label: 'Few labels' }, + { value: 'medium', label: 'Medium' }, + { value: 'high', label: 'Many labels' }, + ]} + /> + set('graph', { animationIntensity })} + options={[ + { value: 'none', label: 'None' }, + { value: 'subtle', label: 'Subtle' }, + { value: 'standard', label: 'Standard' }, + ]} + /> + set('graph', { focusBehavior })} + options={[ + { value: 'neighbourhood', label: 'Move to the node, focus shows two steps' }, + { value: 'node', label: 'Move to the node, focus shows one step' }, + { value: 'none', label: 'Do not move the camera' }, + ]} + /> + set('graph', { showUnverified })} /> +
+ Relationship visibility +

Unchecked relationships are hidden by default in new workspaces and in the open one.

+
+ {EDGE_TYPES.map((t) => ( + + ))} +
+
+
+ + + set('performance', { workerConcurrency })} /> + set('performance', { indexingCache })} /> + set('performance', { renderingQuality })} + options={[ + { value: 'low', label: 'Low' }, + { value: 'balanced', label: 'Balanced' }, + { value: 'high', label: 'High' }, + ]} + /> + set('performance', { reducedMotion })} + options={[ + { value: 'system', label: 'Follow the system' }, + { value: 'on', label: 'Always reduce motion' }, + { value: 'off', label: 'Allow motion' }, + ]} + /> + set('performance', { maxFiles })} /> + set('performance', { maxGraphNodes })} /> + + + + + +

One pattern per line, in .gitignore syntax. Each repository's own .gitignore files are always respected as well.

+