diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4d650b9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "always" + }, + "eslint.useFlatConfig": true, + "eslint.validate": ["javascript", "typescript", "svelte"] +} diff --git a/README.md b/README.md index fd19403..510857f 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ **Open Network Diagram** is an **open-source, self-hosted tool** for creating **interactive network and infrastructure diagrams** using a **declarative JSON format**. ✅ **Fully self-hostable via Docker** -✅ **JSON-based network structure** (editable in UI or manually) +✅ **JSON-based network structure** (editable in UI or manually) ✅ **Interactive network visualisation** -✅ **Persistent storage of network configurations** +✅ **Simple file-based configuration** ✅ **Lightweight Svelte** Use it to **document your home lab, office network, or cloud infrastructure** with an easy-to-use web interface. @@ -25,20 +25,20 @@ Use it to **document your home lab, office network, or cloud infrastructure** wi Pull and run the latest image: ```bash -docker run -d -p 8080:3000 -v /path/to/data:/data jcreek23/open-network-diagram +docker run -d -p 8080:3000 jcreek23/open-network-diagram ``` - **`-p 8080:3000`** → Maps the app to `http://localhost:8080` -- **`-v /path/to/data:/data`** → Mounts a folder for persistent `network.json` storage ### **2️⃣ Open the Web UI** -Visit **`http://localhost:8080`** to view and edit your network diagram. +Visit **`http://localhost:8080`** to view your network diagram. ### **3️⃣ Modify Your Network (JSON-Based)** -- The app reads **`network.json`** from the **mounted `/data` directory**. -- Use the **web UI** to edit and save network changes. +- The app reads **`/data/network.json`** from static assets. +- In this repo, the default file is **`static/data/network.json`**. +- Update that file to change the diagram data. --- @@ -91,7 +91,7 @@ docker build -t open-network-diagram . ### **Run Locally** ```bash -docker run -p 8080:3000 -v /path/to/data:/data open-network-diagram +docker run -p 8080:3000 open-network-diagram ``` ### **CI/CD (GitHub Actions)** diff --git a/eslint.config.js b/eslint.config.js index 9b34ef5..3a02127 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,37 +1,89 @@ -import prettier from 'eslint-config-prettier'; -import js from '@eslint/js'; import { includeIgnoreFile } from '@eslint/compat'; +import { FlatCompat } from '@eslint/eslintrc'; +import js from '@eslint/js'; +import prettier from 'eslint-config-prettier'; +import importPlugin from 'eslint-plugin-import'; import svelte from 'eslint-plugin-svelte'; import globals from 'globals'; +import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import ts from 'typescript-eslint'; +import tseslint from 'typescript-eslint'; import svelteConfig from './svelte.config.js'; const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url)); +const baseDirectory = path.dirname(fileURLToPath(import.meta.url)); +const compat = new FlatCompat({ + baseDirectory, + recommendedConfig: js.configs.recommended +}); -export default ts.config( +const airbnbBaseConfig = compat.extends('airbnb-base').map((config) => ({ + ...config, + files: ['**/*.{js,cjs,mjs,ts,cts,mts}'] +})); + +export default tseslint.config( includeIgnoreFile(gitignorePath), - js.configs.recommended, - ...ts.configs.recommended, - ...svelte.configs.recommended, + { + ignores: ['eslint.config.js', 'svelte.config.js', 'vite.config.ts'] + }, + { + plugins: { + import: importPlugin + } + }, + ...airbnbBaseConfig, + ...tseslint.configs.recommended, + ...svelte.configs['flat/recommended'], prettier, - ...svelte.configs.prettier, + ...svelte.configs['flat/prettier'], { languageOptions: { globals: { ...globals.browser, ...globals.node } }, - rules: { 'no-undef': 'off' } + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.mjs', '.cjs', '.ts', '.d.ts', '.svelte', '.json'] + } + }, + 'import/extensions': ['.js', '.ts', '.mjs', '.svelte'] + }, + rules: { + curly: ['error', 'all'], + 'brace-style': ['error', '1tbs', { allowSingleLine: false }], + 'no-continue': 'off', + 'no-restricted-syntax': 'off', + 'no-inner-declarations': 'off', + 'no-unused-vars': 'off', + 'import/no-extraneous-dependencies': 'off', + '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + 'import/extensions': [ + 'error', + 'ignorePackages', + { + js: 'never', + mjs: 'never', + cjs: 'never', + ts: 'never' + } + ] + } }, { files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'], - ignores: ['eslint.config.js', 'svelte.config.js'], languageOptions: { parserOptions: { projectService: true, extraFileExtensions: ['.svelte'], - parser: ts.parser, + parser: tseslint.parser, svelteConfig } + }, + rules: { + // Svelte components commonly export mutable props and top-level declarations. + 'import/prefer-default-export': 'off', + 'import/no-mutable-exports': 'off' } } ); diff --git a/package.json b/package.json index 4470f25..0d9979f 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ }, "devDependencies": { "@eslint/compat": "^1.2.5", - "@eslint/js": "^9.18.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "^8.57.1", "@sveltejs/adapter-auto": "^4.0.0", "@sveltejs/adapter-netlify": "^5.0.0", "@sveltejs/kit": "^2.16.0", @@ -23,17 +24,19 @@ "@tailwindcss/typography": "^0.5.15", "@tailwindcss/vite": "^4.0.0", "@types/cytoscape-dagre": "^2.3.3", - "eslint": "^9.18.0", - "eslint-config-prettier": "^10.0.1", + "eslint": "^8.57.1", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-svelte": "^3.0.0", "globals": "^16.0.0", - "prettier": "^3.4.2", + "prettier": "^3.8.1", "prettier-plugin-svelte": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.11", "svelte": "^5.0.0", "svelte-check": "^4.0.0", "tailwindcss": "^4.0.0", - "typescript": "^5.0.0", + "typescript": "^5.9.3", "typescript-eslint": "^8.20.0", "vite": "^6.2.5" }, @@ -44,6 +47,7 @@ }, "packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0", "dependencies": { - "leader-line": "^1.0.8" + "cytoscape": "^3.31.2", + "cytoscape-dagre": "^2.5.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5b4c05f..b9ef4af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,16 +8,22 @@ importers: .: dependencies: - leader-line: - specifier: ^1.0.8 - version: 1.0.8 + cytoscape: + specifier: ^3.31.2 + version: 3.33.1 + cytoscape-dagre: + specifier: ^2.5.0 + version: 2.5.0(cytoscape@3.33.1) devDependencies: '@eslint/compat': specifier: ^1.2.5 - version: 1.2.8(eslint@9.24.0(jiti@2.4.2)) + version: 1.2.8(eslint@8.57.1) + '@eslint/eslintrc': + specifier: ^3.3.1 + version: 3.3.1 '@eslint/js': - specifier: ^9.18.0 - version: 9.24.0 + specifier: ^8.57.1 + version: 8.57.1 '@sveltejs/adapter-auto': specifier: ^4.0.0 version: 4.0.0(@sveltejs/kit@2.20.4(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.25.8)(vite@6.2.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.25.8)(vite@6.2.5(jiti@2.4.2)(lightningcss@1.29.2))) @@ -40,41 +46,47 @@ importers: specifier: ^2.3.3 version: 2.3.3 eslint: - specifier: ^9.18.0 - version: 9.24.0(jiti@2.4.2) + specifier: ^8.57.1 + version: 8.57.1 + eslint-config-airbnb-base: + specifier: ^15.0.0 + version: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) eslint-config-prettier: - specifier: ^10.0.1 - version: 10.1.1(eslint@9.24.0(jiti@2.4.2)) + specifier: ^10.1.8 + version: 10.1.8(eslint@8.57.1) + eslint-plugin-import: + specifier: ^2.32.0 + version: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) eslint-plugin-svelte: specifier: ^3.0.0 - version: 3.5.1(eslint@9.24.0(jiti@2.4.2))(svelte@5.25.8) + version: 3.5.1(eslint@8.57.1)(svelte@5.25.8) globals: specifier: ^16.0.0 version: 16.0.0 prettier: - specifier: ^3.4.2 - version: 3.5.3 + specifier: ^3.8.1 + version: 3.8.1 prettier-plugin-svelte: specifier: ^3.3.3 - version: 3.3.3(prettier@3.5.3)(svelte@5.25.8) + version: 3.3.3(prettier@3.8.1)(svelte@5.25.8) prettier-plugin-tailwindcss: specifier: ^0.6.11 - version: 0.6.11(prettier-plugin-svelte@3.3.3(prettier@3.5.3)(svelte@5.25.8))(prettier@3.5.3) + version: 0.6.11(prettier-plugin-svelte@3.3.3(prettier@3.8.1)(svelte@5.25.8))(prettier@3.8.1) svelte: specifier: ^5.0.0 version: 5.25.8 svelte-check: specifier: ^4.0.0 - version: 4.1.5(svelte@5.25.8)(typescript@5.8.3) + version: 4.1.5(svelte@5.25.8)(typescript@5.9.3) tailwindcss: specifier: ^4.0.0 version: 4.1.3 typescript: - specifier: ^5.0.0 - version: 5.8.3 + specifier: ^5.9.3 + version: 5.9.3 typescript-eslint: specifier: ^8.20.0 - version: 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + version: 8.29.1(eslint@8.57.1)(typescript@5.9.3) vite: specifier: ^6.2.5 version: 6.2.5(jiti@2.4.2)(lightningcss@1.29.2) @@ -404,57 +416,30 @@ packages: eslint: optional: true - '@eslint/config-array@0.20.0': - resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.2.1': - resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.12.0': - resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.13.0': - resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.24.0': - resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.2.8': - resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - - '@humanwhocodes/retry@0.4.2': - resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} - engines: {node: '>=18.18'} + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead '@iarna/toml@2.2.5': resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} @@ -592,6 +577,9 @@ packages: cpu: [x64] os: [win32] + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@sveltejs/acorn-typescript@1.0.5': resolution: {integrity: sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==} peerDependencies: @@ -726,8 +714,8 @@ packages: '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} '@typescript-eslint/eslint-plugin@8.29.1': resolution: {integrity: sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==} @@ -776,6 +764,9 @@ packages: resolution: {integrity: sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -789,6 +780,10 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -800,6 +795,38 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -817,6 +844,18 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -843,6 +882,9 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confusing-browser-globals@1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} @@ -856,6 +898,38 @@ packages: engines: {node: '>=4'} hasBin: true + cytoscape-dagre@2.5.0: + resolution: {integrity: sha512-VG2Knemmshop4kh5fpLO27rYcyUaaDkRw+6PiX4bstpB+QFt0p2oauMrsjVbUamGWQ6YNavh7x2em2uZlzV44g==} + peerDependencies: + cytoscape: ^3.2.22 + + cytoscape@3.33.1: + resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} + engines: {node: '>=0.10'} + + dagre@0.8.5: + resolution: {integrity: sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -872,6 +946,14 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + detect-libc@2.0.3: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} @@ -879,10 +961,50 @@ packages: devalue@5.1.1: resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + enhanced-resolve@5.18.1: resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} engines: {node: '>=10.13.0'} + es-abstract@1.24.1: + resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + esbuild@0.24.2: resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} engines: {node: '>=18'} @@ -897,12 +1019,53 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-prettier@10.1.1: - resolution: {integrity: sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==} + eslint-config-airbnb-base@15.0.0: + resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.2 + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} hasBin: true peerDependencies: eslint: '>=7.0.0' + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint-plugin-svelte@3.5.1: resolution: {integrity: sha512-Qn1slddZHfqYiDO6IN8/iN3YL+VuHlgYjm30FT+hh0Jf/TX0jeZMTJXQMajFm5f6f6hURi+XO8P+NPYD+T4jkg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -913,6 +1076,10 @@ packages: svelte: optional: true + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.3.0: resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -925,15 +1092,11 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.24.0: - resolution: {integrity: sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true esm-env@1.2.2: resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} @@ -942,6 +1105,10 @@ packages: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -985,9 +1152,9 @@ packages: picomatch: optional: true - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} @@ -997,18 +1164,51 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1017,6 +1217,14 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -1025,16 +1233,50 @@ packages: resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==} engines: {node: '>=18'} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphlib@2.1.8: + resolution: {integrity: sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1050,21 +1292,127 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1085,6 +1433,10 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1095,9 +1447,6 @@ packages: known-css-properties@0.35.0: resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==} - leader-line@1.0.8: - resolution: {integrity: sha512-3TOYtjjcYJCdtEs+bCuVSj6GvFiAzywtjifeeVcBYVwejHfI8a/NRxU4s6DjXB+H/ccNA/qtZEjrFVw9W97dCQ==} - levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1186,9 +1535,16 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1204,6 +1560,9 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -1223,10 +1582,45 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -1243,10 +1637,17 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1254,6 +1655,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + postcss-load-config@3.1.4: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -1355,8 +1760,8 @@ packages: prettier-plugin-svelte: optional: true - prettier@3.5.3: - resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} hasBin: true @@ -1371,14 +1776,32 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + rollup@4.39.0: resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -1391,6 +1814,22 @@ packages: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + semver@7.7.1: resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} engines: {node: '>=10'} @@ -1399,6 +1838,18 @@ packages: set-cookie-parser@2.7.1: resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1407,6 +1858,22 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + sirv@3.0.1: resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} engines: {node: '>=18'} @@ -1415,6 +1882,30 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -1423,6 +1914,10 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + svelte-check@4.1.5: resolution: {integrity: sha512-Gb0T2IqBNe1tLB9EB1Qh+LOe+JB8wt2/rNBDGvkxQVvk8vNeAoG+vZgFB/3P5+zC7RWlyBlzm9dVjZFph/maIg==} engines: {node: '>= 18.0.0'} @@ -1451,6 +1946,9 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -1465,10 +1963,33 @@ packages: peerDependencies: typescript: '>=4.8.4' + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + typescript-eslint@8.29.1: resolution: {integrity: sha512-f8cDkvndhbQMPcysk6CUSGBWV+g1utqdn71P5YKwMumVMOG/5k7cHq0KyG4O52nB0oKS4aN2Tp5+wB4APJGC+w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1476,11 +1997,15 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -1535,6 +2060,22 @@ packages: vite: optional: true + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1544,6 +2085,9 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} @@ -1712,35 +2256,31 @@ snapshots: '@esbuild/win32-x64@0.25.2': optional: true - '@eslint-community/eslint-utils@4.5.1(eslint@9.24.0(jiti@2.4.2))': + '@eslint-community/eslint-utils@4.5.1(eslint@8.57.1)': dependencies: - eslint: 9.24.0(jiti@2.4.2) + eslint: 8.57.1 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/compat@1.2.8(eslint@9.24.0(jiti@2.4.2))': + '@eslint/compat@1.2.8(eslint@8.57.1)': optionalDependencies: - eslint: 9.24.0(jiti@2.4.2) + eslint: 8.57.1 - '@eslint/config-array@0.20.0': + '@eslint/eslintrc@2.1.4': dependencies: - '@eslint/object-schema': 2.1.6 + ajv: 6.12.6 debug: 4.4.0 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 minimatch: 3.1.2 + strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.2.1': {} - - '@eslint/core@0.12.0': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/core@0.13.0': - dependencies: - '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 @@ -1755,27 +2295,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.24.0': {} + '@eslint/js@8.57.1': {} - '@eslint/object-schema@2.1.6': {} - - '@eslint/plugin-kit@0.2.8': + '@humanwhocodes/config-array@0.13.0': dependencies: - '@eslint/core': 0.13.0 - levn: 0.4.1 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.2': {} + '@humanwhocodes/object-schema@2.0.3': {} '@iarna/toml@2.2.5': {} @@ -1870,6 +2402,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.39.0': optional: true + '@rtsao/scc@1.1.0': {} + '@sveltejs/acorn-typescript@1.0.5(acorn@8.14.1)': dependencies: acorn: 8.14.1 @@ -2004,34 +2538,34 @@ snapshots: '@types/estree@1.0.7': {} - '@types/json-schema@7.0.15': {} + '@types/json5@0.0.29': {} - '@typescript-eslint/eslint-plugin@8.29.1(@typescript-eslint/parser@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.29.1(@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.29.1(eslint@8.57.1)(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.29.1 - '@typescript-eslint/type-utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/type-utils': 8.29.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 8.29.1(eslint@8.57.1)(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.29.1 - eslint: 9.24.0(jiti@2.4.2) + eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.29.1 '@typescript-eslint/types': 8.29.1 - '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.29.1 debug: 4.4.0 - eslint: 9.24.0(jiti@2.4.2) - typescript: 5.8.3 + eslint: 8.57.1 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -2040,20 +2574,20 @@ snapshots: '@typescript-eslint/types': 8.29.1 '@typescript-eslint/visitor-keys': 8.29.1 - '@typescript-eslint/type-utils@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.29.1(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.29.1(eslint@8.57.1)(typescript@5.9.3) debug: 4.4.0 - eslint: 9.24.0(jiti@2.4.2) - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + eslint: 8.57.1 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color '@typescript-eslint/types@8.29.1': {} - '@typescript-eslint/typescript-estree@8.29.1(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.29.1(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.29.1 '@typescript-eslint/visitor-keys': 8.29.1 @@ -2062,19 +2596,19 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.1 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.29.1(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) '@typescript-eslint/scope-manager': 8.29.1 '@typescript-eslint/types': 8.29.1 - '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.8.3) - eslint: 9.24.0(jiti@2.4.2) - typescript: 5.8.3 + '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.9.3) + eslint: 8.57.1 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -2083,6 +2617,8 @@ snapshots: '@typescript-eslint/types': 8.29.1 eslint-visitor-keys: 4.2.0 + '@ungap/structured-clone@1.3.0': {} + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -2096,6 +2632,8 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-regex@5.0.1: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -2104,6 +2642,62 @@ snapshots: aria-query@5.3.2: {} + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + async-function@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + axobject-query@4.1.0: {} balanced-match@1.0.2: {} @@ -2121,6 +2715,23 @@ snapshots: dependencies: fill-range: 7.1.1 + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} chalk@4.1.2: @@ -2142,6 +2753,8 @@ snapshots: concat-map@0.0.1: {} + confusing-browser-globals@1.0.11: {} + cookie@0.6.0: {} cross-spawn@7.0.6: @@ -2152,6 +2765,40 @@ snapshots: cssesc@3.0.0: {} + cytoscape-dagre@2.5.0(cytoscape@3.33.1): + dependencies: + cytoscape: 3.33.1 + dagre: 0.8.5 + + cytoscape@3.33.1: {} + + dagre@0.8.5: + dependencies: + graphlib: 2.1.8 + lodash: 4.17.23 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + debug@4.4.0: dependencies: ms: 2.1.3 @@ -2160,15 +2807,123 @@ snapshots: deepmerge@4.3.1: {} + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + detect-libc@2.0.3: {} devalue@5.1.1: {} + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + enhanced-resolve@5.18.1: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 + es-abstract@1.24.1: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + esbuild@0.24.2: optionalDependencies: '@esbuild/aix-ppc64': 0.24.2 @@ -2227,15 +2982,71 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.1(eslint@9.24.0(jiti@2.4.2)): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1): dependencies: - eslint: 9.24.0(jiti@2.4.2) + confusing-browser-globals: 1.0.11 + eslint: 8.57.1 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + object.assign: 4.1.7 + object.entries: 1.1.9 + semver: 6.3.1 - eslint-plugin-svelte@3.5.1(eslint@9.24.0(jiti@2.4.2))(svelte@5.25.8): + eslint-config-prettier@10.1.8(eslint@8.57.1): dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0(jiti@2.4.2)) + eslint: 8.57.1 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.29.1(eslint@8.57.1)(typescript@5.9.3) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.29.1(eslint@8.57.1)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-svelte@3.5.1(eslint@8.57.1)(svelte@5.25.8): + dependencies: + '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) '@jridgewell/sourcemap-codec': 1.5.0 - eslint: 9.24.0(jiti@2.4.2) + eslint: 8.57.1 esutils: 2.0.3 known-css-properties: 0.35.0 postcss: 8.5.3 @@ -2248,6 +3059,11 @@ snapshots: transitivePeerDependencies: - ts-node + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-scope@8.3.0: dependencies: esrecurse: 4.3.0 @@ -2257,45 +3073,46 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.24.0(jiti@2.4.2): + eslint@8.57.1: dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.20.0 - '@eslint/config-helpers': 0.2.1 - '@eslint/core': 0.12.0 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.24.0 - '@eslint/plugin-kit': 0.2.8 - '@humanfs/node': 0.16.6 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.2 - '@types/estree': 1.0.7 - '@types/json-schema': 7.0.15 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.0 + doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 + file-entry-cache: 6.0.1 find-up: 5.0.0 glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 - optionalDependencies: - jiti: 2.4.2 + strip-ansi: 6.0.1 + text-table: 0.2.0 transitivePeerDependencies: - supports-color @@ -2307,6 +3124,12 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 4.2.0 + espree@9.6.1: + dependencies: + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + eslint-visitor-keys: 3.4.3 + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -2343,9 +3166,9 @@ snapshots: fdir@6.4.3: {} - file-entry-cache@8.0.0: + file-entry-cache@6.0.1: dependencies: - flat-cache: 4.0.1 + flat-cache: 3.2.0 fill-range@7.1.1: dependencies: @@ -2356,16 +3179,62 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - flat-cache@4.0.1: + flat-cache@3.2.0: dependencies: flatted: 3.3.3 keyv: 4.5.4 + rimraf: 3.0.2 flatted@3.3.3: {} + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -2374,16 +3243,60 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + globals@14.0.0: {} globals@16.0.0: {} + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + graceful-fs@4.2.11: {} graphemer@1.4.0: {} + graphlib@2.1.8: + dependencies: + lodash: 4.17.23 + + has-bigints@1.1.0: {} + has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + ignore@5.3.2: {} import-fresh@3.3.1: @@ -2395,18 +3308,135 @@ snapshots: imurmurhash@0.1.4: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-extglob@2.1.1: {} + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-number@7.0.0: {} + is-path-inside@3.0.3: {} + is-reference@3.0.3: dependencies: '@types/estree': 1.0.7 + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + isexe@2.0.0: {} jiti@2.4.2: {} @@ -2421,6 +3451,10 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json5@1.0.2: + dependencies: + minimist: 1.2.8 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -2429,8 +3463,6 @@ snapshots: known-css-properties@0.35.0: {} - leader-line@1.0.8: {} - levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -2495,10 +3527,14 @@ snapshots: lodash.merge@4.6.2: {} + lodash@4.17.23: {} + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + math-intrinsics@1.1.0: {} + merge2@1.4.1: {} micromatch@4.0.8: @@ -2514,6 +3550,8 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimist@1.2.8: {} + mri@1.2.0: {} mrmime@2.0.1: {} @@ -2524,6 +3562,50 @@ snapshots: natural-compare@1.4.0: {} + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -2533,6 +3615,12 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -2547,12 +3635,18 @@ snapshots: path-exists@4.0.0: {} + path-is-absolute@1.0.1: {} + path-key@3.1.1: {} + path-parse@1.0.7: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} + possible-typed-array-names@1.1.0: {} + postcss-load-config@3.1.4(postcss@8.5.3): dependencies: lilconfig: 2.1.0 @@ -2586,18 +3680,18 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-svelte@3.3.3(prettier@3.5.3)(svelte@5.25.8): + prettier-plugin-svelte@3.3.3(prettier@3.8.1)(svelte@5.25.8): dependencies: - prettier: 3.5.3 + prettier: 3.8.1 svelte: 5.25.8 - prettier-plugin-tailwindcss@0.6.11(prettier-plugin-svelte@3.3.3(prettier@3.5.3)(svelte@5.25.8))(prettier@3.5.3): + prettier-plugin-tailwindcss@0.6.11(prettier-plugin-svelte@3.3.3(prettier@3.8.1)(svelte@5.25.8))(prettier@3.8.1): dependencies: - prettier: 3.5.3 + prettier: 3.8.1 optionalDependencies: - prettier-plugin-svelte: 3.3.3(prettier@3.5.3)(svelte@5.25.8) + prettier-plugin-svelte: 3.3.3(prettier@3.8.1)(svelte@5.25.8) - prettier@3.5.3: {} + prettier@3.8.1: {} punycode@2.3.1: {} @@ -2605,10 +3699,40 @@ snapshots: readdirp@4.1.2: {} + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + resolve-from@4.0.0: {} + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + reusify@1.1.0: {} + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + rollup@4.39.0: dependencies: '@types/estree': 1.0.7 @@ -2643,16 +3767,87 @@ snapshots: dependencies: mri: 1.2.0 + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + semver@6.3.1: {} + semver@7.7.1: {} set-cookie-parser@2.7.1: {} + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + sirv@3.0.1: dependencies: '@polka/url': 1.0.0-next.28 @@ -2661,13 +3856,49 @@ snapshots: source-map-js@1.2.1: {} + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + strip-json-comments@3.1.1: {} supports-color@7.2.0: dependencies: has-flag: 4.0.0 - svelte-check@4.1.5(svelte@5.25.8)(typescript@5.8.3): + supports-preserve-symlinks-flag@1.0.0: {} + + svelte-check@4.1.5(svelte@5.25.8)(typescript@5.9.3): dependencies: '@jridgewell/trace-mapping': 0.3.25 chokidar: 4.0.3 @@ -2675,7 +3906,7 @@ snapshots: picocolors: 1.1.1 sade: 1.8.1 svelte: 5.25.8 - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - picomatch @@ -2711,31 +3942,82 @@ snapshots: tapable@2.2.1: {} + text-table@0.2.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 totalist@3.0.1: {} - ts-api-utils@2.1.0(typescript@5.8.3): + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: - typescript: 5.8.3 + typescript: 5.9.3 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3): + type-fest@0.20.2: {} + + typed-array-buffer@1.0.3: dependencies: - '@typescript-eslint/eslint-plugin': 8.29.1(@typescript-eslint/parser@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.24.0(jiti@2.4.2) - typescript: 5.8.3 + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript-eslint@8.29.1(eslint@8.57.1)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.29.1(@typescript-eslint/parser@8.29.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.29.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 8.29.1(eslint@8.57.1)(typescript@5.9.3) + eslint: 8.57.1 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - typescript@5.8.3: {} + typescript@5.9.3: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 uri-js@4.4.1: dependencies: @@ -2757,12 +4039,55 @@ snapshots: optionalDependencies: vite: 6.2.5(jiti@2.4.2)(lightningcss@1.29.2) + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + which@2.0.2: dependencies: isexe: 2.0.0 word-wrap@1.2.5: {} + wrappy@1.0.2: {} + yaml@1.10.2: {} yocto-queue@0.1.0: {} diff --git a/src/app.html b/src/app.html index 2b8d838..77a5ff5 100644 --- a/src/app.html +++ b/src/app.html @@ -5,7 +5,6 @@ %sveltekit.head% -
%sveltekit.body%
diff --git a/src/lib/components/DeviceCard.svelte b/src/lib/components/DeviceCard.svelte deleted file mode 100644 index 41acc23..0000000 --- a/src/lib/components/DeviceCard.svelte +++ /dev/null @@ -1,46 +0,0 @@ - - -
-

{device.name}

-

Type: {device.type}

-

IP: {device.ipAddress}

- {#if device.notes} -

{device.notes}

- {/if} - - {#if device.ports && device.ports.length} -

Ports:

-
- {#each device.ports as port} -
-

{port.portName} ({port.speedGbps ?? 1}GbE)

- {#if port.connectedTo} -

Connected to: {port.connectedTo}

- {/if} -
- {/each} -
- {/if} -
- - diff --git a/src/lib/components/MachineCard.svelte b/src/lib/components/MachineCard.svelte deleted file mode 100644 index 1fbaf07..0000000 --- a/src/lib/components/MachineCard.svelte +++ /dev/null @@ -1,59 +0,0 @@ - - -
-

{machine.machineName}

-

Role: {machine.role}

-

IP Address: {machine.ipAddress}

-

OS: {machine.operatingSystem}

- - {#if machine.ports && machine.ports.length} -

Ports:

-
- {#each machine.ports as port} -
-

{port.portName} ({port.speedGbps ?? 1}GbE)

- {#if port.connectedTo} -

Connected to: {port.connectedTo}

- {/if} -
- {/each} -
- {/if} - - - {#if machine.software?.vms?.length} -
- Show VMs (Total: {machine.software.vms.length}) -
- {#each machine.software.vms as vm} - - {/each} -
-
- {/if} -
- - diff --git a/src/lib/components/Modal.svelte b/src/lib/components/Modal.svelte new file mode 100644 index 0000000..187178f --- /dev/null +++ b/src/lib/components/Modal.svelte @@ -0,0 +1,120 @@ + + + + +{#if isOpen} + + + +{/if} + + diff --git a/src/lib/components/NetworkDiagram.svelte b/src/lib/components/NetworkDiagram.svelte index 681097c..82bbd40 100644 --- a/src/lib/components/NetworkDiagram.svelte +++ b/src/lib/components/NetworkDiagram.svelte @@ -1,224 +1,1469 @@ -
- {#if data} -
- +
+
+ +
+ + + + + + +
+
Source: {dataSourceLabel}
+ {#if isLoadingData} +
Loading JSON...
+ {/if} + {#if loadError} +
{loadError}
+ {/if} + + {#if tooltip.visible} +
+ {tooltip.text} +
+ {/if} +
+ + {#if warnings.length > 0} +
+ Data warnings ({warnings.length}) +
    + {#each warnings as warning (warning)} +
  • {warning}
  • {/each} - - {#each data.machines as machine} - - {/each} - {#each data.devices as device} - - {/each} +
+
+ {/if} +
+ + + {#if selectedDetails?.type === 'machine'} + + +
+

IP: {selectedDetails.ip}

+

Role: {selectedDetails.role}

+

OS: {selectedDetails.os}

+

CPU: {selectedDetails.cpu}

+

RAM: {selectedDetails.ram}

+ {#if selectedDetails.gpu} +

GPU: {selectedDetails.gpu}

+ {/if} +
+ +

Ports

+
    + {#if selectedDetails.ports.length === 0} +
  • None
  • + {:else} + {#each selectedDetails.ports as port (port.portName)} +
  • + {port.portName} ({port.speedGbps ?? 1}GbE): {formatConnection( + port.connectedTo + )} +
  • + {/each} + {/if} +
+ +

Virtual Machines ({selectedDetails.vmCount})

+
    + {#if selectedDetails.vms.length === 0} +
  • None
  • + {:else} + {#each selectedDetails.vms as vm (`${vm.name}:${vm.ip}`)} +
  • + {vm.name} ({vm.role}) - {vm.ip} +
  • + {/each} + {/if} +
+ {:else if selectedDetails?.type === 'device'} +
+

Type: {selectedDetails.deviceType}

+

IP: {selectedDetails.ip}

+ {#if selectedDetails.notes} +

Notes: {selectedDetails.notes}

+ {/if} +
+ +

Ports

+
    + {#if selectedDetails.ports.length === 0} +
  • None
  • + {:else} + {#each selectedDetails.ports as port (port.portName)} +
  • + {port.portName} ({port.speedGbps ?? 1}GbE): {formatConnection( + port.connectedTo + )} +
  • + {/each} + {/if} +
+ {:else if selectedDetails?.type === 'vm'} +
+

Role: {selectedDetails.role}

+

IP: {selectedDetails.ip}

+

Host: {selectedDetails.hostName}

{/if} -
+ diff --git a/src/lib/components/VMCard.svelte b/src/lib/components/VMCard.svelte deleted file mode 100644 index acf7e13..0000000 --- a/src/lib/components/VMCard.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - -
-

{vm.name}

-

Role: {vm.role}

-

IP: {vm.ipAddress}

-
- - diff --git a/src/lib/data/loadNetworkData.ts b/src/lib/data/loadNetworkData.ts new file mode 100644 index 0000000..b5be388 --- /dev/null +++ b/src/lib/data/loadNetworkData.ts @@ -0,0 +1,37 @@ +import type { NetworkData } from '../types'; + +function isNetworkData(value: unknown): value is NetworkData { + if (!value || typeof value !== 'object') { + return false; + } + + const candidate = value as Partial; + return Array.isArray(candidate.machines) && Array.isArray(candidate.devices); +} + +export default async function loadNetworkData(jsonPath: string): Promise { + const response = await fetch(jsonPath, { + headers: { + Accept: 'application/json' + } + }); + + if (!response.ok) { + throw new Error(`Failed to load ${jsonPath} (${response.status} ${response.statusText})`); + } + + let rawData: unknown; + try { + rawData = await response.json(); + } catch (error) { + throw new Error(`Failed to parse JSON at ${jsonPath}`, { + cause: error + }); + } + + if (!isNetworkData(rawData)) { + throw new Error(`JSON at ${jsonPath} is not valid network data`); + } + + return rawData; +} diff --git a/src/lib/graph/transformNetworkData.ts b/src/lib/graph/transformNetworkData.ts new file mode 100644 index 0000000..c3781b7 --- /dev/null +++ b/src/lib/graph/transformNetworkData.ts @@ -0,0 +1,298 @@ +import type { ConnectedPortRef, NetworkData, Port } from '../types'; +import type { GraphEdgeElement, GraphNodeElement, GraphTransformResult } from './types'; + +interface EndpointOwner { + kind: 'machine' | 'device'; + nodeId: string; + name: string; + ports: Map; +} + +function toOwnerKey(kind: EndpointOwner['kind'], name: string): string { + return `${kind}:${name}`; +} + +function toMachineNodeId(name: string): string { + return `machine:${encodeURIComponent(name)}`; +} + +function toDeviceNodeId(name: string): string { + return `device:${encodeURIComponent(name)}`; +} + +function toVmNodeId(hostName: string, vmName: string): string { + return `vm:${encodeURIComponent(hostName)}:${encodeURIComponent(vmName)}`; +} + +function parseConnectedTo(connection: Port['connectedTo']): ConnectedPortRef | null { + if (!connection?.device || !connection?.port) { + return null; + } + return { + device: connection.device.trim(), + port: connection.port.trim() + }; +} + +function hasReciprocalLink( + targetPort: Port | undefined, + expectedDeviceName: string, + expectedPortName: string +): boolean { + const reverse = parseConnectedTo(targetPort?.connectedTo); + if (!reverse) { + return false; + } + return reverse.device === expectedDeviceName && reverse.port === expectedPortName; +} + +function connectionKey(a: string, b: string): string { + return a < b ? `${a}|${b}` : `${b}|${a}`; +} + +function edgeSpeed(a: number | undefined, b: number | undefined): number | undefined { + if (typeof a === 'number' && typeof b === 'number') { + return Math.min(a, b); + } + if (typeof a === 'number') { + return a; + } + if (typeof b === 'number') { + return b; + } + return undefined; +} + +export default function transformNetworkDataToGraph(data: NetworkData): GraphTransformResult { + const nodes: GraphNodeElement[] = []; + const edges: GraphEdgeElement[] = []; + const warnings: string[] = []; + const machineVmIndex: Record< + string, + { + vmNodeIds: string[]; + hostingEdgeIds: string[]; + vmCount: number; + } + > = {}; + const ownersByKey = new Map(); + const seenWarnings = new Set(); + + const warn = (message: string) => { + if (!seenWarnings.has(message)) { + seenWarnings.add(message); + warnings.push(message); + } + }; + + const addOwner = (owner: EndpointOwner) => { + const ownerKey = toOwnerKey(owner.kind, owner.name); + if (ownersByKey.has(ownerKey)) { + warn( + `Duplicate ${owner.kind} name "${owner.name}" found. First occurrence will be used for link resolution.` + ); + return; + } + ownersByKey.set(ownerKey, owner); + }; + + let hostingEdgeCounter = 0; + + for (const machine of data.machines) { + const machineNodeId = toMachineNodeId(machine.machineName); + const machinePortsList = [...(machine.ports ?? [])]; + const sourceMachineVms = machine.software?.vms ?? []; + const machineVms = sourceMachineVms.map((vm) => ({ + name: vm.name, + ip: vm.ipAddress, + role: vm.role + })); + + nodes.push({ + data: { + id: machineNodeId, + label: machine.machineName, + rawName: machine.machineName, + kind: 'machine', + nodeWidth: 200, + nodeHeight: 110, + details: { + type: 'machine', + name: machine.machineName, + ip: machine.ipAddress, + role: machine.role, + os: machine.operatingSystem, + cpu: machine.hardware?.cpu ?? 'Unknown', + ram: machine.hardware?.ram ?? 'Unknown', + gpu: machine.hardware?.gpu ?? undefined, + ports: machinePortsList, + vmCount: machineVms.length, + vms: machineVms + } + } + }); + + machineVmIndex[machineNodeId] = { + vmNodeIds: [], + hostingEdgeIds: [], + vmCount: sourceMachineVms.length + }; + + for (const vm of sourceMachineVms) { + const vmNodeId = toVmNodeId(machine.machineName, vm.name); + + nodes.push({ + data: { + id: vmNodeId, + label: vm.name, + rawName: vm.name, + kind: 'vm', + hostMachineId: machineNodeId, + nodeWidth: 140, + nodeHeight: 66, + details: { + type: 'vm', + name: vm.name, + ip: vm.ipAddress, + role: vm.role, + hostName: machine.machineName + } + } + }); + + hostingEdgeCounter += 1; + const hostingEdgeId = `hosting:${hostingEdgeCounter}`; + edges.push({ + data: { + id: hostingEdgeId, + source: machineNodeId, + target: vmNodeId, + kind: 'hosting', + label: 'hosts' + } + }); + + machineVmIndex[machineNodeId].vmNodeIds.push(vmNodeId); + machineVmIndex[machineNodeId].hostingEdgeIds.push(hostingEdgeId); + } + + const machinePorts = new Map(); + for (const port of machine.ports ?? []) { + machinePorts.set(port.portName, port); + } + + addOwner({ + kind: 'machine', + nodeId: machineNodeId, + name: machine.machineName, + ports: machinePorts + }); + } + + for (const device of data.devices) { + const deviceNodeId = toDeviceNodeId(device.name); + const devicePorts = [...(device.ports ?? [])]; + + nodes.push({ + data: { + id: deviceNodeId, + label: device.name, + rawName: device.name, + kind: 'device', + nodeWidth: 176, + nodeHeight: 116, + details: { + type: 'device', + name: device.name, + ip: device.ipAddress, + deviceType: device.type, + notes: device.notes, + ports: devicePorts + } + } + }); + + const devicePortMap = new Map(); + for (const port of device.ports ?? []) { + devicePortMap.set(port.portName, port); + } + + addOwner({ + kind: 'device', + nodeId: deviceNodeId, + name: device.name, + ports: devicePortMap + }); + } + + const seenPhysicalConnections = new Set(); + let physicalEdgeCounter = 0; + + for (const owner of ownersByKey.values()) { + for (const port of owner.ports.values()) { + const connectedTo = parseConnectedTo(port.connectedTo); + if (!connectedTo) { + continue; + } + + const machineTargetOwner = ownersByKey.get(toOwnerKey('machine', connectedTo.device)); + const deviceTargetOwner = ownersByKey.get(toOwnerKey('device', connectedTo.device)); + if (machineTargetOwner && deviceTargetOwner) { + warn( + `Link from "${owner.name}:${port.portName}" references ambiguous device "${connectedTo.device}" (matches both machine and device names).` + ); + continue; + } + + const targetOwner = machineTargetOwner ?? deviceTargetOwner; + if (!targetOwner) { + warn( + `Link from "${owner.name}:${port.portName}" references unknown device "${connectedTo.device}".` + ); + continue; + } + + const targetPort = targetOwner.ports.get(connectedTo.port); + if (!targetPort) { + warn( + `Link from "${owner.name}:${port.portName}" references unknown port "${connectedTo.device}:${connectedTo.port}".` + ); + continue; + } + + const a = `${owner.nodeId}:${port.portName}`; + const b = `${targetOwner.nodeId}:${connectedTo.port}`; + const dedupeKey = connectionKey(a, b); + if (seenPhysicalConnections.has(dedupeKey)) { + continue; + } + seenPhysicalConnections.add(dedupeKey); + + const reciprocal = hasReciprocalLink(targetPort, owner.name, port.portName); + if (!reciprocal) { + warn( + `Non-reciprocal link: "${owner.name}:${port.portName}" points to "${connectedTo.device}:${connectedTo.port}" but reverse link is missing.` + ); + } + + physicalEdgeCounter += 1; + const speedGbps = edgeSpeed(port.speedGbps, targetPort.speedGbps); + + edges.push({ + data: { + id: `physical:${physicalEdgeCounter}`, + source: owner.nodeId, + target: targetOwner.nodeId, + kind: 'physical', + label: speedGbps ? `${speedGbps}GbE` : undefined, + sourcePort: port.portName, + targetPort: connectedTo.port, + speedGbps, + reciprocal + } + }); + } + } + + return { nodes, edges, warnings, machineVmIndex }; +} diff --git a/src/lib/graph/types.ts b/src/lib/graph/types.ts new file mode 100644 index 0000000..e80324e --- /dev/null +++ b/src/lib/graph/types.ts @@ -0,0 +1,93 @@ +export type GraphNodeKind = 'machine' | 'device' | 'vm'; +export type GraphEdgeKind = 'physical' | 'hosting'; + +export interface PortDetails { + portName: string; + speedGbps?: number; + connectedTo?: { + device: string; + port: string; + }; +} + +export interface MachineDetails { + type: 'machine'; + name: string; + ip: string; + role: string; + os: string; + cpu: string; + ram: string; + gpu?: string; + ports: PortDetails[]; + vmCount: number; + vms: Array<{ + name: string; + ip: string; + role: string; + }>; +} + +export interface DeviceDetails { + type: 'device'; + name: string; + ip: string; + deviceType: string; + notes?: string; + ports: PortDetails[]; +} + +export interface VmDetails { + type: 'vm'; + name: string; + ip: string; + role: string; + hostName: string; +} + +export type GraphNodeDetails = MachineDetails | DeviceDetails | VmDetails; + +export interface GraphNodeData { + id: string; + label: string; + kind: GraphNodeKind; + rawName?: string; + hostMachineId?: string; + nodeWidth?: number; + nodeHeight?: number; + details?: GraphNodeDetails; +} + +export interface GraphEdgeData { + id: string; + source: string; + target: string; + kind: GraphEdgeKind; + label?: string; + sourcePort?: string; + targetPort?: string; + speedGbps?: number; + reciprocal?: boolean; +} + +export interface GraphNodeElement { + data: GraphNodeData; +} + +export interface GraphEdgeElement { + data: GraphEdgeData; +} + +export interface GraphTransformResult { + nodes: GraphNodeElement[]; + edges: GraphEdgeElement[]; + warnings: string[]; + machineVmIndex: Record< + string, + { + vmNodeIds: string[]; + hostingEdgeIds: string[]; + vmCount: number; + } + >; +} diff --git a/src/lib/types.ts b/src/lib/types.ts index 09afe25..2fb4293 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1,7 +1,12 @@ +export interface ConnectedPortRef { + device: string; + port: string; +} + export interface Port { portName: string; speedGbps?: number; // default to 1 if not provided - connectedTo?: string; // e.g. "Router-LAN2" + connectedTo?: ConnectedPortRef; } export interface Hardware { diff --git a/src/lib/utils/pathfinding.ts b/src/lib/utils/pathfinding.ts deleted file mode 100644 index abcd80d..0000000 --- a/src/lib/utils/pathfinding.ts +++ /dev/null @@ -1,62 +0,0 @@ -// Simple grid-based A* pathfinding for orthogonal routing -// Returns a list of [x, y] points from start to end, or [] if no path found - -export type Point = [number, number]; - -interface Node { - x: number; - y: number; - g: number; - h: number; - f: number; - parent?: Node; -} - -export function astar(grid: number[][], start: Point, end: Point): Point[] { - const height = grid.length; - const width = grid[0].length; - const open: Node[] = []; - const closed: boolean[][] = Array.from({ length: height }, () => Array(width).fill(false)); - - function heuristic([x, y]: Point): number { - // Manhattan distance - return Math.abs(x - end[0]) + Math.abs(y - end[1]); - } - - open.push({ x: start[0], y: start[1], g: 0, h: heuristic(start), f: heuristic(start) }); - - while (open.length > 0) { - // Get node with lowest f - open.sort((a, b) => a.f - b.f); - const current = open.shift()!; - if (current.x === end[0] && current.y === end[1]) { - // Reconstruct path - const path: Point[] = []; - let node: Node | undefined = current; - while (node) { - path.push([node.x, node.y]); - node = node.parent; - } - return path.reverse(); - } - closed[current.y][current.x] = true; - // Explore neighbors (orthogonal only) - for (const [dx, dy] of [[1,0], [-1,0], [0,1], [0,-1]]) { - const nx = current.x + dx; - const ny = current.y + dy; - if (nx < 0 || ny < 0 || nx >= width || ny >= height) continue; - if (grid[ny][nx] === 1 || closed[ny][nx]) continue; // Obstacle or closed - const g = current.g + 1; - const h = heuristic([nx, ny]); - const existing = open.find(n => n.x === nx && n.y === ny); - if (!existing) { - open.push({ x: nx, y: ny, g, h, f: g + h, parent: current }); - } else if (g < existing.g) { - existing.g = g; - existing.f = g + h; - existing.parent = current; - } - } - } - return []; -} diff --git a/src/stores/networkStore.ts b/src/stores/networkStore.ts deleted file mode 100644 index 2e3b361..0000000 --- a/src/stores/networkStore.ts +++ /dev/null @@ -1,270 +0,0 @@ -import { writable } from 'svelte/store'; -import type { NetworkData } from '../lib/types'; - -// Create a writable store for the data -export const networkStore = writable({ - machines: [], - devices: [] -}); - -// A function to load JSON from an API or local file if needed -export async function loadNetworkData(jsonPath: string) { - // For a real app, fetch the file or do an import: - // const response = await fetch(jsonPath); - // const data = await response.json(); - // networkStore.set(data); - - // For now, set a static example with 'ports' and sample connections: - const exampleData: NetworkData = { - machines: [ - { - machineName: 'ProxRouter', - ipAddress: '10.0.0.3', - role: 'Hypervisor', - operatingSystem: 'Proxmox', - ports: [ - { - portName: 'eth0', - speedGbps: 10, - // Connect to the router's LAN2 - connectedTo: 'Router-LAN2' - }, - { - portName: 'eth1', - speedGbps: 1 - // Not connected - } - ], - software: { - vms: [ - { name: 'OpnSense', role: 'Router', ipAddress: '10.0.0.4' }, - { name: 'PiVPN', role: 'VPN Server', ipAddress: '10.0.0.5' }, - { name: 'PiHole', role: 'DNS Ad-blocker', ipAddress: '10.0.0.6' }, - { name: 'Dashy', role: 'Dashboard', ipAddress: '10.0.0.12' }, - { name: 'DockerHost', role: 'Docker/Reverse Proxy', ipAddress: '10.0.0.23' } - ] - }, - hardware: { - cpu: 'Intel N100', - ram: '8GB', - networkPorts: 4, - networkPortSpeedGbps: 1, - gpu: null - } - }, - { - machineName: 'Asustor NAS', - ipAddress: '10.0.0.9', - role: 'NAS', - operatingSystem: 'Asustor ADM', - ports: [ - { - portName: 'eth0', - speedGbps: 1 - // No connection - } - ], - software: { vms: [] }, - hardware: { - cpu: 'Realtek RTD1296 Quad Core 1.4GHz', - ram: '2GB', - networkPorts: 1, - networkPortSpeedGbps: 1, - gpu: null - } - }, - { - machineName: 'Home Assistant Green', - ipAddress: '10.0.0.13', - role: 'Smart Home Controller', - operatingSystem: 'Home Assistant OS', - ports: [ - { - portName: 'eth0', - speedGbps: 1 - // Not connected - } - ], - software: { vms: [] }, - hardware: { - cpu: 'Home Assistant Custom SoC', - ram: 'Unknown', - networkPorts: 1, - networkPortSpeedGbps: 1, - gpu: null - } - }, - { - machineName: 'Plex Server', - ipAddress: '10.0.0.11', - role: 'Media Server', - operatingSystem: 'Ubuntu Server', - ports: [ - { - portName: 'eth0', - speedGbps: 1 - // Not connected - } - ], - software: { vms: [] }, - hardware: { - cpu: 'Intel N100', - ram: 'Unknown', - networkPorts: 1, - networkPortSpeedGbps: 1, - gpu: null - } - }, - { - machineName: 'Win11 N100', - ipAddress: '10.0.0.8', - role: 'Media Downloader', - operatingSystem: 'Windows 11', - ports: [ - { - portName: 'eth0', - speedGbps: 1 - // Not connected - } - ], - software: { vms: [] }, - hardware: { - cpu: 'Intel N100', - ram: 'Unknown', - networkPorts: 1, - networkPortSpeedGbps: 1, - gpu: null - } - }, - { - machineName: 'Win11 Backblaze NAS', - ipAddress: '10.0.0.7', - role: 'Backup NAS + Hypervisor', - operatingSystem: 'TrueNAS Scale', - ports: [ - { - portName: 'eth0', - speedGbps: 1 - // Not connected - } - ], - software: { - vms: [ - { name: 'Win11-Backblaze', role: 'Backblaze Backup', ipAddress: '10.0.0.24' }, - { name: 'UbuntuDockerHost', role: 'Docker Host', ipAddress: '10.0.0.14' }, - { name: 'MakeMKV', role: 'Blu-ray Ripper', ipAddress: '10.0.0.14' }, - { name: 'Handbrake', role: 'Video Transcoder', ipAddress: '10.0.0.15' }, - { name: 'NextCloud', role: 'Cloud Storage', ipAddress: 'TBD' } - ] - }, - hardware: { - cpu: 'AMD Ryzen 5 4600G', - ram: '16GB', - networkPorts: 1, - networkPortSpeedGbps: 1, - gpu: 'EVGA GeForce GTX 1050 Ti' - } - }, - { - machineName: 'AI Server', - ipAddress: '10.0.0.20', - role: 'AI Dev/Inference', - operatingSystem: 'Pop!_OS', - ports: [ - { - portName: 'eth0', - speedGbps: 10 - // Not connected - } - ], - software: { - vms: [ - { name: 'Ollama', role: 'LLM Inference', ipAddress: '10.0.0.21' }, - { name: 'Bot Training', role: 'AI Training', ipAddress: '10.0.0.22' } - ] - }, - hardware: { - cpu: 'AMD Ryzen 5 3600', - ram: '32GB', - networkPorts: 1, - networkPortSpeedGbps: 1, - gpu: 'Gigabyte GeForce GTX 1080' - } - } - ], - devices: [ - { - name: 'Router', - ipAddress: '10.0.0.1', - type: 'Gateway', - notes: 'Main internet-facing router', - ports: [ - { - portName: 'LAN1', - speedGbps: 1, - // Connect to Omada Controller - connectedTo: 'Omada Controller-eth0' - }, - { - portName: 'LAN2', - speedGbps: 10, - // Connected to ProxRouter - connectedTo: 'ProxRouter-eth0' - }, - { - portName: 'LAN3', - speedGbps: 1, - // Connect to HDHomeRun - connectedTo: 'HDHomeRun-eth0' - } - ] - }, - { - name: 'HDHomeRun', - ipAddress: '10.0.0.2', - type: 'TV Tuner', - ports: [ - { - portName: 'eth0', - speedGbps: 1, - connectedTo: 'Router-LAN3' - } - ] - }, - { - name: 'Omada Controller', - ipAddress: '10.0.0.4', - type: 'Network Controller', - notes: 'Access via port 8043', - ports: [ - { - portName: 'eth0', - speedGbps: 1, - connectedTo: 'Router-LAN1' - } - ] - }, - { - name: '3DS', - ipAddress: '10.0.0.17', - type: 'Handheld Console' - // No ports => Wi-Fi only - }, - { - name: '2DS', - ipAddress: '10.0.0.18', - type: 'Handheld Console' - // No ports => Wi-Fi only - }, - { - name: 'Nintendo Switch', - ipAddress: '10.0.0.19', - type: 'Gaming Console', - notes: 'IP to be confirmed' - // No ports => Wi-Fi only - } - ] - }; - - networkStore.set(exampleData); -} diff --git a/static/data/network.json b/static/data/network.json new file mode 100644 index 0000000..a6a6f8c --- /dev/null +++ b/static/data/network.json @@ -0,0 +1,494 @@ +{ + "machines": [ + { + "machineName": "ProxRouter", + "ipAddress": "10.0.0.3", + "role": "Hypervisor", + "operatingSystem": "Proxmox", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "1" + } + }, + { + "portName": "eth1", + "speedGbps": 1 + }, + { + "portName": "eth2", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "2" + } + }, + { + "portName": "eth3", + "speedGbps": 1, + "connectedTo": { + "device": "WAN Uplink", + "port": "wan" + } + } + ], + "software": { + "vms": [ + { + "name": "OpnSense", + "role": "Router/Firewall/Gateway (DHCP 10.0.0.100-254)", + "ipAddress": "10.0.0.1" + }, + { + "name": "TPLink Omada Controller", + "role": "Network Controller (:8043)", + "ipAddress": "10.0.0.4" + }, + { "name": "PiVPN (WireGuard)", "role": "VPN Server", "ipAddress": "10.0.0.5" }, + { + "name": "PiHole", + "role": "DNS Ad-blocker (installed, not in active use)", + "ipAddress": "10.0.0.6" + }, + { "name": "Dashy", "role": "Dashboard", "ipAddress": "10.0.0.12" }, + { + "name": "ProxRouter-Docker", + "role": "Docker host (Nginx reverse proxy, RustDesk, TwinGate)", + "ipAddress": "10.0.0.23" + } + ] + }, + "hardware": { + "cpu": "Intel N100", + "ram": "8GB", + "networkPorts": 4, + "networkPortSpeedGbps": 1 + } + }, + { + "machineName": "Asustor NAS", + "ipAddress": "10.0.0.9", + "role": "NAS", + "operatingSystem": "Asustor ADM", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "3" + } + } + ], + "software": { "vms": [] }, + "hardware": { + "cpu": "Realtek RTD1296 Quad Core 1.4GHz", + "ram": "2GB", + "networkPorts": 1, + "networkPortSpeedGbps": 1 + } + }, + { + "machineName": "Home Assistant Green", + "ipAddress": "10.0.0.13", + "role": "Smart Home Controller", + "operatingSystem": "Home Assistant OS", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "4" + } + } + ], + "software": { "vms": [] }, + "hardware": { + "cpu": "Home Assistant Custom SoC", + "ram": "Unknown", + "networkPorts": 1, + "networkPortSpeedGbps": 1 + } + }, + { + "machineName": "Plex Server", + "ipAddress": "10.0.0.11", + "role": "Media Server", + "operatingSystem": "Ubuntu Server", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "5" + } + } + ], + "software": { "vms": [] }, + "hardware": { + "cpu": "Intel N100", + "ram": "Unknown", + "networkPorts": 1, + "networkPortSpeedGbps": 1 + } + }, + { + "machineName": "Win11 N100", + "ipAddress": "10.0.0.8", + "role": "Media Downloader", + "operatingSystem": "Windows 11", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "6" + } + } + ], + "software": { "vms": [] }, + "hardware": { + "cpu": "Intel N100", + "ram": "Unknown", + "networkPorts": 1, + "networkPortSpeedGbps": 1 + } + }, + { + "machineName": "Win11 Backblaze NAS", + "ipAddress": "10.0.0.7", + "role": "Backup NAS + Hypervisor", + "operatingSystem": "TrueNAS Scale", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "7" + } + } + ], + "software": { + "vms": [ + { "name": "Win11NAS", "role": "Backblaze Backup VM", "ipAddress": "10.0.0.24" }, + { "name": "MakeMKV", "role": "Blu-ray Ripper", "ipAddress": "10.0.0.14" }, + { "name": "Handbrake", "role": "Video Transcoder", "ipAddress": "10.0.0.15" } + ] + }, + "hardware": { + "cpu": "AMD Ryzen 5 4600G", + "ram": "16GB", + "networkPorts": 1, + "networkPortSpeedGbps": 1, + "gpu": "EVGA GeForce GTX 1050 Ti" + } + }, + { + "machineName": "TrueNAS Host", + "ipAddress": "10.0.0.10", + "role": "Storage + VM Host", + "operatingSystem": "TrueNAS Scale", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "8" + } + } + ], + "software": { + "vms": [ + { + "name": "TrueNAS-Docker", + "role": "Docker host on TrueNAS", + "ipAddress": "10.0.0.25" + } + ] + }, + "hardware": { + "cpu": "Unknown", + "ram": "Unknown", + "networkPorts": 1, + "networkPortSpeedGbps": 1 + } + }, + { + "machineName": "AI Server", + "ipAddress": "10.0.0.20", + "role": "AI Dev/Inference", + "operatingSystem": "Pop!_OS", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "9" + } + } + ], + "software": { + "vms": [ + { "name": "Ollama", "role": "LLM Inference", "ipAddress": "10.0.0.21" }, + { "name": "Bot Training", "role": "AI Training", "ipAddress": "10.0.0.22" } + ] + }, + "hardware": { + "cpu": "AMD Ryzen 5 3600", + "ram": "32GB", + "networkPorts": 1, + "networkPortSpeedGbps": 1, + "gpu": "Gigabyte GeForce GTX 1080" + } + }, + { + "machineName": "Immich Mini PC", + "ipAddress": "10.0.0.30", + "role": "Photo Server", + "operatingSystem": "Linux", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "10" + } + } + ], + "software": { "vms": [] }, + "hardware": { + "cpu": "Unknown", + "ram": "Unknown", + "networkPorts": 1, + "networkPortSpeedGbps": 1 + } + } + ], + "devices": [ + { + "name": "Gigabit Switch", + "ipAddress": "unknown", + "type": "Network Switch", + "notes": "Main 24-port switch. Wireless access point uplinks through this switch.", + "ports": [ + { + "portName": "1", + "speedGbps": 1, + "connectedTo": { + "device": "ProxRouter", + "port": "eth0" + } + }, + { + "portName": "2", + "speedGbps": 1, + "connectedTo": { + "device": "ProxRouter", + "port": "eth2" + } + }, + { + "portName": "3", + "speedGbps": 1, + "connectedTo": { + "device": "Asustor NAS", + "port": "eth0" + } + }, + { + "portName": "4", + "speedGbps": 1, + "connectedTo": { + "device": "Home Assistant Green", + "port": "eth0" + } + }, + { + "portName": "5", + "speedGbps": 1, + "connectedTo": { + "device": "Plex Server", + "port": "eth0" + } + }, + { + "portName": "6", + "speedGbps": 1, + "connectedTo": { + "device": "Win11 N100", + "port": "eth0" + } + }, + { + "portName": "7", + "speedGbps": 1, + "connectedTo": { + "device": "Win11 Backblaze NAS", + "port": "eth0" + } + }, + { + "portName": "8", + "speedGbps": 1, + "connectedTo": { + "device": "TrueNAS Host", + "port": "eth0" + } + }, + { + "portName": "9", + "speedGbps": 1, + "connectedTo": { + "device": "AI Server", + "port": "eth0" + } + }, + { + "portName": "10", + "speedGbps": 1, + "connectedTo": { + "device": "Immich Mini PC", + "port": "eth0" + } + }, + { + "portName": "11", + "speedGbps": 1, + "connectedTo": { + "device": "HDHomeRun", + "port": "eth0" + } + }, + { + "portName": "12", + "speedGbps": 1 + }, + { + "portName": "13", + "speedGbps": 1 + }, + { + "portName": "14", + "speedGbps": 1 + }, + { + "portName": "15", + "speedGbps": 1 + }, + { + "portName": "16", + "speedGbps": 1 + }, + { + "portName": "17", + "speedGbps": 1 + }, + { + "portName": "18", + "speedGbps": 1 + }, + { + "portName": "19", + "speedGbps": 1 + }, + { + "portName": "20", + "speedGbps": 1 + }, + { + "portName": "21", + "speedGbps": 1 + }, + { + "portName": "22", + "speedGbps": 1 + }, + { + "portName": "23", + "speedGbps": 1 + }, + { + "portName": "24", + "speedGbps": 1 + } + ] + }, + { + "name": "WAN Uplink", + "ipAddress": "unknown", + "type": "ISP/WAN", + "notes": "Upstream internet link (modem/ONT/ISP path).", + "ports": [ + { + "portName": "wan", + "speedGbps": 1, + "connectedTo": { + "device": "ProxRouter", + "port": "eth3" + } + } + ] + }, + { + "name": "HDHomeRun", + "ipAddress": "10.0.0.2", + "type": "TV Tuner", + "ports": [ + { + "portName": "eth0", + "speedGbps": 1, + "connectedTo": { + "device": "Gigabit Switch", + "port": "11" + } + } + ] + }, + { + "name": "3DS", + "ipAddress": "10.0.0.17", + "type": "Handheld Console", + "notes": "Wi-Fi only." + }, + { + "name": "2DS", + "ipAddress": "10.0.0.18", + "type": "Handheld Console", + "notes": "Wi-Fi only." + }, + { + "name": "Nintendo Switch", + "ipAddress": "10.0.0.19", + "type": "Gaming Console", + "notes": "Wi-Fi only." + }, + { + "name": "NanoKVM Lite", + "ipAddress": "10.0.0.26", + "type": "KVM Device", + "notes": "Port link not yet modeled." + }, + { + "name": "UPS Pi", + "ipAddress": "10.0.0.27", + "type": "Power Monitoring Device", + "notes": "Port link not yet modeled." + }, + { + "name": "Waveshare", + "ipAddress": "10.0.0.28", + "type": "Peripheral Device", + "notes": "Port link not yet modeled." + } + ] +}