From 8689cda38845e77c9116b161baac4cb4883ce9c9 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:09:48 -0400 Subject: [PATCH 01/15] chore: add dev deps for new layout engines (FA2, d3-hierarchy, webcola, cytoscape) --- package.json | 7 +- pnpm-lock.yaml | 4596 +++++++++++++++++++++++------------------------- 2 files changed, 2249 insertions(+), 2354 deletions(-) diff --git a/package.json b/package.json index 3e6642c..b45db9a 100644 --- a/package.json +++ b/package.json @@ -80,20 +80,24 @@ "@dagrejs/dagre": "^3.0.0", "@dagrejs/graphlib": "^4.0.1", "@hpcc-js/wasm-graphviz": "^1.22.0", + "@types/cytoscape": "^3.31.0", "@types/d3-array": "^3.2.2", "@types/d3-force": "^3.0.10", + "@types/d3-hierarchy": "^3.1.7", "@types/node": "^25.0.3", "@vitest/coverage-v8": "^4.0.18", "@xyflow/system": "^0.0.75", "bumpp": "^10.3.2", - "cytoscape": "^3.33.1", + "cytoscape": "^3.34.0", "d3-array": "^3.2.4", "d3-force": "^3.0.0", + "d3-hierarchy": "^3.1.2", "dotparser": "^1.1.1", "elkjs": "^0.11.1", "fast-xml-parser": "^5.3.4", "graphology": "^0.26.0", "graphology-components": "^1.5.4", + "graphology-layout-forceatlas2": "^0.10.1", "graphology-metrics": "^2.4.0", "graphology-shortest-path": "^2.1.0", "graphology-types": "^0.24.8", @@ -104,6 +108,7 @@ "tsx": "^4.21.0", "typescript": "^5.9.3", "vitest": "^4.0.16", + "webcola": "^3.4.0", "xstate": "^5.28.0", "zod": "^4.3.6" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e2515cb..07c0017 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,2332 +1,1377 @@ -lockfileVersion: '9.0' +lockfileVersion: '6.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -importers: - - .: - devDependencies: - '@changesets/changelog-github': - specifier: ^0.5.2 - version: 0.5.2 - '@changesets/cli': - specifier: ^2.29.8 - version: 2.29.8(@types/node@25.2.1) - '@dagrejs/dagre': - specifier: ^3.0.0 - version: 3.0.0 - '@dagrejs/graphlib': - specifier: ^4.0.1 - version: 4.0.1 - '@hpcc-js/wasm-graphviz': - specifier: ^1.22.0 - version: 1.22.0 - '@types/d3-array': - specifier: ^3.2.2 - version: 3.2.2 - '@types/d3-force': - specifier: ^3.0.10 - version: 3.0.10 - '@types/node': - specifier: ^25.0.3 - version: 25.2.1 - '@vitest/coverage-v8': - specifier: ^4.0.18 - version: 4.0.18(vitest@4.0.18(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) - '@xyflow/system': - specifier: ^0.0.75 - version: 0.0.75 - bumpp: - specifier: ^10.3.2 - version: 10.4.1(magicast@0.5.3) - cytoscape: - specifier: ^3.33.1 - version: 3.33.1 - d3-array: - specifier: ^3.2.4 - version: 3.2.4 - d3-force: - specifier: ^3.0.0 - version: 3.0.0 - dotparser: - specifier: ^1.1.1 - version: 1.1.1 - elkjs: - specifier: ^0.11.1 - version: 0.11.1 - fast-xml-parser: - specifier: ^5.3.4 - version: 5.3.4 - graphology: - specifier: ^0.26.0 - version: 0.26.0(graphology-types@0.24.8) - graphology-components: - specifier: ^1.5.4 - version: 1.5.4(graphology-types@0.24.8) - graphology-metrics: - specifier: ^2.4.0 - version: 2.4.0(graphology-types@0.24.8) - graphology-shortest-path: - specifier: ^2.1.0 - version: 2.1.0(graphology-types@0.24.8) - graphology-types: - specifier: ^0.24.8 - version: 0.24.8 - ngraph.graph: - specifier: ^20.1.2 - version: 20.1.2 - ngraph.path: - specifier: ^1.6.1 - version: 1.6.1 - publint: - specifier: ^0.3.15 - version: 0.3.18 - tsdown: - specifier: ^0.18.1 - version: 0.18.4(publint@0.3.18)(typescript@5.9.3) - tsx: - specifier: ^4.21.0 - version: 4.21.0 - typescript: - specifier: ^5.9.3 - version: 5.9.3 - vitest: - specifier: ^4.0.16 - version: 4.0.18(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) - xstate: - specifier: ^5.28.0 - version: 5.28.0 - zod: - specifier: ^4.3.6 - version: 4.3.6 +devDependencies: + '@changesets/changelog-github': + specifier: ^0.5.2 + version: 0.5.2 + '@changesets/cli': + specifier: ^2.29.8 + version: 2.31.0(@types/node@25.9.3) + '@dagrejs/dagre': + specifier: ^3.0.0 + version: 3.0.0 + '@dagrejs/graphlib': + specifier: ^4.0.1 + version: 4.0.1 + '@hpcc-js/wasm-graphviz': + specifier: ^1.22.0 + version: 1.22.0 + '@types/cytoscape': + specifier: ^3.31.0 + version: 3.31.0 + '@types/d3-array': + specifier: ^3.2.2 + version: 3.2.2 + '@types/d3-force': + specifier: ^3.0.10 + version: 3.0.10 + '@types/d3-hierarchy': + specifier: ^3.1.7 + version: 3.1.7 + '@types/node': + specifier: ^25.0.3 + version: 25.9.3 + '@vitest/coverage-v8': + specifier: ^4.0.18 + version: 4.1.8(vitest@4.1.8) + '@xyflow/system': + specifier: ^0.0.75 + version: 0.0.75 + bumpp: + specifier: ^10.3.2 + version: 10.4.1 + cytoscape: + specifier: ^3.34.0 + version: 3.34.0 + d3-array: + specifier: ^3.2.4 + version: 3.2.4 + d3-force: + specifier: ^3.0.0 + version: 3.0.0 + d3-hierarchy: + specifier: ^3.1.2 + version: 3.1.2 + dotparser: + specifier: ^1.1.1 + version: 1.1.1 + elkjs: + specifier: ^0.11.1 + version: 0.11.1 + fast-xml-parser: + specifier: ^5.3.4 + version: 5.8.0 + graphology: + specifier: ^0.26.0 + version: 0.26.0(graphology-types@0.24.8) + graphology-components: + specifier: ^1.5.4 + version: 1.5.4(graphology-types@0.24.8) + graphology-layout-forceatlas2: + specifier: ^0.10.1 + version: 0.10.1(graphology-types@0.24.8) + graphology-metrics: + specifier: ^2.4.0 + version: 2.4.0(graphology-types@0.24.8) + graphology-shortest-path: + specifier: ^2.1.0 + version: 2.1.0(graphology-types@0.24.8) + graphology-types: + specifier: ^0.24.8 + version: 0.24.8 + ngraph.graph: + specifier: ^20.1.2 + version: 20.1.2 + ngraph.path: + specifier: ^1.6.1 + version: 1.6.1 + publint: + specifier: ^0.3.15 + version: 0.3.21 + tsdown: + specifier: ^0.18.1 + version: 0.18.4(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)(publint@0.3.21)(typescript@5.9.3) + tsx: + specifier: ^4.21.0 + version: 4.22.4 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vitest: + specifier: ^4.0.16 + version: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16) + webcola: + specifier: ^3.4.0 + version: 3.4.0 + xstate: + specifier: ^5.28.0 + version: 5.32.0 + zod: + specifier: ^4.3.6 + version: 4.4.3 packages: - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + /@babel/generator@7.29.7: + resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==, tarball: https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz} engines: {node: '>=6.9.0'} + dependencies: + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + dev: true - '@babel/helper-string-parser@7.29.7': + /@babel/helper-string-parser@7.29.7: resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==, tarball: https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz} engines: {node: '>=6.9.0'} + dev: true - '@babel/helper-validator-identifier@7.29.7': + /@babel/helper-validator-identifier@7.29.7: resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==, tarball: https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz} engines: {node: '>=6.9.0'} + dev: true - '@babel/parser@7.29.7': + /@babel/parser@7.29.7: resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==, tarball: https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz} engines: {node: '>=6.0.0'} hasBin: true + dependencies: + '@babel/types': 7.29.7 + dev: true - '@babel/runtime@7.28.6': - resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + /@babel/runtime@7.29.7: + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==, tarball: https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz} engines: {node: '>=6.9.0'} + dev: true - '@babel/types@7.29.7': + /@babel/types@7.29.7: resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==, tarball: https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz} engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + dev: true - '@bcoe/v8-coverage@1.0.2': + /@bcoe/v8-coverage@1.0.2: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==, tarball: https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz} engines: {node: '>=18'} + dev: true - '@changesets/apply-release-plan@7.0.14': - resolution: {integrity: sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==} + /@changesets/apply-release-plan@7.1.1: + resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==, tarball: https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.1.1.tgz} + dependencies: + '@changesets/config': 3.1.4 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.8.4 + dev: true - '@changesets/assemble-release-plan@6.0.9': - resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} + /@changesets/assemble-release-plan@6.0.10: + resolution: {integrity: sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==, tarball: https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.10.tgz} + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.8.4 + dev: true - '@changesets/changelog-git@0.2.1': - resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + /@changesets/changelog-git@0.2.1: + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==, tarball: https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz} + dependencies: + '@changesets/types': 6.1.0 + dev: true - '@changesets/changelog-github@0.5.2': - resolution: {integrity: sha512-HeGeDl8HaIGj9fQHo/tv5XKQ2SNEi9+9yl1Bss1jttPqeiASRXhfi0A2wv8yFKCp07kR1gpOI5ge6+CWNm1jPw==} + /@changesets/changelog-github@0.5.2: + resolution: {integrity: sha512-HeGeDl8HaIGj9fQHo/tv5XKQ2SNEi9+9yl1Bss1jttPqeiASRXhfi0A2wv8yFKCp07kR1gpOI5ge6+CWNm1jPw==, tarball: https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.5.2.tgz} + dependencies: + '@changesets/get-github-info': 0.7.0 + '@changesets/types': 6.1.0 + dotenv: 8.6.0 + transitivePeerDependencies: + - encoding + dev: true - '@changesets/cli@2.29.8': - resolution: {integrity: sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==} + /@changesets/cli@2.31.0(@types/node@25.9.3): + resolution: {integrity: sha512-AhI4enNTgHu2IZr6K4WZyf0EPch4XVMn1yOMFmCD9gsfBGqMYaHXls5HyDv6/CL5axVQABz68eG30eCtbr2wFg==, tarball: https://registry.npmjs.org/@changesets/cli/-/cli-2.31.0.tgz} hasBin: true + dependencies: + '@changesets/apply-release-plan': 7.1.1 + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.4 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/get-release-plan': 4.0.16 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@25.9.3) + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.8.4 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' + dev: true - '@changesets/config@3.1.2': - resolution: {integrity: sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==} + /@changesets/config@3.1.4: + resolution: {integrity: sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==, tarball: https://registry.npmjs.org/@changesets/config/-/config-3.1.4.tgz} + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + dev: true - '@changesets/errors@0.2.0': - resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + /@changesets/errors@0.2.0: + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==, tarball: https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz} + dependencies: + extendable-error: 0.1.7 + dev: true - '@changesets/get-dependents-graph@2.1.3': - resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} + /@changesets/get-dependents-graph@2.1.4: + resolution: {integrity: sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==, tarball: https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.4.tgz} + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.8.4 + dev: true - '@changesets/get-github-info@0.7.0': - resolution: {integrity: sha512-+i67Bmhfj9V4KfDeS1+Tz3iF32btKZB2AAx+cYMqDSRFP7r3/ZdGbjCo+c6qkyViN9ygDuBjzageuPGJtKGe5A==} + /@changesets/get-github-info@0.7.0: + resolution: {integrity: sha512-+i67Bmhfj9V4KfDeS1+Tz3iF32btKZB2AAx+cYMqDSRFP7r3/ZdGbjCo+c6qkyViN9ygDuBjzageuPGJtKGe5A==, tarball: https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.7.0.tgz} + dependencies: + dataloader: 1.4.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: true - '@changesets/get-release-plan@4.0.14': - resolution: {integrity: sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==} + /@changesets/get-release-plan@4.0.16: + resolution: {integrity: sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==, tarball: https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.16.tgz} + dependencies: + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/config': 3.1.4 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + dev: true - '@changesets/get-version-range-type@0.4.0': - resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + /@changesets/get-version-range-type@0.4.0: + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==, tarball: https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz} + dev: true - '@changesets/git@3.0.4': - resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + /@changesets/git@3.0.4: + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==, tarball: https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz} + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + dev: true - '@changesets/logger@0.1.1': - resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + /@changesets/logger@0.1.1: + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==, tarball: https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz} + dependencies: + picocolors: 1.1.1 + dev: true - '@changesets/parse@0.4.2': - resolution: {integrity: sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==} + /@changesets/parse@0.4.3: + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==, tarball: https://registry.npmjs.org/@changesets/parse/-/parse-0.4.3.tgz} + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.2.0 + dev: true - '@changesets/pre@2.0.2': - resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + /@changesets/pre@2.0.2: + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==, tarball: https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz} + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + dev: true - '@changesets/read@0.6.6': - resolution: {integrity: sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==} + /@changesets/read@0.6.7: + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==, tarball: https://registry.npmjs.org/@changesets/read/-/read-0.6.7.tgz} + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.3 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + dev: true - '@changesets/should-skip-package@0.1.2': - resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + /@changesets/should-skip-package@0.1.2: + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==, tarball: https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz} + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + dev: true - '@changesets/types@4.1.0': - resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + /@changesets/types@4.1.0: + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==, tarball: https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz} + dev: true - '@changesets/types@6.1.0': - resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + /@changesets/types@6.1.0: + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==, tarball: https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz} + dev: true - '@changesets/write@0.4.0': - resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + /@changesets/write@0.4.0: + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==, tarball: https://registry.npmjs.org/@changesets/write/-/write-0.4.0.tgz} + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.2.0 + prettier: 2.8.8 + dev: true - '@dagrejs/dagre@3.0.0': + /@dagrejs/dagre@3.0.0: resolution: {integrity: sha512-ZzhnTy1rfuoew9Ez3EIw4L2znPGnYYhfn8vc9c4oB8iw6QAsszbiU0vRhlxWPFnmmNSFAkrYeF1PhM5m4lAN0Q==, tarball: https://registry.npmjs.org/@dagrejs/dagre/-/dagre-3.0.0.tgz} + dependencies: + '@dagrejs/graphlib': 4.0.1 + dev: true - '@dagrejs/graphlib@4.0.1': + /@dagrejs/graphlib@4.0.1: resolution: {integrity: sha512-IvcV6FduIIAmLwnH+yun+QtV36SC7mERqa86aClNqmMN09WhmPPYU8ckHrZBozErf+UvHPWOTJYaGYiIcs0DgA==, tarball: https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-4.0.1.tgz} + dev: true + + /@emnapi/core@1.10.0: + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==, tarball: https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz} + requiresBuild: true + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + dev: true + optional: true + + /@emnapi/core@1.11.0: + resolution: {integrity: sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==, tarball: https://registry.npmjs.org/@emnapi/core/-/core-1.11.0.tgz} + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + dev: true + optional: true + + /@emnapi/runtime@1.10.0: + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==, tarball: https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz} + requiresBuild: true + dependencies: + tslib: 2.8.1 + dev: true + optional: true - '@emnapi/core@1.8.1': - resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==, tarball: https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz} + /@emnapi/runtime@1.11.0: + resolution: {integrity: sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==, tarball: https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.0.tgz} + dependencies: + tslib: 2.8.1 + dev: true + optional: true - '@emnapi/runtime@1.8.1': - resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==, tarball: https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz} + /@emnapi/wasi-threads@1.2.1: + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==, tarball: https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz} + requiresBuild: true + dependencies: + tslib: 2.8.1 + dev: true + optional: true - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==, tarball: https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz} + /@emnapi/wasi-threads@1.2.2: + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==, tarball: https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz} + dependencies: + tslib: 2.8.1 + dev: true + optional: true - '@esbuild/aix-ppc64@0.27.3': - resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz} + /@esbuild/aix-ppc64@0.28.1: + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-arm64@0.27.3': - resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz} + /@esbuild/android-arm64@0.28.1: + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm64] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-arm@0.27.3': - resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz} + /@esbuild/android-arm@0.28.1: + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-x64@0.27.3': - resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz} + /@esbuild/android-x64@0.28.1: + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz} engines: {node: '>=18'} cpu: [x64] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/darwin-arm64@0.27.3': - resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz} + /@esbuild/darwin-arm64@0.28.1: + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@esbuild/darwin-x64@0.27.3': - resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz} + /@esbuild/darwin-x64@0.28.1: + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz} engines: {node: '>=18'} cpu: [x64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@esbuild/freebsd-arm64@0.27.3': - resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz} + /@esbuild/freebsd-arm64@0.28.1: + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/freebsd-x64@0.27.3': - resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz} + /@esbuild/freebsd-x64@0.28.1: + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-arm64@0.27.3': - resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz} + /@esbuild/linux-arm64@0.28.1: + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-arm@0.27.3': - resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz} + /@esbuild/linux-arm@0.28.1: + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-ia32@0.27.3': - resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz} + /@esbuild/linux-ia32@0.28.1: + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz} engines: {node: '>=18'} cpu: [ia32] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-loong64@0.27.3': - resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz} + /@esbuild/linux-loong64@0.28.1: + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz} engines: {node: '>=18'} cpu: [loong64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-mips64el@0.27.3': - resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz} + /@esbuild/linux-mips64el@0.28.1: + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-ppc64@0.27.3': - resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz} + /@esbuild/linux-ppc64@0.28.1: + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-riscv64@0.27.3': - resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz} + /@esbuild/linux-riscv64@0.28.1: + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-s390x@0.27.3': - resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz} + /@esbuild/linux-s390x@0.28.1: + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz} engines: {node: '>=18'} cpu: [s390x] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-x64@0.27.3': - resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz} + /@esbuild/linux-x64@0.28.1: + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz} engines: {node: '>=18'} cpu: [x64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/netbsd-arm64@0.27.3': - resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==, tarball: https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz} + /@esbuild/netbsd-arm64@0.28.1: + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==, tarball: https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/netbsd-x64@0.27.3': - resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz} + /@esbuild/netbsd-x64@0.28.1: + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/openbsd-arm64@0.27.3': - resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==, tarball: https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz} + /@esbuild/openbsd-arm64@0.28.1: + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==, tarball: https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/openbsd-x64@0.27.3': - resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz} + /@esbuild/openbsd-x64@0.28.1: + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/openharmony-arm64@0.27.3': - resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==, tarball: https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz} + /@esbuild/openharmony-arm64@0.28.1: + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==, tarball: https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + requiresBuild: true + dev: true + optional: true - '@esbuild/sunos-x64@0.27.3': - resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz} + /@esbuild/sunos-x64@0.28.1: + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz} engines: {node: '>=18'} cpu: [x64] os: [sunos] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-arm64@0.27.3': - resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz} + /@esbuild/win32-arm64@0.28.1: + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz} engines: {node: '>=18'} cpu: [arm64] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-ia32@0.27.3': - resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz} + /@esbuild/win32-ia32@0.28.1: + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz} engines: {node: '>=18'} cpu: [ia32] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-x64@0.27.3': - resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz} + /@esbuild/win32-x64@0.28.1: + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz} engines: {node: '>=18'} cpu: [x64] os: [win32] + requiresBuild: true + dev: true + optional: true - '@hpcc-js/wasm-graphviz@1.22.0': + /@hpcc-js/wasm-graphviz@1.22.0: resolution: {integrity: sha512-/l6m+ev4TzYwiSm2pklMALiKejuheJwFkOHKrTAvFei+US+MVv6Vgk06xMc4Mjn57WiqzheMVGnmNu1iqkcBdA==, tarball: https://registry.npmjs.org/@hpcc-js/wasm-graphviz/-/wasm-graphviz-1.22.0.tgz} + dev: true - '@inquirer/external-editor@1.0.3': - resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + /@inquirer/external-editor@1.0.3(@types/node@25.9.3): + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==, tarball: https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true + dependencies: + '@types/node': 25.9.3 + chardet: 2.1.1 + iconv-lite: 0.7.2 + dev: true - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + /@jridgewell/gen-mapping@0.3.13: + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==, tarball: https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + dev: true - '@jridgewell/resolve-uri@3.1.2': + /@jridgewell/resolve-uri@3.1.2: resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, tarball: https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz} engines: {node: '>=6.0.0'} + dev: true - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + /@jridgewell/sourcemap-codec@1.5.5: + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, tarball: https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz} + dev: true - '@jridgewell/trace-mapping@0.3.31': + /@jridgewell/trace-mapping@0.3.31: resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==, tarball: https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + dev: true + + /@manypkg/find-root@1.1.0: + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==, tarball: https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz} + dependencies: + '@babel/runtime': 7.29.7 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + dev: true + + /@manypkg/get-packages@1.1.3: + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==, tarball: https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz} + dependencies: + '@babel/runtime': 7.29.7 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + dev: true - '@manypkg/find-root@1.1.0': - resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + /@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==, tarball: https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz} + requiresBuild: true + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + dev: true + optional: true - '@manypkg/get-packages@1.1.3': - resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + /@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0): + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==, tarball: https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz} + requiresBuild: true + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + dependencies: + '@emnapi/core': 1.11.0 + '@emnapi/runtime': 1.11.0 + '@tybys/wasm-util': 0.10.2 + dev: true + optional: true - '@napi-rs/wasm-runtime@1.1.1': - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==, tarball: https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz} + /@nodable/entities@2.1.1: + resolution: {integrity: sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg==, tarball: https://registry.npmjs.org/@nodable/entities/-/entities-2.1.1.tgz} + dev: true - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, tarball: https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz} engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, tarball: https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz} engines: {node: '>= 8'} + dev: true - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, tarball: https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz} engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + dev: true - '@oxc-project/types@0.103.0': - resolution: {integrity: sha512-bkiYX5kaXWwUessFRSoXFkGIQTmc6dLGdxuRTrC+h8PSnIdZyuXHHlLAeTmOue5Br/a0/a7dHH0Gca6eXn9MKg==} + /@oxc-project/types@0.103.0: + resolution: {integrity: sha512-bkiYX5kaXWwUessFRSoXFkGIQTmc6dLGdxuRTrC+h8PSnIdZyuXHHlLAeTmOue5Br/a0/a7dHH0Gca6eXn9MKg==, tarball: https://registry.npmjs.org/@oxc-project/types/-/types-0.103.0.tgz} + dev: true - '@oxc-project/types@0.112.0': - resolution: {integrity: sha512-m6RebKHIRsax2iCwVpYW2ErQwa4ywHJrE4sCK3/8JK8ZZAWOKXaRJFl/uP51gaVyyXlaS4+chU1nSCdzYf6QqQ==} + /@oxc-project/types@0.127.0: + resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==, tarball: https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz} + dev: true - '@publint/pack@0.1.4': + /@oxc-project/types@0.133.0: + resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==, tarball: https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz} + dev: true + + /@publint/pack@0.1.4: resolution: {integrity: sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ==, tarball: https://registry.npmjs.org/@publint/pack/-/pack-0.1.4.tgz} engines: {node: '>=18'} + dev: true - '@quansync/fs@1.0.0': - resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} + /@quansync/fs@1.0.0: + resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==, tarball: https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz} + dependencies: + quansync: 1.0.0 + dev: true - '@rolldown/binding-android-arm64@1.0.0-beta.57': + /@rolldown/binding-android-arm64@1.0.0-beta.57: resolution: {integrity: sha512-GoOVDy8bjw9z1K30Oo803nSzXJS/vWhFijFsW3kzvZCO8IZwFnNa6pGctmbbJstKl3Fv6UBwyjJQN6msejW0IQ==, tarball: https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] + requiresBuild: true + dev: true + optional: true + + /@rolldown/binding-android-arm64@1.0.0-rc.17: + resolution: {integrity: sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==, tarball: https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-android-arm64@1.0.0-rc.3': - resolution: {integrity: sha512-0T1k9FinuBZ/t7rZ8jN6OpUKPnUjNdYHoj/cESWrQ3ZraAJ4OMm6z7QjSfCxqj8mOp9kTKc1zHK3kGz5vMu+nQ==, tarball: https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.3.tgz} + /@rolldown/binding-android-arm64@1.0.3: + resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==, tarball: https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-darwin-arm64@1.0.0-beta.57': + /@rolldown/binding-darwin-arm64@1.0.0-beta.57: resolution: {integrity: sha512-9c4FOhRGpl+PX7zBK5p17c5efpF9aSpTPgyigv57hXf5NjQUaJOOiejPLAtFiKNBIfm5Uu6yFkvLKzOafNvlTw==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rolldown/binding-darwin-arm64@1.0.0-rc.17: + resolution: {integrity: sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.3': - resolution: {integrity: sha512-JWWLzvcmc/3pe7qdJqPpuPk91SoE/N+f3PcWx/6ZwuyDVyungAEJPvKm/eEldiDdwTmaEzWfIR+HORxYWrCi1A==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.3.tgz} + /@rolldown/binding-darwin-arm64@1.0.3: + resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-darwin-x64@1.0.0-beta.57': + /@rolldown/binding-darwin-x64@1.0.0-beta.57: resolution: {integrity: sha512-6RsB8Qy4LnGqNGJJC/8uWeLWGOvbRL/KG5aJ8XXpSEupg/KQtlBEiFaYU/Ma5Usj1s+bt3ItkqZYAI50kSplBA==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rolldown/binding-darwin-x64@1.0.0-rc.17: + resolution: {integrity: sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.3': - resolution: {integrity: sha512-MTakBxfx3tde5WSmbHxuqlDsIW0EzQym+PJYGF4P6lG2NmKzi128OGynoFUqoD5ryCySEY85dug4v+LWGBElIw==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.3.tgz} + /@rolldown/binding-darwin-x64@1.0.3: + resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-freebsd-x64@1.0.0-beta.57': + /@rolldown/binding-freebsd-x64@1.0.0-beta.57: resolution: {integrity: sha512-uA9kG7+MYkHTbqwv67Tx+5GV5YcKd33HCJIi0311iYBd25yuwyIqvJfBdt1VVB8tdOlyTb9cPAgfCki8nhwTQg==, tarball: https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@rolldown/binding-freebsd-x64@1.0.0-rc.17: + resolution: {integrity: sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==, tarball: https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.3': - resolution: {integrity: sha512-jje3oopyOLs7IwfvXoS6Lxnmie5JJO7vW29fdGFu5YGY1EDbVDhD+P9vDihqS5X6fFiqL3ZQZCMBg6jyHkSVww==, tarball: https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.3.tgz} + /@rolldown/binding-freebsd-x64@1.0.3: + resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==, tarball: https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.57': + /@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.57: resolution: {integrity: sha512-3KkS0cHsllT2T+Te+VZMKHNw6FPQihYsQh+8J4jkzwgvAQpbsbXmrqhkw3YU/QGRrD8qgcOvBr6z5y6Jid+rmw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17: + resolution: {integrity: sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': - resolution: {integrity: sha512-A0n8P3hdLAaqzSFrQoA42p23ZKBYQOw+8EH5r15Sa9X1kD9/JXe0YT2gph2QTWvdr0CVK2BOXiK6ENfy6DXOag==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.3.tgz} + /@rolldown/binding-linux-arm-gnueabihf@1.0.3: + resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.57': + /@rolldown/binding-linux-arm64-gnu@1.0.0-beta.57: resolution: {integrity: sha512-A3/wu1RgsHhqP3rVH2+sM81bpk+Qd2XaHTl8LtX5/1LNR7QVBFBCpAoiXwjTdGnI5cMdBVi7Z1pi52euW760Fw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [glibc] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': - resolution: {integrity: sha512-kWXkoxxarYISBJ4bLNf5vFkEbb4JvccOwxWDxuK9yee8lg5XA7OpvlTptfRuwEvYcOZf+7VS69Uenpmpyo5Bjw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.3.tgz} + /@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17: + resolution: {integrity: sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [glibc] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.57': - resolution: {integrity: sha512-d0kIVezTQtazpyWjiJIn5to8JlwfKITDqwsFv0Xc6s31N16CD2PC/Pl2OtKgS7n8WLOJbfqgIp5ixYzTAxCqMg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.57.tgz} + /@rolldown/binding-linux-arm64-gnu@1.0.3: + resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [musl] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': - resolution: {integrity: sha512-Z03/wrqau9Bicfgb3Dbs6SYTHliELk2PM2LpG2nFd+cGupTMF5kanLEcj2vuuJLLhptNyS61rtk7SOZ+lPsTUA==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.3.tgz} + /@rolldown/binding-linux-arm64-musl@1.0.0-beta.57: + resolution: {integrity: sha512-d0kIVezTQtazpyWjiJIn5to8JlwfKITDqwsFv0Xc6s31N16CD2PC/Pl2OtKgS7n8WLOJbfqgIp5ixYzTAxCqMg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [musl] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.57': - resolution: {integrity: sha512-E199LPijo98yrLjPCmETx8EF43sZf9t3guSrLee/ej1rCCc3zDVTR4xFfN9BRAapGVl7/8hYqbbiQPTkv73kUg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.57.tgz} + /@rolldown/binding-linux-arm64-musl@1.0.0-rc.17: + resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] + cpu: [arm64] os: [linux] - libc: [glibc] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': - resolution: {integrity: sha512-iSXXZsQp08CSilff/DCTFZHSVEpEwdicV3W8idHyrByrcsRDVh9sGC3sev6d8BygSGj3vt8GvUKBPCoyMA4tgQ==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.3.tgz} + /@rolldown/binding-linux-arm64-musl@1.0.3: + resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] + cpu: [arm64] os: [linux] - libc: [glibc] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-beta.57': - resolution: {integrity: sha512-++EQDpk/UJ33kY/BNsh7A7/P1sr/jbMuQ8cE554ZIy+tCUWCivo9zfyjDUoiMdnxqX6HLJEqqGnbGQOvzm2OMQ==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.57.tgz} + /@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17: + resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] + cpu: [ppc64] os: [linux] - libc: [musl] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': - resolution: {integrity: sha512-qaj+MFudtdCv9xZo9znFvkgoajLdc+vwf0Kz5N44g+LU5XMe+IsACgn3UG7uTRlCCvhMAGXm1XlpEA5bZBrOcw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.3.tgz} + /@rolldown/binding-linux-ppc64-gnu@1.0.3: + resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] + cpu: [ppc64] os: [linux] - libc: [musl] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-beta.57': - resolution: {integrity: sha512-voDEBcNqxbUv/GeXKFtxXVWA+H45P/8Dec4Ii/SbyJyGvCqV1j+nNHfnFUIiRQ2Q40DwPe/djvgYBs9PpETiMA==, tarball: https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.57.tgz} + /@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17: + resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': - resolution: {integrity: sha512-U662UnMETyjT65gFmG9ma+XziENrs7BBnENi/27swZPYagubfHRirXHG2oMl+pEax2WvO7Kb9gHZmMakpYqBHQ==, tarball: https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.3.tgz} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.0.0-beta.57': - resolution: {integrity: sha512-bRhcF7NLlCnpkzLVlVhrDEd0KH22VbTPkPTbMjlYvqhSmarxNIq5vtlQS8qmV7LkPKHrNLWyJW/V/sOyFba26Q==, tarball: https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.57.tgz} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': - resolution: {integrity: sha512-gekrQ3Q2HiC1T5njGyuUJoGpK/l6B/TNXKed3fZXNf9YRTJn3L5MOZsFBn4bN2+UX+8+7hgdlTcEsexX988G4g==, tarball: https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.3.tgz} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.57': - resolution: {integrity: sha512-rnDVGRks2FQ2hgJ2g15pHtfxqkGFGjJQUDWzYznEkE8Ra2+Vag9OffxdbJMZqBWXHVM0iS4dv8qSiEn7bO+n1Q==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.57.tgz} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': - resolution: {integrity: sha512-85y5JifyMgs8m5K2XzR/VDsapKbiFiohl7s5lEj7nmNGO0pkTXE7q6TQScei96BNAsoK7JC3pA7ukA8WRHVJpg==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.3.tgz} + /@rolldown/binding-linux-s390x-gnu@1.0.3: + resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.57': - resolution: {integrity: sha512-OqIUyNid1M4xTj6VRXp/Lht/qIP8fo25QyAZlCP+p6D2ATCEhyW4ZIFLnC9zAGN/HMbXoCzvwfa8Jjg/8J4YEg==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.57.tgz} + /@rolldown/binding-linux-x64-gnu@1.0.0-beta.57: + resolution: {integrity: sha512-E199LPijo98yrLjPCmETx8EF43sZf9t3guSrLee/ej1rCCc3zDVTR4xFfN9BRAapGVl7/8hYqbbiQPTkv73kUg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] - os: [win32] + os: [linux] + requiresBuild: true + dev: true + optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': - resolution: {integrity: sha512-a4VUQZH7LxGbUJ3qJ/TzQG8HxdHvf+jOnqf7B7oFx1TEBm+j2KNL2zr5SQ7wHkNAcaPevF6gf9tQnVBnC4mD+A==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.3.tgz} + /@rolldown/binding-linux-x64-gnu@1.0.0-rc.17: + resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.0-beta.57': - resolution: {integrity: sha512-aQNelgx14tGA+n2tNSa9x6/jeoCL9fkDeCei7nOKnHx0fEFRRMu5ReiITo+zZD5TzWDGGRjbSYCs93IfRIyTuQ==} - - '@rolldown/pluginutils@1.0.0-rc.3': - resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} - - '@rollup/rollup-android-arm-eabi@4.57.1': - resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.57.1': - resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.57.1': - resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.57.1': - resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.57.1': - resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==, tarball: https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.57.1': - resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==, tarball: https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.57.1': - resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm-musleabihf@4.57.1': - resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz} - cpu: [arm] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-arm64-gnu@4.57.1': - resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm64-musl@4.57.1': - resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-loong64-gnu@4.57.1': - resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-loong64-musl@4.57.1': - resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.57.1': - resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-ppc64-musl@4.57.1': - resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.57.1': - resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-riscv64-musl@4.57.1': - resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz} - cpu: [riscv64] os: [linux] - libc: [musl] + requiresBuild: true + dev: true + optional: true - '@rollup/rollup-linux-s390x-gnu@4.57.1': - resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz} - cpu: [s390x] + /@rolldown/binding-linux-x64-gnu@1.0.3: + resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] os: [linux] - libc: [glibc] + requiresBuild: true + dev: true + optional: true - '@rollup/rollup-linux-x64-gnu@4.57.1': - resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz} + /@rolldown/binding-linux-x64-musl@1.0.0-beta.57: + resolution: {integrity: sha512-++EQDpk/UJ33kY/BNsh7A7/P1sr/jbMuQ8cE554ZIy+tCUWCivo9zfyjDUoiMdnxqX6HLJEqqGnbGQOvzm2OMQ==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.57.tgz} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [glibc] + requiresBuild: true + dev: true + optional: true - '@rollup/rollup-linux-x64-musl@4.57.1': - resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz} + /@rolldown/binding-linux-x64-musl@1.0.0-rc.17: + resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [musl] + requiresBuild: true + dev: true + optional: true - '@rollup/rollup-openbsd-x64@4.57.1': - resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==, tarball: https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz} + /@rolldown/binding-linux-x64-musl@1.0.3: + resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] - os: [openbsd] + os: [linux] + requiresBuild: true + dev: true + optional: true - '@rollup/rollup-openharmony-arm64@4.57.1': - resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==, tarball: https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz} + /@rolldown/binding-openharmony-arm64@1.0.0-beta.57: + resolution: {integrity: sha512-voDEBcNqxbUv/GeXKFtxXVWA+H45P/8Dec4Ii/SbyJyGvCqV1j+nNHfnFUIiRQ2Q40DwPe/djvgYBs9PpETiMA==, tarball: https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.57.tgz} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + requiresBuild: true + dev: true + optional: true - '@rollup/rollup-win32-arm64-msvc@4.57.1': - resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz} + /@rolldown/binding-openharmony-arm64@1.0.0-rc.17: + resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==, tarball: https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.57.1': - resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.57.1': - resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.57.1': - resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz} - cpu: [x64] - os: [win32] - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==, tarball: https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz} - - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - - '@types/d3-array@3.2.2': - resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} - - '@types/d3-color@3.1.3': - resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==, tarball: https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz} - - '@types/d3-drag@3.0.7': - resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==, tarball: https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz} - - '@types/d3-force@3.0.10': - resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} - - '@types/d3-interpolate@3.0.4': - resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==, tarball: https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz} - - '@types/d3-selection@3.0.11': - resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==, tarball: https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz} - - '@types/d3-transition@3.0.9': - resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==, tarball: https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz} - - '@types/d3-zoom@3.0.8': - resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==, tarball: https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/node@12.20.55': - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - - '@types/node@25.2.1': - resolution: {integrity: sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==} - - '@vitest/coverage-v8@4.0.18': - resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==, tarball: https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.18.tgz} - peerDependencies: - '@vitest/browser': 4.0.18 - vitest: 4.0.18 - peerDependenciesMeta: - '@vitest/browser': - optional: true - - '@vitest/expect@4.0.18': - resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} - - '@vitest/mocker@4.0.18': - resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} - peerDependencies: - msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@4.0.18': - resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==, tarball: https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz} - - '@vitest/runner@4.0.18': - resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} - - '@vitest/snapshot@4.0.18': - resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} - - '@vitest/spy@4.0.18': - resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} - - '@vitest/utils@4.0.18': - resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==, tarball: https://registry.npmjs.org/@vitest/utils/-/utils-4.0.18.tgz} - - '@xyflow/system@0.0.75': - resolution: {integrity: sha512-iXs+AGFLi8w/VlAoc/iSxk+CxfT6o64Uw/k0CKASOPqjqz6E0rb5jFZgJtXGZCpfQI6OQpu5EnumP5fGxQheaQ==, tarball: https://registry.npmjs.org/@xyflow/system/-/system-0.0.75.tgz} - - '@yomguithereal/helpers@1.1.1': - resolution: {integrity: sha512-UYvAq/XCA7xoh1juWDYsq3W0WywOB+pz8cgVnE1b45ZfdMhBvHDrgmSFG3jXeZSr2tMTYLGHFHON+ekG05Jebg==, tarball: https://registry.npmjs.org/@yomguithereal/helpers/-/helpers-1.1.1.tgz} - - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansis@4.2.0: - resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} - engines: {node: '>=14'} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - args-tokenizer@0.3.0: - resolution: {integrity: sha512-xXAd7G2Mll5W8uo37GETpQ2VrE84M181Z7ugHFGQnJZ50M2mbOv0osSZ9VsSgPfJQ+LVG0prSi0th+ELMsno7Q==} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - ast-kit@2.2.0: - resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} - engines: {node: '>=20.19.0'} - - ast-v8-to-istanbul@0.3.12: - resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==, tarball: https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.12.tgz} - - better-path-resolve@1.0.0: - resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} - engines: {node: '>=4'} - - birpc@4.0.0: - resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - bumpp@10.4.1: - resolution: {integrity: sha512-X/bwWs5Gbb/D7rN4aHLB7zdjiA6nGdjckM1sTHhI9oovIbEw2L5pw5S4xzk8ZTeOZ8EnwU/Ze4SoZ6/Vr3pM2Q==} - engines: {node: '>=18'} - hasBin: true - - c12@3.3.3: - resolution: {integrity: sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q==} - peerDependencies: - magicast: '*' - peerDependenciesMeta: - magicast: - optional: true - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} - - chardet@2.1.1: - resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - - chokidar@5.0.0: - resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} - engines: {node: '>= 20.19.0'} - - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - - citty@0.1.6: - resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} - - citty@0.2.0: - resolution: {integrity: sha512-8csy5IBFI2ex2hTVpaHN2j+LNE199AgiI7y4dMintrr8i0lQiFn+0AWMZrWdHKIgMOer65f8IThysYhoReqjWA==} - - confbox@0.2.4: - resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - cytoscape@3.33.1: - resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} - engines: {node: '>=0.10'} - - d3-array@3.2.4: - resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} - engines: {node: '>=12'} - - d3-color@3.1.0: - resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==, tarball: https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz} - engines: {node: '>=12'} - - d3-dispatch@3.0.1: - resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} - engines: {node: '>=12'} - - d3-drag@3.0.0: - resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==, tarball: https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz} - engines: {node: '>=12'} - - d3-ease@3.0.1: - resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==, tarball: https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz} - engines: {node: '>=12'} - - d3-force@3.0.0: - resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} - engines: {node: '>=12'} - - d3-interpolate@3.0.1: - resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==, tarball: https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz} - engines: {node: '>=12'} - - d3-quadtree@3.0.1: - resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} - engines: {node: '>=12'} - - d3-selection@3.0.0: - resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==, tarball: https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz} - engines: {node: '>=12'} - - d3-timer@3.0.1: - resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} - engines: {node: '>=12'} - - d3-transition@3.0.1: - resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==, tarball: https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz} - engines: {node: '>=12'} - peerDependencies: - d3-selection: 2 - 3 - - d3-zoom@3.0.0: - resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==, tarball: https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz} - engines: {node: '>=12'} - - dataloader@1.4.0: - resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} - - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - - destr@2.0.5: - resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - - detect-indent@6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - dotenv@17.2.4: - resolution: {integrity: sha512-mudtfb4zRB4bVvdj0xRo+e6duH1csJRM8IukBqfTRvHotn9+LBXB8ynAidP9zHqoRC/fsllXgk4kCKlR21fIhw==} - engines: {node: '>=12'} - - dotenv@8.6.0: - resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} - engines: {node: '>=10'} - - dotparser@1.1.1: - resolution: {integrity: sha512-8ojhUts0HbLnXJgjTiJOddwVVBUk6hg4SJ5kGiuhzgK/f+y79TiWvICwx1oCWlVbBC8YI3nEaIQg9fjGYbGBXw==, tarball: https://registry.npmjs.org/dotparser/-/dotparser-1.1.1.tgz} - - dts-resolver@2.1.3: - resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==} - engines: {node: '>=20.19.0'} - peerDependencies: - oxc-resolver: '>=11.0.0' - peerDependenciesMeta: - oxc-resolver: - optional: true - - elkjs@0.11.1: - resolution: {integrity: sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==, tarball: https://registry.npmjs.org/elkjs/-/elkjs-0.11.1.tgz} - - empathic@2.0.0: - resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} - engines: {node: '>=14'} - - enquirer@2.4.1: - resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} - engines: {node: '>=8.6'} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - esbuild@0.27.3: - resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, tarball: https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz} - - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==, tarball: https://registry.npmjs.org/events/-/events-3.3.0.tgz} - engines: {node: '>=0.8.x'} - - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} - engines: {node: '>=12.0.0'} - - exsolve@1.0.8: - resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} - - extendable-error@0.1.7: - resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-xml-parser@5.3.4: - resolution: {integrity: sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==} - hasBin: true - - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - - fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - get-tsconfig@4.13.6: - resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} - - giget@2.0.0: - resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} - hasBin: true - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - graphology-components@1.5.4: - resolution: {integrity: sha512-O37vC226wgnN0C6FUWHNe4fbTzaF51CcQjwX3naId/QTzH/PkUtXaanCShj9ws5Vju+z4u3zvSeEZE84Bo9jlA==, tarball: https://registry.npmjs.org/graphology-components/-/graphology-components-1.5.4.tgz} - peerDependencies: - graphology-types: '>=0.19.0' - - graphology-indices@0.17.0: - resolution: {integrity: sha512-A7RXuKQvdqSWOpn7ZVQo4S33O0vCfPBnUSf7FwE0zNCasqwZVUaCXePuWo5HBpWw68KJcwObZDHpFk6HKH6MYQ==, tarball: https://registry.npmjs.org/graphology-indices/-/graphology-indices-0.17.0.tgz} - peerDependencies: - graphology-types: '>=0.20.0' - - graphology-metrics@2.4.0: - resolution: {integrity: sha512-7WOfOP+mFLCaTJx55Qg4eY+211vr1/b3D/R3biz3SXGhAaCVcWYkfabnmO4O4WBNWANEHtVnFrGgJ0kj6MM6xw==, tarball: https://registry.npmjs.org/graphology-metrics/-/graphology-metrics-2.4.0.tgz} - peerDependencies: - graphology-types: '>=0.20.0' - - graphology-shortest-path@2.1.0: - resolution: {integrity: sha512-KbT9CTkP/u72vGEJzyRr24xFC7usI9Es3LMmCPHGwQ1KTsoZjxwA9lMKxfU0syvT/w+7fZUdB/Hu2wWYcJBm6Q==, tarball: https://registry.npmjs.org/graphology-shortest-path/-/graphology-shortest-path-2.1.0.tgz} - peerDependencies: - graphology-types: '>=0.20.0' - - graphology-types@0.24.8: - resolution: {integrity: sha512-hDRKYXa8TsoZHjgEaysSRyPdT6uB78Ci8WnjgbStlQysz7xR52PInxNsmnB7IBOM1BhikxkNyCVEFgmPKnpx3Q==, tarball: https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.8.tgz} - - graphology-utils@2.5.2: - resolution: {integrity: sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==, tarball: https://registry.npmjs.org/graphology-utils/-/graphology-utils-2.5.2.tgz} - peerDependencies: - graphology-types: '>=0.23.0' - - graphology@0.26.0: - resolution: {integrity: sha512-8SSImzgUUYC89Z042s+0r/vMibY7GX/Emz4LDO5e7jYXhuoWfHISPFJYjpRLUSJGq6UQ6xlenvX1p/hJdfXuXg==, tarball: https://registry.npmjs.org/graphology/-/graphology-0.26.0.tgz} - peerDependencies: - graphology-types: '>=0.24.0' - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, tarball: https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz} - engines: {node: '>=8'} - - hookable@6.0.1: - resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, tarball: https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz} - - human-id@4.1.3: - resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} - hasBin: true - - iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} - engines: {node: '>=0.10.0'} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - import-without-cache@0.2.5: - resolution: {integrity: sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==} - engines: {node: '>=20.19.0'} - - internmap@2.0.3: - resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} - engines: {node: '>=12'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-subdir@1.2.0: - resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} - engines: {node: '>=4'} - - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, tarball: https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz} - engines: {node: '>=8'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, tarball: https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz} - engines: {node: '>=10'} - - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==, tarball: https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz} - engines: {node: '>=8'} - - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} - hasBin: true - - js-tokens@10.0.0: - resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==, tarball: https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz} - - js-yaml@3.14.2: - resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} - hasBin: true - - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} - hasBin: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - - lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - magicast@0.5.3: - resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==, tarball: https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz} - - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, tarball: https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz} - engines: {node: '>=10'} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mnemonist@0.39.8: - resolution: {integrity: sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==, tarball: https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz} - - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - ngraph.events@1.4.0: - resolution: {integrity: sha512-NeDGI4DSyjBNBRtA86222JoYietsmCXbs8CEB0dZ51Xeh4lhVl1y3wpWLumczvnha8sFQIW4E0vvVWwgmX2mGw==, tarball: https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.4.0.tgz} - - ngraph.graph@20.1.2: - resolution: {integrity: sha512-W/G3GBR3Y5UxMLHTUCPP9v+pbtpzwuAEIqP5oZV+9IwgxAIEZwh+Foc60iPc1idlnK7Zxu0p3puxAyNmDvBd0Q==, tarball: https://registry.npmjs.org/ngraph.graph/-/ngraph.graph-20.1.2.tgz} - - ngraph.path@1.6.1: - resolution: {integrity: sha512-NiA52wAoRo/t36/1dBAZkXPeX+rQ1mn82bc9LSfnfywGY9TxH/jXw3x3fZ1mOCblyln26lHtfHHEzssjjyX+aw==, tarball: https://registry.npmjs.org/ngraph.path/-/ngraph.path-1.6.1.tgz} - - node-fetch-native@1.6.7: - resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - nypm@0.6.5: - resolution: {integrity: sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==} - engines: {node: '>=18'} - hasBin: true - - obliterator@2.0.5: - resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==, tarball: https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz} - - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==, tarball: https://registry.npmjs.org/obug/-/obug-2.1.1.tgz} - - ohash@2.0.11: - resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - - outdent@0.5.0: - resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - - p-filter@2.1.0: - resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} - engines: {node: '>=8'} - - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - - p-map@2.1.0: - resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} - engines: {node: '>=6'} - - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - package-manager-detector@0.2.11: - resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} - - package-manager-detector@1.6.0: - resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} - - pandemonium@2.4.1: - resolution: {integrity: sha512-wRqjisUyiUfXowgm7MFH2rwJzKIr20rca5FsHXCMNm1W5YPP1hCtrZfgmQ62kP7OZ7Xt+cR858aB28lu5NX55g==, tarball: https://registry.npmjs.org/pandemonium/-/pandemonium-2.4.1.tgz} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - perfect-debounce@2.1.0: - resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - - pkg-types@2.3.0: - resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - - publint@0.3.18: - resolution: {integrity: sha512-JRJFeBTrfx4qLwEuGFPk+haJOJN97KnPuK01yj+4k/Wj5BgoOK5uNsivporiqBjk2JDaslg7qJOhGRnpltGeog==, tarball: https://registry.npmjs.org/publint/-/publint-0.3.18.tgz} - engines: {node: '>=18'} - hasBin: true - - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} - - quansync@1.0.0: - resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - rc9@2.1.2: - resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} - - read-yaml-file@1.1.0: - resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} - engines: {node: '>=6'} - - readdirp@5.0.0: - resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} - engines: {node: '>= 20.19.0'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rolldown-plugin-dts@0.20.0: - resolution: {integrity: sha512-cLAY1kN2ilTYMfZcFlGWbXnu6Nb+8uwUBsi+Mjbh4uIx7IN8uMOmJ7RxrrRgPsO4H7eSz3E+JwGoL1gyugiyUA==} - engines: {node: '>=20.19.0'} - peerDependencies: - '@ts-macro/tsc': ^0.3.6 - '@typescript/native-preview': '>=7.0.0-dev.20250601.1' - rolldown: ^1.0.0-beta.57 - typescript: ^5.0.0 - vue-tsc: ~3.2.0 - peerDependenciesMeta: - '@ts-macro/tsc': - optional: true - '@typescript/native-preview': - optional: true - typescript: - optional: true - vue-tsc: - optional: true - - rolldown@1.0.0-beta.57: - resolution: {integrity: sha512-lMMxcNN71GMsSko8RyeTaFoATHkCh4IWU7pYF73ziMYjhHZWfVesC6GQ+iaJCvZmVjvgSks9Ks1aaqEkBd8udg==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - rolldown@1.0.0-rc.3: - resolution: {integrity: sha512-Po/YZECDOqVXjIXrtC5h++a5NLvKAQNrd9ggrIG3sbDfGO5BqTUsrI6l8zdniKRp3r5Tp/2JTrXqx4GIguFCMw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - rollup@4.57.1: - resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - sade@1.8.1: - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==, tarball: https://registry.npmjs.org/sade/-/sade-1.8.1.tgz} - engines: {node: '>=6'} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, tarball: https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz} - engines: {node: '>=0.10.0'} - - spawndamnit@3.0.1: - resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==, tarball: https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz} - - 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'} - - strnum@2.1.2: - resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, tarball: https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz} - engines: {node: '>=8'} - - term-size@2.2.1: - resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} - engines: {node: '>=8'} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} - engines: {node: '>=18'} - - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - tinyrainbow@3.0.3: - resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} - engines: {node: '>=14.0.0'} - - tinyrainbow@3.1.0: - resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==, tarball: https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz} - engines: {node: '>=14.0.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - - tsdown@0.18.4: - resolution: {integrity: sha512-J/tRS6hsZTkvqmt4+xdELUCkQYDuUCXgBv0fw3ImV09WPGbEKfsPD65E+WUjSu3E7Z6tji9XZ1iWs8rbGqB/ZA==} - engines: {node: '>=20.19.0'} - hasBin: true - peerDependencies: - '@arethetypeswrong/core': ^0.18.1 - '@vitejs/devtools': '*' - publint: ^0.3.0 - typescript: ^5.0.0 - unplugin-lightningcss: ^0.4.0 - unplugin-unused: ^0.5.0 - peerDependenciesMeta: - '@arethetypeswrong/core': - optional: true - '@vitejs/devtools': - optional: true - publint: - optional: true - typescript: - optional: true - unplugin-lightningcss: - optional: true - unplugin-unused: - optional: true - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, tarball: https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz} - - tsx@4.21.0: - resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} - engines: {node: '>=18.0.0'} - hasBin: true - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - unconfig-core@7.4.2: - resolution: {integrity: sha512-VgPCvLWugINbXvMQDf8Jh0mlbvNjNC6eSUziHsBCMpxR05OPrNrvDnyatdMjRgcHaaNsCqz+wjNXxNw1kRLHUg==} - - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - - unrun@0.2.27: - resolution: {integrity: sha512-Mmur1UJpIbfxasLOhPRvox/QS4xBiDii71hMP7smfRthGcwFL2OAmYRgduLANOAU4LUkvVamuP+02U+c90jlrw==} - engines: {node: '>=20.19.0'} - hasBin: true - peerDependencies: - synckit: ^0.11.11 - peerDependenciesMeta: - synckit: - optional: true - - vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitest@4.0.18: - resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.18 - '@vitest/browser-preview': 4.0.18 - '@vitest/browser-webdriverio': 4.0.18 - '@vitest/ui': 4.0.18 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@opentelemetry/api': - optional: true - '@types/node': - optional: true - '@vitest/browser-playwright': - optional: true - '@vitest/browser-preview': - optional: true - '@vitest/browser-webdriverio': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - - xstate@5.28.0: - resolution: {integrity: sha512-Iaqq6ZrUzqeUtA3hC5LQKZfR8ZLzEFTImMHJM3jWEdVvXWdKvvVLXZEiNQWm3SCA9ZbEou/n5rcsna1wb9t28A==} - - yaml@2.8.2: - resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} - engines: {node: '>= 14.6'} - hasBin: true - - zod@4.3.6: - resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - -snapshots: - - '@babel/generator@7.29.1': - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - - '@babel/helper-string-parser@7.29.7': {} - - '@babel/helper-validator-identifier@7.29.7': {} - - '@babel/parser@7.29.7': - dependencies: - '@babel/types': 7.29.7 - - '@babel/runtime@7.28.6': {} - - '@babel/types@7.29.7': - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - - '@bcoe/v8-coverage@1.0.2': {} - - '@changesets/apply-release-plan@7.0.14': - dependencies: - '@changesets/config': 3.1.2 - '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.4 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.8.8 - resolve-from: 5.0.0 - semver: 7.7.4 - - '@changesets/assemble-release-plan@6.0.9': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - semver: 7.7.4 - - '@changesets/changelog-git@0.2.1': - dependencies: - '@changesets/types': 6.1.0 - - '@changesets/changelog-github@0.5.2': - dependencies: - '@changesets/get-github-info': 0.7.0 - '@changesets/types': 6.1.0 - dotenv: 8.6.0 - transitivePeerDependencies: - - encoding - - '@changesets/cli@2.29.8(@types/node@25.2.1)': - dependencies: - '@changesets/apply-release-plan': 7.0.14 - '@changesets/assemble-release-plan': 6.0.9 - '@changesets/changelog-git': 0.2.1 - '@changesets/config': 3.1.2 - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/get-release-plan': 4.0.14 - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.6 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@25.2.1) - '@manypkg/get-packages': 1.1.3 - ansi-colors: 4.1.3 - ci-info: 3.9.0 - enquirer: 2.4.1 - fs-extra: 7.0.1 - mri: 1.2.0 - p-limit: 2.3.0 - package-manager-detector: 0.2.11 - picocolors: 1.1.1 - resolve-from: 5.0.0 - semver: 7.7.4 - spawndamnit: 3.0.1 - term-size: 2.2.1 - transitivePeerDependencies: - - '@types/node' - - '@changesets/config@3.1.2': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/logger': 0.1.1 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - micromatch: 4.0.8 - - '@changesets/errors@0.2.0': - dependencies: - extendable-error: 0.1.7 - - '@changesets/get-dependents-graph@2.1.3': - dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - picocolors: 1.1.1 - semver: 7.7.4 - - '@changesets/get-github-info@0.7.0': - dependencies: - dataloader: 1.4.0 - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - - '@changesets/get-release-plan@4.0.14': - dependencies: - '@changesets/assemble-release-plan': 6.0.9 - '@changesets/config': 3.1.2 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.6 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - - '@changesets/get-version-range-type@0.4.0': {} - - '@changesets/git@3.0.4': - dependencies: - '@changesets/errors': 0.2.0 - '@manypkg/get-packages': 1.1.3 - is-subdir: 1.2.0 - micromatch: 4.0.8 - spawndamnit: 3.0.1 - - '@changesets/logger@0.1.1': - dependencies: - picocolors: 1.1.1 - - '@changesets/parse@0.4.2': - dependencies: - '@changesets/types': 6.1.0 - js-yaml: 4.1.1 - - '@changesets/pre@2.0.2': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - - '@changesets/read@0.6.6': - dependencies: - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.2 - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - p-filter: 2.1.0 - picocolors: 1.1.1 - - '@changesets/should-skip-package@0.1.2': - dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - - '@changesets/types@4.1.0': {} - - '@changesets/types@6.1.0': {} - - '@changesets/write@0.4.0': - dependencies: - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - human-id: 4.1.3 - prettier: 2.8.8 - - '@dagrejs/dagre@3.0.0': - dependencies: - '@dagrejs/graphlib': 4.0.1 - - '@dagrejs/graphlib@4.0.1': {} - - '@emnapi/core@1.8.1': - dependencies: - '@emnapi/wasi-threads': 1.1.0 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.8.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.1.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/aix-ppc64@0.27.3': - optional: true - - '@esbuild/android-arm64@0.27.3': - optional: true - - '@esbuild/android-arm@0.27.3': - optional: true - - '@esbuild/android-x64@0.27.3': - optional: true - - '@esbuild/darwin-arm64@0.27.3': - optional: true - - '@esbuild/darwin-x64@0.27.3': - optional: true - - '@esbuild/freebsd-arm64@0.27.3': - optional: true - - '@esbuild/freebsd-x64@0.27.3': - optional: true - - '@esbuild/linux-arm64@0.27.3': - optional: true - - '@esbuild/linux-arm@0.27.3': - optional: true - - '@esbuild/linux-ia32@0.27.3': - optional: true - - '@esbuild/linux-loong64@0.27.3': - optional: true - - '@esbuild/linux-mips64el@0.27.3': - optional: true - - '@esbuild/linux-ppc64@0.27.3': - optional: true - - '@esbuild/linux-riscv64@0.27.3': - optional: true - - '@esbuild/linux-s390x@0.27.3': - optional: true - - '@esbuild/linux-x64@0.27.3': - optional: true - - '@esbuild/netbsd-arm64@0.27.3': - optional: true - - '@esbuild/netbsd-x64@0.27.3': - optional: true - - '@esbuild/openbsd-arm64@0.27.3': - optional: true - - '@esbuild/openbsd-x64@0.27.3': - optional: true - - '@esbuild/openharmony-arm64@0.27.3': - optional: true - - '@esbuild/sunos-x64@0.27.3': - optional: true - - '@esbuild/win32-arm64@0.27.3': - optional: true - - '@esbuild/win32-ia32@0.27.3': - optional: true - - '@esbuild/win32-x64@0.27.3': - optional: true - - '@hpcc-js/wasm-graphviz@1.22.0': {} - - '@inquirer/external-editor@1.0.3(@types/node@25.2.1)': - dependencies: - chardet: 2.1.1 - iconv-lite: 0.7.2 - optionalDependencies: - '@types/node': 25.2.1 - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@manypkg/find-root@1.1.0': - dependencies: - '@babel/runtime': 7.28.6 - '@types/node': 12.20.55 - find-up: 4.1.0 - fs-extra: 8.1.0 - - '@manypkg/get-packages@1.1.3': - dependencies: - '@babel/runtime': 7.28.6 - '@changesets/types': 4.1.0 - '@manypkg/find-root': 1.1.0 - fs-extra: 8.1.0 - globby: 11.1.0 - read-yaml-file: 1.1.0 - - '@napi-rs/wasm-runtime@1.1.1': - dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 - - '@oxc-project/types@0.103.0': {} - - '@oxc-project/types@0.112.0': {} - - '@publint/pack@0.1.4': {} - - '@quansync/fs@1.0.0': - dependencies: - quansync: 1.0.0 - - '@rolldown/binding-android-arm64@1.0.0-beta.57': - optional: true - - '@rolldown/binding-android-arm64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-darwin-arm64@1.0.0-beta.57': - optional: true - - '@rolldown/binding-darwin-arm64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-darwin-x64@1.0.0-beta.57': - optional: true - - '@rolldown/binding-darwin-x64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-freebsd-x64@1.0.0-beta.57': - optional: true - - '@rolldown/binding-freebsd-x64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.57': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.57': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.57': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.57': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.3': - optional: true - - '@rolldown/binding-linux-x64-musl@1.0.0-beta.57': - optional: true - - '@rolldown/binding-linux-x64-musl@1.0.0-rc.3': - optional: true - - '@rolldown/binding-openharmony-arm64@1.0.0-beta.57': - optional: true - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.3': - optional: true - - '@rolldown/binding-wasm32-wasi@1.0.0-beta.57': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 - optional: true - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.3': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.57': - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.57': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.3': - optional: true - - '@rolldown/pluginutils@1.0.0-beta.57': {} - - '@rolldown/pluginutils@1.0.0-rc.3': {} - - '@rollup/rollup-android-arm-eabi@4.57.1': - optional: true - - '@rollup/rollup-android-arm64@4.57.1': - optional: true - - '@rollup/rollup-darwin-arm64@4.57.1': - optional: true - - '@rollup/rollup-darwin-x64@4.57.1': - optional: true - - '@rollup/rollup-freebsd-arm64@4.57.1': - optional: true - - '@rollup/rollup-freebsd-x64@4.57.1': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.57.1': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.57.1': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.57.1': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.57.1': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.57.1': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.57.1': + os: [openharmony] + requiresBuild: true + dev: true optional: true - '@rollup/rollup-linux-ppc64-gnu@4.57.1': + /@rolldown/binding-openharmony-arm64@1.0.3: + resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==, tarball: https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + requiresBuild: true + dev: true optional: true - '@rollup/rollup-linux-ppc64-musl@4.57.1': + /@rolldown/binding-wasm32-wasi@1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0): + resolution: {integrity: sha512-bRhcF7NLlCnpkzLVlVhrDEd0KH22VbTPkPTbMjlYvqhSmarxNIq5vtlQS8qmV7LkPKHrNLWyJW/V/sOyFba26Q==, tarball: https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.57.tgz} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + dev: true optional: true - '@rollup/rollup-linux-riscv64-gnu@4.57.1': + /@rolldown/binding-wasm32-wasi@1.0.0-rc.17: + resolution: {integrity: sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==, tarball: https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + dev: true optional: true - '@rollup/rollup-linux-riscv64-musl@4.57.1': + /@rolldown/binding-wasm32-wasi@1.0.3: + resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==, tarball: https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + dev: true optional: true - '@rollup/rollup-linux-s390x-gnu@4.57.1': + /@rolldown/binding-win32-arm64-msvc@1.0.0-beta.57: + resolution: {integrity: sha512-rnDVGRks2FQ2hgJ2g15pHtfxqkGFGjJQUDWzYznEkE8Ra2+Vag9OffxdbJMZqBWXHVM0iS4dv8qSiEn7bO+n1Q==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.57.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true optional: true - '@rollup/rollup-linux-x64-gnu@4.57.1': + /@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17: + resolution: {integrity: sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true optional: true - '@rollup/rollup-linux-x64-musl@4.57.1': + /@rolldown/binding-win32-arm64-msvc@1.0.3: + resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true optional: true - '@rollup/rollup-openbsd-x64@4.57.1': + /@rolldown/binding-win32-x64-msvc@1.0.0-beta.57: + resolution: {integrity: sha512-OqIUyNid1M4xTj6VRXp/Lht/qIP8fo25QyAZlCP+p6D2ATCEhyW4ZIFLnC9zAGN/HMbXoCzvwfa8Jjg/8J4YEg==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.57.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true optional: true - '@rollup/rollup-openharmony-arm64@4.57.1': + /@rolldown/binding-win32-x64-msvc@1.0.0-rc.17: + resolution: {integrity: sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true optional: true - '@rollup/rollup-win32-arm64-msvc@4.57.1': + /@rolldown/binding-win32-x64-msvc@1.0.3: + resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true optional: true - '@rollup/rollup-win32-ia32-msvc@4.57.1': - optional: true + /@rolldown/pluginutils@1.0.0-beta.57: + resolution: {integrity: sha512-aQNelgx14tGA+n2tNSa9x6/jeoCL9fkDeCei7nOKnHx0fEFRRMu5ReiITo+zZD5TzWDGGRjbSYCs93IfRIyTuQ==, tarball: https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.57.tgz} + dev: true - '@rollup/rollup-win32-x64-gnu@4.57.1': - optional: true + /@rolldown/pluginutils@1.0.0-rc.17: + resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==, tarball: https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz} + dev: true - '@rollup/rollup-win32-x64-msvc@4.57.1': - optional: true + /@rolldown/pluginutils@1.0.1: + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==, tarball: https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz} + dev: true - '@standard-schema/spec@1.1.0': {} + /@standard-schema/spec@1.1.0: + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==, tarball: https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz} + dev: true - '@tybys/wasm-util@0.10.1': + /@tybys/wasm-util@0.10.2: + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==, tarball: https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz} + requiresBuild: true dependencies: tslib: 2.8.1 + dev: true optional: true - '@types/chai@5.2.3': + /@types/chai@5.2.3: + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==, tarball: https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz} dependencies: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 + dev: true + + /@types/cytoscape@3.31.0: + resolution: {integrity: sha512-EXHOHxqQjGxLDEh5cP4te6J0bi7LbCzmZkzsR6f703igUac8UGMdEohMyU3GHAayCTZrLQOMnaE/lqB2Ekh8Ww==, tarball: https://registry.npmjs.org/@types/cytoscape/-/cytoscape-3.31.0.tgz} + deprecated: This is a stub types definition. cytoscape provides its own type definitions, so you do not need this installed. + dependencies: + cytoscape: 3.34.0 + dev: true - '@types/d3-array@3.2.2': {} + /@types/d3-array@3.2.2: + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==, tarball: https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz} + dev: true - '@types/d3-color@3.1.3': {} + /@types/d3-color@3.1.3: + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==, tarball: https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz} + dev: true - '@types/d3-drag@3.0.7': + /@types/d3-drag@3.0.7: + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==, tarball: https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz} dependencies: '@types/d3-selection': 3.0.11 + dev: true + + /@types/d3-force@3.0.10: + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==, tarball: https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz} + dev: true - '@types/d3-force@3.0.10': {} + /@types/d3-hierarchy@3.1.7: + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==, tarball: https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz} + dev: true - '@types/d3-interpolate@3.0.4': + /@types/d3-interpolate@3.0.4: + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==, tarball: https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz} dependencies: '@types/d3-color': 3.1.3 + dev: true - '@types/d3-selection@3.0.11': {} + /@types/d3-selection@3.0.11: + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==, tarball: https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz} + dev: true - '@types/d3-transition@3.0.9': + /@types/d3-transition@3.0.9: + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==, tarball: https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz} dependencies: '@types/d3-selection': 3.0.11 + dev: true - '@types/d3-zoom@3.0.8': + /@types/d3-zoom@3.0.8: + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==, tarball: https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz} dependencies: '@types/d3-interpolate': 3.0.4 '@types/d3-selection': 3.0.11 + dev: true - '@types/deep-eql@4.0.2': {} + /@types/deep-eql@4.0.2: + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==, tarball: https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz} + dev: true - '@types/estree@1.0.8': {} + /@types/estree@1.0.9: + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==, tarball: https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz} + dev: true - '@types/node@12.20.55': {} + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==, tarball: https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz} + dev: true - '@types/node@25.2.1': + /@types/node@25.9.3: + resolution: {integrity: sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==, tarball: https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz} dependencies: - undici-types: 7.16.0 + undici-types: 7.24.6 + dev: true - '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + /@vitest/coverage-v8@4.1.8(vitest@4.1.8): + resolution: {integrity: sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==, tarball: https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.8.tgz} + peerDependencies: + '@vitest/browser': 4.1.8 + vitest: 4.1.8 + peerDependenciesMeta: + '@vitest/browser': + optional: true dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.18 - ast-v8-to-istanbul: 0.3.12 + '@vitest/utils': 4.1.8 + ast-v8-to-istanbul: 1.0.4 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 magicast: 0.5.3 - obug: 2.1.1 - std-env: 3.10.0 + obug: 2.1.2 + std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.0.18(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16) + dev: true - '@vitest/expect@4.0.18': + /@vitest/expect@4.1.8: + resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==, tarball: https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz} dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 chai: 6.2.2 tinyrainbow: 3.1.0 + dev: true - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + /@vitest/mocker@4.1.8(vite@8.0.16): + resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==, tarball: https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.8.tgz} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true dependencies: - '@vitest/spy': 4.0.18 + '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 - optionalDependencies: - vite: 7.3.1(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 8.0.16(@types/node@25.9.3)(tsx@4.22.4) + dev: true - '@vitest/pretty-format@4.0.18': + /@vitest/pretty-format@4.1.8: + resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==, tarball: https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.8.tgz} dependencies: tinyrainbow: 3.1.0 + dev: true - '@vitest/runner@4.0.18': + /@vitest/runner@4.1.8: + resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==, tarball: https://registry.npmjs.org/@vitest/runner/-/runner-4.1.8.tgz} dependencies: - '@vitest/utils': 4.0.18 + '@vitest/utils': 4.1.8 pathe: 2.0.3 + dev: true - '@vitest/snapshot@4.0.18': + /@vitest/snapshot@4.1.8: + resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==, tarball: https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.8.tgz} dependencies: - '@vitest/pretty-format': 4.0.18 + '@vitest/pretty-format': 4.1.8 + '@vitest/utils': 4.1.8 magic-string: 0.30.21 pathe: 2.0.3 + dev: true - '@vitest/spy@4.0.18': {} + /@vitest/spy@4.1.8: + resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==, tarball: https://registry.npmjs.org/@vitest/spy/-/spy-4.1.8.tgz} + dev: true - '@vitest/utils@4.0.18': + /@vitest/utils@4.1.8: + resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==, tarball: https://registry.npmjs.org/@vitest/utils/-/utils-4.1.8.tgz} dependencies: - '@vitest/pretty-format': 4.0.18 + '@vitest/pretty-format': 4.1.8 + convert-source-map: 2.0.0 tinyrainbow: 3.1.0 + dev: true - '@xyflow/system@0.0.75': + /@xyflow/system@0.0.75: + resolution: {integrity: sha512-iXs+AGFLi8w/VlAoc/iSxk+CxfT6o64Uw/k0CKASOPqjqz6E0rb5jFZgJtXGZCpfQI6OQpu5EnumP5fGxQheaQ==, tarball: https://registry.npmjs.org/@xyflow/system/-/system-0.0.75.tgz} dependencies: '@types/d3-drag': 3.0.7 '@types/d3-interpolate': 3.0.4 @@ -2337,143 +1382,274 @@ snapshots: d3-interpolate: 3.0.1 d3-selection: 3.0.0 d3-zoom: 3.0.0 + dev: true + + /@yomguithereal/helpers@1.1.1: + resolution: {integrity: sha512-UYvAq/XCA7xoh1juWDYsq3W0WywOB+pz8cgVnE1b45ZfdMhBvHDrgmSFG3jXeZSr2tMTYLGHFHON+ekG05Jebg==, tarball: https://registry.npmjs.org/@yomguithereal/helpers/-/helpers-1.1.1.tgz} + dev: true - '@yomguithereal/helpers@1.1.1': {} + /ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==, tarball: https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz} + engines: {node: '>=6'} + dev: true - ansi-colors@4.1.3: {} + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, tarball: https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz} + engines: {node: '>=8'} + dev: true - ansi-regex@5.0.1: {} + /ansis@4.3.1: + resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==, tarball: https://registry.npmjs.org/ansis/-/ansis-4.3.1.tgz} + engines: {node: '>=14'} + dev: true - ansis@4.2.0: {} + /anynum@1.0.0: + resolution: {integrity: sha512-xjR9/zBVnUOP6ztMIIgShjsxui80nQUQH+5xJnvrYLs+90bF25/KJqaAi8mk+B4RDtX1Nspi6fmp4YTEts8SfA==, tarball: https://registry.npmjs.org/anynum/-/anynum-1.0.0.tgz} + dev: true - argparse@1.0.10: + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, tarball: https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz} dependencies: sprintf-js: 1.0.3 + dev: true - argparse@2.0.1: {} + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, tarball: https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz} + dev: true - args-tokenizer@0.3.0: {} + /args-tokenizer@0.3.0: + resolution: {integrity: sha512-xXAd7G2Mll5W8uo37GETpQ2VrE84M181Z7ugHFGQnJZ50M2mbOv0osSZ9VsSgPfJQ+LVG0prSi0th+ELMsno7Q==, tarball: https://registry.npmjs.org/args-tokenizer/-/args-tokenizer-0.3.0.tgz} + dev: true - array-union@2.1.0: {} + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, tarball: https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz} + engines: {node: '>=8'} + dev: true - assertion-error@2.0.1: {} + /assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==, tarball: https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz} + engines: {node: '>=12'} + dev: true - ast-kit@2.2.0: + /ast-kit@2.2.0: + resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==, tarball: https://registry.npmjs.org/ast-kit/-/ast-kit-2.2.0.tgz} + engines: {node: '>=20.19.0'} dependencies: '@babel/parser': 7.29.7 pathe: 2.0.3 + dev: true - ast-v8-to-istanbul@0.3.12: + /ast-v8-to-istanbul@1.0.4: + resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==, tarball: https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.4.tgz} dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 js-tokens: 10.0.0 + dev: true - better-path-resolve@1.0.0: + /better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==, tarball: https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz} + engines: {node: '>=4'} dependencies: is-windows: 1.0.2 + dev: true - birpc@4.0.0: {} + /birpc@4.0.0: + resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==, tarball: https://registry.npmjs.org/birpc/-/birpc-4.0.0.tgz} + dev: true - braces@3.0.3: + /braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, tarball: https://registry.npmjs.org/braces/-/braces-3.0.3.tgz} + engines: {node: '>=8'} dependencies: fill-range: 7.1.1 + dev: true - bumpp@10.4.1(magicast@0.5.3): + /bumpp@10.4.1: + resolution: {integrity: sha512-X/bwWs5Gbb/D7rN4aHLB7zdjiA6nGdjckM1sTHhI9oovIbEw2L5pw5S4xzk8ZTeOZ8EnwU/Ze4SoZ6/Vr3pM2Q==, tarball: https://registry.npmjs.org/bumpp/-/bumpp-10.4.1.tgz} + engines: {node: '>=18'} + hasBin: true dependencies: - ansis: 4.2.0 + ansis: 4.3.1 args-tokenizer: 0.3.0 - c12: 3.3.3(magicast@0.5.3) + c12: 3.3.4 cac: 6.7.14 escalade: 3.2.0 jsonc-parser: 3.3.1 package-manager-detector: 1.6.0 - semver: 7.7.4 - tinyexec: 1.0.2 - tinyglobby: 0.2.15 - yaml: 2.8.2 + semver: 7.8.4 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + yaml: 2.9.0 transitivePeerDependencies: - magicast + dev: true - c12@3.3.3(magicast@0.5.3): + /c12@3.3.4: + resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==, tarball: https://registry.npmjs.org/c12/-/c12-3.3.4.tgz} + peerDependencies: + magicast: '*' + peerDependenciesMeta: + magicast: + optional: true dependencies: chokidar: 5.0.0 confbox: 0.2.4 - defu: 6.1.4 - dotenv: 17.2.4 + defu: 6.1.7 + dotenv: 17.4.2 exsolve: 1.0.8 - giget: 2.0.0 - jiti: 2.6.1 + giget: 3.3.0 + jiti: 2.7.0 ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 2.1.0 - pkg-types: 2.3.0 - rc9: 2.1.2 - optionalDependencies: - magicast: 0.5.3 + pkg-types: 2.3.1 + rc9: 3.0.1 + dev: true - cac@6.7.14: {} + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, tarball: https://registry.npmjs.org/cac/-/cac-6.7.14.tgz} + engines: {node: '>=8'} + dev: true - chai@6.2.2: {} + /chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==, tarball: https://registry.npmjs.org/chai/-/chai-6.2.2.tgz} + engines: {node: '>=18'} + dev: true - chardet@2.1.1: {} + /chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==, tarball: https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz} + dev: true - chokidar@5.0.0: + /chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==, tarball: https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz} + engines: {node: '>= 20.19.0'} dependencies: readdirp: 5.0.0 + dev: true - ci-info@3.9.0: {} - - citty@0.1.6: - dependencies: - consola: 3.4.2 - - citty@0.2.0: {} + /confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==, tarball: https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz} + dev: true - confbox@0.2.4: {} + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, tarball: https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz} + dev: true - consola@3.4.2: {} - - cross-spawn@7.0.6: + /cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, tarball: https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz} + engines: {node: '>= 8'} dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + dev: true - cytoscape@3.33.1: {} + /cytoscape@3.34.0: + resolution: {integrity: sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==, tarball: https://registry.npmjs.org/cytoscape/-/cytoscape-3.34.0.tgz} + engines: {node: '>=0.10'} + dev: true - d3-array@3.2.4: + /d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==, tarball: https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz} + engines: {node: '>=12'} dependencies: internmap: 2.0.3 + dev: true - d3-color@3.1.0: {} + /d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==, tarball: https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz} + engines: {node: '>=12'} + dev: true + + /d3-dispatch@1.0.6: + resolution: {integrity: sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==, tarball: https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz} + dev: true + + /d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==, tarball: https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz} + engines: {node: '>=12'} + dev: true - d3-dispatch@3.0.1: {} + /d3-drag@1.2.5: + resolution: {integrity: sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==, tarball: https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz} + dependencies: + d3-dispatch: 1.0.6 + d3-selection: 1.4.2 + dev: true - d3-drag@3.0.0: + /d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==, tarball: https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz} + engines: {node: '>=12'} dependencies: d3-dispatch: 3.0.1 d3-selection: 3.0.0 + dev: true - d3-ease@3.0.1: {} + /d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==, tarball: https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz} + engines: {node: '>=12'} + dev: true - d3-force@3.0.0: + /d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==, tarball: https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz} + engines: {node: '>=12'} dependencies: d3-dispatch: 3.0.1 d3-quadtree: 3.0.1 d3-timer: 3.0.1 + dev: true + + /d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==, tarball: https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz} + engines: {node: '>=12'} + dev: true - d3-interpolate@3.0.1: + /d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==, tarball: https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz} + engines: {node: '>=12'} dependencies: d3-color: 3.1.0 + dev: true + + /d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==, tarball: https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz} + dev: true - d3-quadtree@3.0.1: {} + /d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==, tarball: https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz} + engines: {node: '>=12'} + dev: true + + /d3-selection@1.4.2: + resolution: {integrity: sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg==, tarball: https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz} + dev: true + + /d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==, tarball: https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz} + engines: {node: '>=12'} + dev: true + + /d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==, tarball: https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz} + dependencies: + d3-path: 1.0.9 + dev: true - d3-selection@3.0.0: {} + /d3-timer@1.0.10: + resolution: {integrity: sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==, tarball: https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz} + dev: true - d3-timer@3.0.1: {} + /d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==, tarball: https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz} + engines: {node: '>=12'} + dev: true - d3-transition@3.0.1(d3-selection@3.0.0): + /d3-transition@3.0.1(d3-selection@3.0.0): + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==, tarball: https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 dependencies: d3-color: 3.1.0 d3-dispatch: 3.0.1 @@ -2481,153 +1657,271 @@ snapshots: d3-interpolate: 3.0.1 d3-selection: 3.0.0 d3-timer: 3.0.1 + dev: true - d3-zoom@3.0.0: + /d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==, tarball: https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz} + engines: {node: '>=12'} dependencies: d3-dispatch: 3.0.1 d3-drag: 3.0.0 d3-interpolate: 3.0.1 d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) + dev: true - dataloader@1.4.0: {} + /dataloader@1.4.0: + resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==, tarball: https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz} + dev: true - defu@6.1.4: {} + /defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==, tarball: https://registry.npmjs.org/defu/-/defu-6.1.7.tgz} + dev: true - destr@2.0.5: {} + /destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==, tarball: https://registry.npmjs.org/destr/-/destr-2.0.5.tgz} + dev: true + + /detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==, tarball: https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz} + engines: {node: '>=8'} + dev: true - detect-indent@6.1.0: {} + /detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==, tarball: https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz} + engines: {node: '>=8'} + dev: true - dir-glob@3.0.1: + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, tarball: https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz} + engines: {node: '>=8'} dependencies: path-type: 4.0.0 + dev: true - dotenv@17.2.4: {} + /dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==, tarball: https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz} + engines: {node: '>=12'} + dev: true - dotenv@8.6.0: {} + /dotenv@8.6.0: + resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==, tarball: https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz} + engines: {node: '>=10'} + dev: true - dotparser@1.1.1: {} + /dotparser@1.1.1: + resolution: {integrity: sha512-8ojhUts0HbLnXJgjTiJOddwVVBUk6hg4SJ5kGiuhzgK/f+y79TiWvICwx1oCWlVbBC8YI3nEaIQg9fjGYbGBXw==, tarball: https://registry.npmjs.org/dotparser/-/dotparser-1.1.1.tgz} + dev: true - dts-resolver@2.1.3: {} + /dts-resolver@2.1.3: + resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==, tarball: https://registry.npmjs.org/dts-resolver/-/dts-resolver-2.1.3.tgz} + engines: {node: '>=20.19.0'} + peerDependencies: + oxc-resolver: '>=11.0.0' + peerDependenciesMeta: + oxc-resolver: + optional: true + dev: true - elkjs@0.11.1: {} + /elkjs@0.11.1: + resolution: {integrity: sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==, tarball: https://registry.npmjs.org/elkjs/-/elkjs-0.11.1.tgz} + dev: true - empathic@2.0.0: {} + /empathic@2.0.1: + resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==, tarball: https://registry.npmjs.org/empathic/-/empathic-2.0.1.tgz} + engines: {node: '>=14'} + dev: true - enquirer@2.4.1: + /enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==, tarball: https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz} + engines: {node: '>=8.6'} dependencies: ansi-colors: 4.1.3 strip-ansi: 6.0.1 + dev: true - es-module-lexer@1.7.0: {} + /es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==, tarball: https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz} + dev: true - esbuild@0.27.3: + /esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==, tarball: https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true optionalDependencies: - '@esbuild/aix-ppc64': 0.27.3 - '@esbuild/android-arm': 0.27.3 - '@esbuild/android-arm64': 0.27.3 - '@esbuild/android-x64': 0.27.3 - '@esbuild/darwin-arm64': 0.27.3 - '@esbuild/darwin-x64': 0.27.3 - '@esbuild/freebsd-arm64': 0.27.3 - '@esbuild/freebsd-x64': 0.27.3 - '@esbuild/linux-arm': 0.27.3 - '@esbuild/linux-arm64': 0.27.3 - '@esbuild/linux-ia32': 0.27.3 - '@esbuild/linux-loong64': 0.27.3 - '@esbuild/linux-mips64el': 0.27.3 - '@esbuild/linux-ppc64': 0.27.3 - '@esbuild/linux-riscv64': 0.27.3 - '@esbuild/linux-s390x': 0.27.3 - '@esbuild/linux-x64': 0.27.3 - '@esbuild/netbsd-arm64': 0.27.3 - '@esbuild/netbsd-x64': 0.27.3 - '@esbuild/openbsd-arm64': 0.27.3 - '@esbuild/openbsd-x64': 0.27.3 - '@esbuild/openharmony-arm64': 0.27.3 - '@esbuild/sunos-x64': 0.27.3 - '@esbuild/win32-arm64': 0.27.3 - '@esbuild/win32-ia32': 0.27.3 - '@esbuild/win32-x64': 0.27.3 - - escalade@3.2.0: {} - - esprima@4.0.1: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.8 - - events@3.3.0: {} - - expect-type@1.3.0: {} - - exsolve@1.0.8: {} - - extendable-error@0.1.7: {} - - fast-glob@3.3.3: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + dev: true + + /escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, tarball: https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz} + engines: {node: '>=6'} + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, tarball: https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz} + engines: {node: '>=4'} + hasBin: true + dev: true + + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, tarball: https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz} + dependencies: + '@types/estree': 1.0.9 + dev: true + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==, tarball: https://registry.npmjs.org/events/-/events-3.3.0.tgz} + engines: {node: '>=0.8.x'} + dev: true + + /expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==, tarball: https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz} + engines: {node: '>=12.0.0'} + dev: true + + /exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==, tarball: https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz} + dev: true + + /extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==, tarball: https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz} + dev: true + + /fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, tarball: https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz} + engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.8 + dev: true - fast-xml-parser@5.3.4: + /fast-xml-builder@1.2.0: + resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==, tarball: https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz} dependencies: - strnum: 2.1.2 + path-expression-matcher: 1.5.0 + xml-naming: 0.1.0 + dev: true - fastq@1.20.1: + /fast-xml-parser@5.8.0: + resolution: {integrity: sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==, tarball: https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz} + hasBin: true + dependencies: + '@nodable/entities': 2.1.1 + fast-xml-builder: 1.2.0 + path-expression-matcher: 1.5.0 + strnum: 2.4.0 + xml-naming: 0.1.0 + dev: true + + /fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==, tarball: https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz} dependencies: reusify: 1.1.0 + dev: true - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 + /fdir@6.5.0(picomatch@4.0.4): + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, tarball: https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + dependencies: + picomatch: 4.0.4 + dev: true - fill-range@7.1.1: + /fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, tarball: https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz} + engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 + dev: true - find-up@4.1.0: + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, tarball: https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz} + engines: {node: '>=8'} dependencies: locate-path: 5.0.0 path-exists: 4.0.0 + dev: true - fs-extra@7.0.1: + /fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==, tarball: https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz} + engines: {node: '>=6 <7 || >=8'} dependencies: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 + dev: true - fs-extra@8.1.0: + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==, tarball: https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz} + engines: {node: '>=6 <7 || >=8'} dependencies: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 + dev: true - fsevents@2.3.3: + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true optional: true - get-tsconfig@4.13.6: + /get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==, tarball: https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz} dependencies: resolve-pkg-maps: 1.0.0 + dev: true - giget@2.0.0: - dependencies: - citty: 0.1.6 - consola: 3.4.2 - defu: 6.1.4 - node-fetch-native: 1.6.7 - nypm: 0.6.5 - pathe: 2.0.3 + /giget@3.3.0: + resolution: {integrity: sha512-gzi2D96p+AMfDcmJHGDj3KJ9NRiwvlFAU5yfa3ROwWZmFUjX4P43x3BcyRaOMMLto1vUo7C+86+MFhYTl6Ryiw==, tarball: https://registry.npmjs.org/giget/-/giget-3.3.0.tgz} + hasBin: true + dev: true - glob-parent@5.1.2: + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, tarball: https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz} + engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 + dev: true - globby@11.1.0: + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, tarball: https://registry.npmjs.org/globby/-/globby-11.1.0.tgz} + engines: {node: '>=10'} dependencies: array-union: 2.1.0 dir-glob: 3.0.1 @@ -2635,22 +1929,45 @@ snapshots: ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 + dev: true - graceful-fs@4.2.11: {} + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, tarball: https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz} + dev: true - graphology-components@1.5.4(graphology-types@0.24.8): + /graphology-components@1.5.4(graphology-types@0.24.8): + resolution: {integrity: sha512-O37vC226wgnN0C6FUWHNe4fbTzaF51CcQjwX3naId/QTzH/PkUtXaanCShj9ws5Vju+z4u3zvSeEZE84Bo9jlA==, tarball: https://registry.npmjs.org/graphology-components/-/graphology-components-1.5.4.tgz} + peerDependencies: + graphology-types: '>=0.19.0' dependencies: graphology-indices: 0.17.0(graphology-types@0.24.8) graphology-types: 0.24.8 graphology-utils: 2.5.2(graphology-types@0.24.8) + dev: true - graphology-indices@0.17.0(graphology-types@0.24.8): + /graphology-indices@0.17.0(graphology-types@0.24.8): + resolution: {integrity: sha512-A7RXuKQvdqSWOpn7ZVQo4S33O0vCfPBnUSf7FwE0zNCasqwZVUaCXePuWo5HBpWw68KJcwObZDHpFk6HKH6MYQ==, tarball: https://registry.npmjs.org/graphology-indices/-/graphology-indices-0.17.0.tgz} + peerDependencies: + graphology-types: '>=0.20.0' dependencies: graphology-types: 0.24.8 graphology-utils: 2.5.2(graphology-types@0.24.8) mnemonist: 0.39.8 + dev: true + + /graphology-layout-forceatlas2@0.10.1(graphology-types@0.24.8): + resolution: {integrity: sha512-ogzBeF1FvWzjkikrIFwxhlZXvD2+wlY54lqhsrWprcdPjopM2J9HoMweUmIgwaTvY4bUYVimpSsOdvDv1gPRFQ==, tarball: https://registry.npmjs.org/graphology-layout-forceatlas2/-/graphology-layout-forceatlas2-0.10.1.tgz} + peerDependencies: + graphology-types: '>=0.19.0' + dependencies: + graphology-types: 0.24.8 + graphology-utils: 2.5.2(graphology-types@0.24.8) + dev: true - graphology-metrics@2.4.0(graphology-types@0.24.8): + /graphology-metrics@2.4.0(graphology-types@0.24.8): + resolution: {integrity: sha512-7WOfOP+mFLCaTJx55Qg4eY+211vr1/b3D/R3biz3SXGhAaCVcWYkfabnmO4O4WBNWANEHtVnFrGgJ0kj6MM6xw==, tarball: https://registry.npmjs.org/graphology-metrics/-/graphology-metrics-2.4.0.tgz} + peerDependencies: + graphology-types: '>=0.20.0' dependencies: graphology-indices: 0.17.0(graphology-types@0.24.8) graphology-shortest-path: 2.1.0(graphology-types@0.24.8) @@ -2658,265 +1975,612 @@ snapshots: graphology-utils: 2.5.2(graphology-types@0.24.8) mnemonist: 0.39.8 pandemonium: 2.4.1 + dev: true - graphology-shortest-path@2.1.0(graphology-types@0.24.8): + /graphology-shortest-path@2.1.0(graphology-types@0.24.8): + resolution: {integrity: sha512-KbT9CTkP/u72vGEJzyRr24xFC7usI9Es3LMmCPHGwQ1KTsoZjxwA9lMKxfU0syvT/w+7fZUdB/Hu2wWYcJBm6Q==, tarball: https://registry.npmjs.org/graphology-shortest-path/-/graphology-shortest-path-2.1.0.tgz} + peerDependencies: + graphology-types: '>=0.20.0' dependencies: '@yomguithereal/helpers': 1.1.1 graphology-indices: 0.17.0(graphology-types@0.24.8) graphology-types: 0.24.8 graphology-utils: 2.5.2(graphology-types@0.24.8) mnemonist: 0.39.8 + dev: true - graphology-types@0.24.8: {} + /graphology-types@0.24.8: + resolution: {integrity: sha512-hDRKYXa8TsoZHjgEaysSRyPdT6uB78Ci8WnjgbStlQysz7xR52PInxNsmnB7IBOM1BhikxkNyCVEFgmPKnpx3Q==, tarball: https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.8.tgz} + dev: true - graphology-utils@2.5.2(graphology-types@0.24.8): + /graphology-utils@2.5.2(graphology-types@0.24.8): + resolution: {integrity: sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==, tarball: https://registry.npmjs.org/graphology-utils/-/graphology-utils-2.5.2.tgz} + peerDependencies: + graphology-types: '>=0.23.0' dependencies: graphology-types: 0.24.8 + dev: true - graphology@0.26.0(graphology-types@0.24.8): + /graphology@0.26.0(graphology-types@0.24.8): + resolution: {integrity: sha512-8SSImzgUUYC89Z042s+0r/vMibY7GX/Emz4LDO5e7jYXhuoWfHISPFJYjpRLUSJGq6UQ6xlenvX1p/hJdfXuXg==, tarball: https://registry.npmjs.org/graphology/-/graphology-0.26.0.tgz} + peerDependencies: + graphology-types: '>=0.24.0' dependencies: events: 3.3.0 graphology-types: 0.24.8 + dev: true - has-flag@4.0.0: {} + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, tarball: https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz} + engines: {node: '>=8'} + dev: true - hookable@6.0.1: {} + /hookable@6.1.1: + resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==, tarball: https://registry.npmjs.org/hookable/-/hookable-6.1.1.tgz} + dev: true - html-escaper@2.0.2: {} + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, tarball: https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz} + dev: true - human-id@4.1.3: {} + /human-id@4.2.0: + resolution: {integrity: sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==, tarball: https://registry.npmjs.org/human-id/-/human-id-4.2.0.tgz} + hasBin: true + dev: true - iconv-lite@0.7.2: + /iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==, tarball: https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz} + engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 + dev: true - ignore@5.3.2: {} + /ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, tarball: https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz} + engines: {node: '>= 4'} + dev: true - import-without-cache@0.2.5: {} + /import-without-cache@0.2.5: + resolution: {integrity: sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==, tarball: https://registry.npmjs.org/import-without-cache/-/import-without-cache-0.2.5.tgz} + engines: {node: '>=20.19.0'} + dev: true - internmap@2.0.3: {} + /internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==, tarball: https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz} + engines: {node: '>=12'} + dev: true - is-extglob@2.1.1: {} + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, tarball: https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz} + engines: {node: '>=0.10.0'} + dev: true - is-glob@4.0.3: + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, tarball: https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz} + engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 + dev: true - is-number@7.0.0: {} + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, tarball: https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz} + engines: {node: '>=0.12.0'} + dev: true - is-subdir@1.2.0: + /is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==, tarball: https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz} + engines: {node: '>=4'} dependencies: better-path-resolve: 1.0.0 + dev: true + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==, tarball: https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz} + engines: {node: '>=0.10.0'} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, tarball: https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz} + dev: true + + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, tarball: https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, tarball: https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==, tarball: https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==, tarball: https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz} + hasBin: true + dev: true + + /js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==, tarball: https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz} + dev: true + + /js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==, tarball: https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true - is-windows@1.0.2: {} + /js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==, tarball: https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==, tarball: https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==, tarball: https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz} + dev: true + + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==, tarball: https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==, tarball: https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true - isexe@2.0.0: {} + /lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==, tarball: https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true - istanbul-lib-coverage@3.2.2: {} + /lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==, tarball: https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 + /lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==, tarball: https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true - istanbul-reports@3.2.0: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 + /lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==, tarball: https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true - jiti@2.6.1: {} + /lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==, tarball: https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true - js-tokens@10.0.0: {} + /lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==, tarball: https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true - js-yaml@3.14.2: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 + /lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==, tarball: https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true - js-yaml@4.1.1: - dependencies: - argparse: 2.0.1 + /lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==, tarball: https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true - jsesc@3.1.0: {} + /lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==, tarball: https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true - jsonc-parser@3.3.1: {} + /lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==, tarball: https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true - jsonfile@4.0.0: + /lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==, tarball: https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz} + engines: {node: '>= 12.0.0'} + dependencies: + detect-libc: 2.1.2 optionalDependencies: - graceful-fs: 4.2.11 - - locate-path@5.0.0: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, tarball: https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz} + engines: {node: '>=8'} dependencies: p-locate: 4.1.0 + dev: true - lodash.startcase@4.4.0: {} + /lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==, tarball: https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz} + dev: true - magic-string@0.30.21: + /magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, tarball: https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz} dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + dev: true - magicast@0.5.3: + /magicast@0.5.3: + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==, tarball: https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz} dependencies: '@babel/parser': 7.29.7 '@babel/types': 7.29.7 source-map-js: 1.2.1 + dev: true - make-dir@4.0.0: + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, tarball: https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz} + engines: {node: '>=10'} dependencies: - semver: 7.7.4 + semver: 7.8.4 + dev: true - merge2@1.4.1: {} + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, tarball: https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz} + engines: {node: '>= 8'} + dev: true - micromatch@4.0.8: + /micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, tarball: https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz} + engines: {node: '>=8.6'} dependencies: braces: 3.0.3 - picomatch: 2.3.1 + picomatch: 2.3.2 + dev: true - mnemonist@0.39.8: + /mnemonist@0.39.8: + resolution: {integrity: sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==, tarball: https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz} dependencies: obliterator: 2.0.5 + dev: true - mri@1.2.0: {} + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==, tarball: https://registry.npmjs.org/mri/-/mri-1.2.0.tgz} + engines: {node: '>=4'} + dev: true - nanoid@3.3.11: {} + /nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==, tarball: https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true - ngraph.events@1.4.0: {} + /ngraph.events@1.4.0: + resolution: {integrity: sha512-NeDGI4DSyjBNBRtA86222JoYietsmCXbs8CEB0dZ51Xeh4lhVl1y3wpWLumczvnha8sFQIW4E0vvVWwgmX2mGw==, tarball: https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.4.0.tgz} + dev: true - ngraph.graph@20.1.2: + /ngraph.graph@20.1.2: + resolution: {integrity: sha512-W/G3GBR3Y5UxMLHTUCPP9v+pbtpzwuAEIqP5oZV+9IwgxAIEZwh+Foc60iPc1idlnK7Zxu0p3puxAyNmDvBd0Q==, tarball: https://registry.npmjs.org/ngraph.graph/-/ngraph.graph-20.1.2.tgz} dependencies: ngraph.events: 1.4.0 + dev: true - ngraph.path@1.6.1: {} - - node-fetch-native@1.6.7: {} + /ngraph.path@1.6.1: + resolution: {integrity: sha512-NiA52wAoRo/t36/1dBAZkXPeX+rQ1mn82bc9LSfnfywGY9TxH/jXw3x3fZ1mOCblyln26lHtfHHEzssjjyX+aw==, tarball: https://registry.npmjs.org/ngraph.path/-/ngraph.path-1.6.1.tgz} + dev: true - node-fetch@2.7.0: + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==, tarball: https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true dependencies: whatwg-url: 5.0.0 + dev: true - nypm@0.6.5: - dependencies: - citty: 0.2.0 - pathe: 2.0.3 - tinyexec: 1.0.2 - - obliterator@2.0.5: {} + /obliterator@2.0.5: + resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==, tarball: https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz} + dev: true - obug@2.1.1: {} + /obug@2.1.2: + resolution: {integrity: sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==, tarball: https://registry.npmjs.org/obug/-/obug-2.1.2.tgz} + engines: {node: '>=12.20.0'} + dev: true - ohash@2.0.11: {} + /ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==, tarball: https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz} + dev: true - outdent@0.5.0: {} + /outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==, tarball: https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz} + dev: true - p-filter@2.1.0: + /p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==, tarball: https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz} + engines: {node: '>=8'} dependencies: p-map: 2.1.0 + dev: true - p-limit@2.3.0: + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, tarball: https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz} + engines: {node: '>=6'} dependencies: p-try: 2.2.0 + dev: true - p-locate@4.1.0: + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, tarball: https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz} + engines: {node: '>=8'} dependencies: p-limit: 2.3.0 + dev: true - p-map@2.1.0: {} + /p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==, tarball: https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz} + engines: {node: '>=6'} + dev: true - p-try@2.2.0: {} + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, tarball: https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz} + engines: {node: '>=6'} + dev: true - package-manager-detector@0.2.11: + /package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==, tarball: https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz} dependencies: quansync: 0.2.11 + dev: true - package-manager-detector@1.6.0: {} + /package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==, tarball: https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz} + dev: true - pandemonium@2.4.1: + /pandemonium@2.4.1: + resolution: {integrity: sha512-wRqjisUyiUfXowgm7MFH2rwJzKIr20rca5FsHXCMNm1W5YPP1hCtrZfgmQ62kP7OZ7Xt+cR858aB28lu5NX55g==, tarball: https://registry.npmjs.org/pandemonium/-/pandemonium-2.4.1.tgz} dependencies: mnemonist: 0.39.8 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, tarball: https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz} + engines: {node: '>=8'} + dev: true - path-exists@4.0.0: {} + /path-expression-matcher@1.5.0: + resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==, tarball: https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz} + engines: {node: '>=14.0.0'} + dev: true - path-key@3.1.1: {} + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, tarball: https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz} + engines: {node: '>=8'} + dev: true - path-type@4.0.0: {} + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, tarball: https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz} + engines: {node: '>=8'} + dev: true - pathe@2.0.3: {} + /pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, tarball: https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz} + dev: true - perfect-debounce@2.1.0: {} + /perfect-debounce@2.1.0: + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==, tarball: https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz} + dev: true - picocolors@1.1.1: {} + /picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, tarball: https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz} + dev: true - picomatch@2.3.1: {} + /picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==, tarball: https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz} + engines: {node: '>=8.6'} + dev: true - picomatch@4.0.3: {} + /picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==, tarball: https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz} + engines: {node: '>=12'} + dev: true - pify@4.0.1: {} + /pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==, tarball: https://registry.npmjs.org/pify/-/pify-4.0.1.tgz} + engines: {node: '>=6'} + dev: true - pkg-types@2.3.0: + /pkg-types@2.3.1: + resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==, tarball: https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.1.tgz} dependencies: confbox: 0.2.4 exsolve: 1.0.8 pathe: 2.0.3 + dev: true - postcss@8.5.6: + /postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==, tarball: https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz} + engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 + dev: true - prettier@2.8.8: {} + /prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==, tarball: https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true - publint@0.3.18: + /publint@0.3.21: + resolution: {integrity: sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ==, tarball: https://registry.npmjs.org/publint/-/publint-0.3.21.tgz} + engines: {node: '>=18'} + hasBin: true dependencies: '@publint/pack': 0.1.4 package-manager-detector: 1.6.0 picocolors: 1.1.1 sade: 1.8.1 + dev: true - quansync@0.2.11: {} + /quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==, tarball: https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz} + dev: true - quansync@1.0.0: {} + /quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==, tarball: https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz} + dev: true - queue-microtask@1.2.3: {} + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, tarball: https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz} + dev: true - rc9@2.1.2: + /rc9@3.0.1: + resolution: {integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==, tarball: https://registry.npmjs.org/rc9/-/rc9-3.0.1.tgz} dependencies: - defu: 6.1.4 + defu: 6.1.7 destr: 2.0.5 + dev: true - read-yaml-file@1.1.0: + /read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==, tarball: https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz} + engines: {node: '>=6'} dependencies: graceful-fs: 4.2.11 js-yaml: 3.14.2 pify: 4.0.1 strip-bom: 3.0.0 + dev: true - readdirp@5.0.0: {} + /readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==, tarball: https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz} + engines: {node: '>= 20.19.0'} + dev: true - resolve-from@5.0.0: {} + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, tarball: https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz} + engines: {node: '>=8'} + dev: true - resolve-pkg-maps@1.0.0: {} + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==, tarball: https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz} + dev: true - reusify@1.1.0: {} + /reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, tarball: https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true - rolldown-plugin-dts@0.20.0(rolldown@1.0.0-beta.57)(typescript@5.9.3): + /rolldown-plugin-dts@0.20.0(rolldown@1.0.0-beta.57)(typescript@5.9.3): + resolution: {integrity: sha512-cLAY1kN2ilTYMfZcFlGWbXnu6Nb+8uwUBsi+Mjbh4uIx7IN8uMOmJ7RxrrRgPsO4H7eSz3E+JwGoL1gyugiyUA==, tarball: https://registry.npmjs.org/rolldown-plugin-dts/-/rolldown-plugin-dts-0.20.0.tgz} + engines: {node: '>=20.19.0'} + peerDependencies: + '@ts-macro/tsc': ^0.3.6 + '@typescript/native-preview': '>=7.0.0-dev.20250601.1' + rolldown: ^1.0.0-beta.57 + typescript: ^5.0.0 + vue-tsc: ~3.2.0 + peerDependenciesMeta: + '@ts-macro/tsc': + optional: true + '@typescript/native-preview': + optional: true + typescript: + optional: true + vue-tsc: + optional: true dependencies: - '@babel/generator': 7.29.1 + '@babel/generator': 7.29.7 '@babel/parser': 7.29.7 '@babel/types': 7.29.7 ast-kit: 2.2.0 birpc: 4.0.0 dts-resolver: 2.1.3 - get-tsconfig: 4.13.6 - obug: 2.1.1 - rolldown: 1.0.0-beta.57 - optionalDependencies: + get-tsconfig: 4.14.0 + obug: 2.1.2 + rolldown: 1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) typescript: 5.9.3 transitivePeerDependencies: - oxc-resolver + dev: true - rolldown@1.0.0-beta.57: + /rolldown@1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0): + resolution: {integrity: sha512-lMMxcNN71GMsSko8RyeTaFoATHkCh4IWU7pYF73ziMYjhHZWfVesC6GQ+iaJCvZmVjvgSks9Ks1aaqEkBd8udg==, tarball: https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.57.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true dependencies: '@oxc-project/types': 0.103.0 '@rolldown/pluginutils': 1.0.0-beta.57 @@ -2931,255 +2595,481 @@ snapshots: '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.57 '@rolldown/binding-linux-x64-musl': 1.0.0-beta.57 '@rolldown/binding-openharmony-arm64': 1.0.0-beta.57 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.57 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.57 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.57 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + dev: true - rolldown@1.0.0-rc.3: + /rolldown@1.0.0-rc.17: + resolution: {integrity: sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==, tarball: https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true dependencies: - '@oxc-project/types': 0.112.0 - '@rolldown/pluginutils': 1.0.0-rc.3 + '@oxc-project/types': 0.127.0 + '@rolldown/pluginutils': 1.0.0-rc.17 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.3 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.3 - '@rolldown/binding-darwin-x64': 1.0.0-rc.3 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.3 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.3 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.3 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.3 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.3 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.3 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.3 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.3 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.3 - - rollup@4.57.1: - dependencies: - '@types/estree': 1.0.8 + '@rolldown/binding-android-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-x64': 1.0.0-rc.17 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.17 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 + dev: true + + /rolldown@1.0.3: + resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==, tarball: https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + dependencies: + '@oxc-project/types': 0.133.0 + '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.57.1 - '@rollup/rollup-android-arm64': 4.57.1 - '@rollup/rollup-darwin-arm64': 4.57.1 - '@rollup/rollup-darwin-x64': 4.57.1 - '@rollup/rollup-freebsd-arm64': 4.57.1 - '@rollup/rollup-freebsd-x64': 4.57.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.57.1 - '@rollup/rollup-linux-arm-musleabihf': 4.57.1 - '@rollup/rollup-linux-arm64-gnu': 4.57.1 - '@rollup/rollup-linux-arm64-musl': 4.57.1 - '@rollup/rollup-linux-loong64-gnu': 4.57.1 - '@rollup/rollup-linux-loong64-musl': 4.57.1 - '@rollup/rollup-linux-ppc64-gnu': 4.57.1 - '@rollup/rollup-linux-ppc64-musl': 4.57.1 - '@rollup/rollup-linux-riscv64-gnu': 4.57.1 - '@rollup/rollup-linux-riscv64-musl': 4.57.1 - '@rollup/rollup-linux-s390x-gnu': 4.57.1 - '@rollup/rollup-linux-x64-gnu': 4.57.1 - '@rollup/rollup-linux-x64-musl': 4.57.1 - '@rollup/rollup-openbsd-x64': 4.57.1 - '@rollup/rollup-openharmony-arm64': 4.57.1 - '@rollup/rollup-win32-arm64-msvc': 4.57.1 - '@rollup/rollup-win32-ia32-msvc': 4.57.1 - '@rollup/rollup-win32-x64-gnu': 4.57.1 - '@rollup/rollup-win32-x64-msvc': 4.57.1 - fsevents: 2.3.3 - - run-parallel@1.2.0: + '@rolldown/binding-android-arm64': 1.0.3 + '@rolldown/binding-darwin-arm64': 1.0.3 + '@rolldown/binding-darwin-x64': 1.0.3 + '@rolldown/binding-freebsd-x64': 1.0.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.3 + '@rolldown/binding-linux-arm64-musl': 1.0.3 + '@rolldown/binding-linux-ppc64-gnu': 1.0.3 + '@rolldown/binding-linux-s390x-gnu': 1.0.3 + '@rolldown/binding-linux-x64-gnu': 1.0.3 + '@rolldown/binding-linux-x64-musl': 1.0.3 + '@rolldown/binding-openharmony-arm64': 1.0.3 + '@rolldown/binding-wasm32-wasi': 1.0.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.3 + '@rolldown/binding-win32-x64-msvc': 1.0.3 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, tarball: https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz} dependencies: queue-microtask: 1.2.3 + dev: true - sade@1.8.1: + /sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==, tarball: https://registry.npmjs.org/sade/-/sade-1.8.1.tgz} + engines: {node: '>=6'} dependencies: mri: 1.2.0 + dev: true - safer-buffer@2.1.2: {} + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, tarball: https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz} + dev: true - semver@7.7.4: {} + /semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==, tarball: https://registry.npmjs.org/semver/-/semver-7.8.4.tgz} + engines: {node: '>=10'} + hasBin: true + dev: true - shebang-command@2.0.0: + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, tarball: https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz} + engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 + dev: true - shebang-regex@3.0.0: {} + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, tarball: https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz} + engines: {node: '>=8'} + dev: true - siginfo@2.0.0: {} + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, tarball: https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz} + dev: true - signal-exit@4.1.0: {} + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, tarball: https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz} + engines: {node: '>=14'} + dev: true - slash@3.0.0: {} + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, tarball: https://registry.npmjs.org/slash/-/slash-3.0.0.tgz} + engines: {node: '>=8'} + dev: true - source-map-js@1.2.1: {} + /source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, tarball: https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz} + engines: {node: '>=0.10.0'} + dev: true - spawndamnit@3.0.1: + /spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==, tarball: https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz} dependencies: cross-spawn: 7.0.6 signal-exit: 4.1.0 + dev: true - sprintf-js@1.0.3: {} + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, tarball: https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz} + dev: true - stackback@0.0.2: {} + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, tarball: https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz} + dev: true - std-env@3.10.0: {} + /std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==, tarball: https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz} + dev: true - strip-ansi@6.0.1: + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, tarball: https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz} + engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 + dev: true - strip-bom@3.0.0: {} + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, tarball: https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz} + engines: {node: '>=4'} + dev: true - strnum@2.1.2: {} + /strnum@2.4.0: + resolution: {integrity: sha512-sHrVyWWdq28RbhjuJdZsA1SnGRJV6NiXbk6AXBxDOsgAcA+lmpUZCYjOdLBxkXMwis6RRe7dlZt4VlIWFVzkmg==, tarball: https://registry.npmjs.org/strnum/-/strnum-2.4.0.tgz} + dependencies: + anynum: 1.0.0 + dev: true - supports-color@7.2.0: + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, tarball: https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz} + engines: {node: '>=8'} dependencies: has-flag: 4.0.0 + dev: true - term-size@2.2.1: {} + /term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==, tarball: https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz} + engines: {node: '>=8'} + dev: true - tinybench@2.9.0: {} + /tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==, tarball: https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz} + dev: true - tinyexec@1.0.2: {} + /tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==, tarball: https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz} + engines: {node: '>=18'} + dev: true - tinyglobby@0.2.15: + /tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==, tarball: https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz} + engines: {node: '>=12.0.0'} dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - tinyrainbow@3.0.3: {} + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + dev: true - tinyrainbow@3.1.0: {} + /tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==, tarball: https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz} + engines: {node: '>=14.0.0'} + dev: true - to-regex-range@5.0.1: + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, tarball: https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz} + engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 + dev: true - tr46@0.0.3: {} + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, tarball: https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz} + dev: true - tree-kill@1.2.2: {} + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==, tarball: https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz} + hasBin: true + dev: true - tsdown@0.18.4(publint@0.3.18)(typescript@5.9.3): + /tsdown@0.18.4(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)(publint@0.3.21)(typescript@5.9.3): + resolution: {integrity: sha512-J/tRS6hsZTkvqmt4+xdELUCkQYDuUCXgBv0fw3ImV09WPGbEKfsPD65E+WUjSu3E7Z6tji9XZ1iWs8rbGqB/ZA==, tarball: https://registry.npmjs.org/tsdown/-/tsdown-0.18.4.tgz} + engines: {node: '>=20.19.0'} + hasBin: true + peerDependencies: + '@arethetypeswrong/core': ^0.18.1 + '@vitejs/devtools': '*' + publint: ^0.3.0 + typescript: ^5.0.0 + unplugin-lightningcss: ^0.4.0 + unplugin-unused: ^0.5.0 + peerDependenciesMeta: + '@arethetypeswrong/core': + optional: true + '@vitejs/devtools': + optional: true + publint: + optional: true + typescript: + optional: true + unplugin-lightningcss: + optional: true + unplugin-unused: + optional: true dependencies: - ansis: 4.2.0 + ansis: 4.3.1 cac: 6.7.14 - defu: 6.1.4 - empathic: 2.0.0 - hookable: 6.0.1 + defu: 6.1.7 + empathic: 2.0.1 + hookable: 6.1.1 import-without-cache: 0.2.5 - obug: 2.1.1 - picomatch: 4.0.3 - rolldown: 1.0.0-beta.57 + obug: 2.1.2 + picomatch: 4.0.4 + publint: 0.3.21 + rolldown: 1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) rolldown-plugin-dts: 0.20.0(rolldown@1.0.0-beta.57)(typescript@5.9.3) - semver: 7.7.4 - tinyexec: 1.0.2 - tinyglobby: 0.2.15 + semver: 7.8.4 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 tree-kill: 1.2.2 - unconfig-core: 7.4.2 - unrun: 0.2.27 - optionalDependencies: - publint: 0.3.18 typescript: 5.9.3 + unconfig-core: 7.5.0 + unrun: 0.2.39 transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - '@ts-macro/tsc' - '@typescript/native-preview' - oxc-resolver - synckit - vue-tsc + dev: true - tslib@2.8.1: + /tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, tarball: https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz} + dev: true optional: true - tsx@4.21.0: + /tsx@4.22.4: + resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==, tarball: https://registry.npmjs.org/tsx/-/tsx-4.22.4.tgz} + engines: {node: '>=18.0.0'} + hasBin: true dependencies: - esbuild: 0.27.3 - get-tsconfig: 4.13.6 + esbuild: 0.28.1 optionalDependencies: fsevents: 2.3.3 + dev: true - typescript@5.9.3: {} + /typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==, tarball: https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz} + engines: {node: '>=14.17'} + hasBin: true + dev: true - unconfig-core@7.4.2: + /unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==, tarball: https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.5.0.tgz} dependencies: '@quansync/fs': 1.0.0 quansync: 1.0.0 + dev: true - undici-types@7.16.0: {} + /undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==, tarball: https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz} + dev: true - universalify@0.1.2: {} + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==, tarball: https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz} + engines: {node: '>= 4.0.0'} + dev: true - unrun@0.2.27: + /unrun@0.2.39: + resolution: {integrity: sha512-h9FxYVpztY/wwq+bauLOh6Y3CWu2IVeRLq5lxzneBiIU9Tn86OGp9xiQrGhnYspAmg5dzdY0Cc8+Y70kuTARCg==, tarball: https://registry.npmjs.org/unrun/-/unrun-0.2.39.tgz} + engines: {node: '>=20.19.0'} + hasBin: true + peerDependencies: + synckit: ^0.11.11 + peerDependenciesMeta: + synckit: + optional: true dependencies: - rolldown: 1.0.0-rc.3 + rolldown: 1.0.0-rc.17 + dev: true - vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): + /vite@8.0.16(@types/node@25.9.3)(tsx@4.22.4): + resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==, tarball: https://registry.npmjs.org/vite/-/vite-8.0.16.tgz} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.18 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true dependencies: - esbuild: 0.27.3 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.57.1 - tinyglobby: 0.2.15 + '@types/node': 25.9.3 + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.15 + rolldown: 1.0.3 + tinyglobby: 0.2.17 + tsx: 4.22.4 optionalDependencies: - '@types/node': 25.2.1 fsevents: 2.3.3 - jiti: 2.6.1 - tsx: 4.21.0 - yaml: 2.8.2 - - vitest@4.0.18(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): - dependencies: - '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) - '@vitest/pretty-format': 4.0.18 - '@vitest/runner': 4.0.18 - '@vitest/snapshot': 4.0.18 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 - es-module-lexer: 1.7.0 + dev: true + + /vitest@4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16): + resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==, tarball: https://registry.npmjs.org/vitest/-/vitest-4.1.8.tgz} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.8 + '@vitest/browser-preview': 4.1.8 + '@vitest/browser-webdriverio': 4.1.8 + '@vitest/coverage-istanbul': 4.1.8 + '@vitest/coverage-v8': 4.1.8 + '@vitest/ui': 4.1.8 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/node': 25.9.3 + '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) + '@vitest/expect': 4.1.8 + '@vitest/mocker': 4.1.8(vite@8.0.16) + '@vitest/pretty-format': 4.1.8 + '@vitest/runner': 4.1.8 + '@vitest/snapshot': 4.1.8 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 - obug: 2.1.1 + obug: 2.1.2 pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.10.0 + picomatch: 4.0.4 + std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 1.0.2 - tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.2.1)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.0.16(@types/node@25.9.3)(tsx@4.22.4) why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 25.2.1 transitivePeerDependencies: - - jiti - - less - - lightningcss - msw - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml + dev: true + + /webcola@3.4.0: + resolution: {integrity: sha512-4BiLXjXw3SJHo3Xd+rF+7fyClT6n7I+AR6TkBqyQ4kTsePSAMDLRCXY1f3B/kXJeP9tYn4G1TblxTO+jAt0gaw==, tarball: https://registry.npmjs.org/webcola/-/webcola-3.4.0.tgz} + dependencies: + d3-dispatch: 1.0.6 + d3-drag: 1.2.5 + d3-shape: 1.3.7 + d3-timer: 1.0.10 + dev: true - webidl-conversions@3.0.1: {} + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, tarball: https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz} + dev: true - whatwg-url@5.0.0: + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, tarball: https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 + dev: true - which@2.0.2: + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, tarball: https://registry.npmjs.org/which/-/which-2.0.2.tgz} + engines: {node: '>= 8'} + hasBin: true dependencies: isexe: 2.0.0 + dev: true - why-is-node-running@2.3.0: + /why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==, tarball: https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz} + engines: {node: '>=8'} + hasBin: true dependencies: siginfo: 2.0.0 stackback: 0.0.2 + dev: true + + /xml-naming@0.1.0: + resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==, tarball: https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz} + engines: {node: '>=16.0.0'} + dev: true - xstate@5.28.0: {} + /xstate@5.32.0: + resolution: {integrity: sha512-zsk73aWGmxn9z34P0kbiod5JwTvdYRW3+IDxITq8sd9+VWwMyW7BUzpplnYy9mIEXa6V8IMDv7Hy4m0mhT5+2Q==, tarball: https://registry.npmjs.org/xstate/-/xstate-5.32.0.tgz} + dev: true - yaml@2.8.2: {} + /yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==, tarball: https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz} + engines: {node: '>= 14.6'} + hasBin: true + dev: true - zod@4.3.6: {} + /zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==, tarball: https://registry.npmjs.org/zod/-/zod-4.4.3.tgz} + dev: true From 9ee5a99de3874f5e9689325afd7a6f4fa85fd7c1 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:17:40 -0400 Subject: [PATCH 02/15] feat(layout): genLayoutTransition, translateGraph/centerGraph, constraints.layer (ELK partitions, dot rank=same) --- src/layout/elk.ts | 25 ++++++ src/layout/graphviz.ts | 18 +++++ src/layout/index.ts | 137 ++++++++++++++++++++++++++++++++ tests/layout/core.test.ts | 144 +++++++++++++++++++++++++++++++++- tests/layout/elk.test.ts | 25 ++++++ tests/layout/graphviz.test.ts | 27 +++++++ 6 files changed, 375 insertions(+), 1 deletion(-) diff --git a/src/layout/elk.ts b/src/layout/elk.ts index b86dc69..bee2178 100644 --- a/src/layout/elk.ts +++ b/src/layout/elk.ts @@ -70,8 +70,33 @@ export async function getElkLayout( }); const root = toELK(sized); + + // constraints.layer → ELK partitions (same value = same layer, ordered + // along the flow axis) + const layerOf = options?.constraints?.layer; + let hasPartitions = false; + if (layerOf) { + const nodeById = new Map(sized.nodes.map((node) => [node.id, node])); + const visit = (elkNode: ElkNode): void => { + for (const child of elkNode.children ?? []) { + const node = nodeById.get(child.id); + const layer = node === undefined ? undefined : layerOf(node); + if (layer !== undefined) { + hasPartitions = true; + child.layoutOptions = { + ...child.layoutOptions, + 'elk.partitioning.partition': String(layer), + }; + } + visit(child); + } + }; + visit(root); + } + root.layoutOptions = { 'elk.algorithm': options?.algorithm ?? 'layered', + ...(hasPartitions && { 'elk.partitioning.activate': 'true' }), ...(options?.spacing?.node !== undefined && { 'elk.spacing.nodeNode': String(options.spacing.node), }), diff --git a/src/layout/graphviz.ts b/src/layout/graphviz.ts index 34a3c29..a79bbd3 100644 --- a/src/layout/graphviz.ts +++ b/src/layout/graphviz.ts @@ -150,6 +150,8 @@ let graphvizPromise: Promise | undefined; * has no directed edge operator). * - `options.seed` maps to the Graphviz `start` attribute (used by the * randomized engines neato/fdp/sfdp; ignored by deterministic engines). + * - `options.constraints.layer` maps to `{ rank=same; … }` groups (`dot` + * engine only — the other engines have no rank concept). * * @example * ```ts @@ -208,6 +210,22 @@ export async function getGraphvizLayout( ` ${escapeId(node.id)} [width=${width / POINTS_PER_INCH}, height=${height / POINTS_PER_INCH}, fixedsize=true, shape=box];`, ); } + // constraints.layer → dot rank=same groups (same-layer grouping; ordering + // between layers still follows the edges). Other engines have no ranks. + const layerOf = options?.constraints?.layer; + if (engine === 'dot' && layerOf) { + const layers = new Map(); + for (const node of graph.nodes) { + const layer = layerOf(node); + if (layer === undefined) continue; + let ids = layers.get(layer); + if (ids === undefined) layers.set(layer, (ids = [])); + ids.push(node.id); + } + for (const [, ids] of [...layers].sort((a, b) => a[0] - b[0])) { + lines.push(` { rank=same; ${ids.map(escapeId).join('; ')}; }`); + } + } for (const edge of graph.edges) { const attrs: string[] = []; if (edge.label) attrs.push(`label="${escapeLabel(edge.label)}"`); diff --git a/src/layout/index.ts b/src/layout/index.ts index 857776d..ebb6193 100644 --- a/src/layout/index.ts +++ b/src/layout/index.ts @@ -5,6 +5,7 @@ import type { Point, VisualGraph, } from '../types'; +import { getLCA } from '../queries'; /** * Common options understood by every layout adapter. Engine-specific options @@ -35,6 +36,32 @@ export interface LayoutOptions { isFixed?: (node: GraphNode) => boolean; /** Seed for engines with randomness — same seed, same layout. */ seed?: number; + /** + * Portable layout constraints. **Advisory**, like port `direction`: engines + * that can express a constraint honor it, others ignore it. Per-adapter + * support is documented on each adapter. + */ + constraints?: LayoutConstraints; +} + +/** + * Portable constraints understood by (some) layout adapters. + * + * | Constraint | ELK | Graphviz (dot) | dagre | force engines | + * |------------|-----|----------------|-------|----------------| + * | `layer` | partitions | `rank=same` groups | ignored | ignored | + */ +export interface LayoutConstraints { + /** + * Assign nodes to ordered layers along the flow axis (`0`, `1`, `2`, …; + * `undefined` leaves the node unconstrained). Nodes with the same value + * land in the same layer; smaller values come earlier in the layout + * direction. ELK maps this to partitions + * (`elk.partitioning.partition`); the Graphviz `dot` engine maps it to + * `{ rank=same; … }` groups (same-layer grouping — ordering *between* + * constrained layers still follows the edges). + */ + layer?: (node: GraphNode) => number | undefined; } /** @@ -151,3 +178,113 @@ export function getLayoutBounds(graph: Graph | VisualGraph): EntityRect { if (minX === Infinity) return { x: 0, y: 0, width: 0, height: 0 }; return { x: minX, y: minY, width: maxX - minX, height: maxY - minY }; } + +export interface LayoutTransitionOptions { + /** Number of frames to yield. Default: 30. */ + steps?: number; + /** + * Easing function mapping linear progress `t` (0 → 1] to eased progress. + * Default: smoothstep (`t² · (3 − 2t)`). + */ + ease?: (t: number) => number; +} + +/** + * Animate between two layouts of the same graph: yields interpolated + * {@link LayoutFrame}s from the node positions in `from` to those in `to` + * (drive them with {@link applyLayoutFrame}, e.g. one per animation frame), + * and returns `to`. This is what makes layouts swappable live — lay out with + * one engine, re-lay out with another, and tween between them. + * + * Nodes are matched by id; nodes without a position in `from` (or absent from + * it) start at their `to` position. Edge routes are not interpolated — frames + * carry node positions only; hide or re-route edges during the transition. + * `alpha` cools linearly 1 → 0 like the physics layouts. + * + * @example + * ```ts + * const next = await getElkLayout(graph); + * for (const frame of genLayoutTransition(graph, next)) { + * applyLayoutFrame(graph, frame); + * render(graph); + * } + * ``` + */ +export function* genLayoutTransition( + from: Graph | VisualGraph, + to: VisualGraph, + options?: LayoutTransitionOptions, +): Generator { + const steps = Math.max(1, Math.floor(options?.steps ?? 30)); + const ease = options?.ease ?? ((t: number) => t * t * (3 - 2 * t)); + const fromById = new Map(from.nodes.map((node) => [node.id, node])); + const tweens = to.nodes.map((node) => { + const fromNode = fromById.get(node.id); + const hasStart = fromNode?.x !== undefined && fromNode.y !== undefined; + return { + id: node.id, + startX: hasStart ? fromNode.x! : node.x, + startY: hasStart ? fromNode.y! : node.y, + endX: node.x, + endY: node.y, + }; + }); + + for (let step = 1; step <= steps; step++) { + const t = ease(step / steps); + const positions: LayoutFrame['positions'] = {}; + for (const tween of tweens) { + positions[tween.id] = { + x: tween.startX + (tween.endX - tween.startX) * t, + y: tween.startY + (tween.endY - tween.startY) * t, + }; + } + yield { positions, alpha: 1 - step / steps }; + } + return to; +} + +/** + * **Mutable.** Shift the graph's geometry by `(dx, dy)` in place: node + * positions, edge route `points`, and edge label rects. Non-structural, so no + * index invalidation is needed. + * + * Hierarchy-aware: child nodes (`parentId` set) use parent-relative + * coordinates (the ELK/xyflow convention), so only top-level nodes are + * shifted — children move with their parents. Likewise, an edge's geometry is + * shifted only when its containing coordinate system is the root (the LCA of + * its endpoints is no node). + */ +export function translateGraph(graph: Graph, dx: number, dy: number): void { + for (const node of graph.nodes) { + if (node.parentId != null) continue; + if (node.x !== undefined) node.x += dx; + if (node.y !== undefined) node.y += dy; + } + for (const edge of graph.edges) { + if (getLCA(graph, edge.sourceId, edge.targetId) !== undefined) continue; + if (edge.x !== undefined) edge.x += dx; + if (edge.y !== undefined) edge.y += dy; + for (const point of edge.points ?? []) { + point.x += dx; + point.y += dy; + } + } +} + +/** + * **Mutable.** Translate the graph in place so its {@link getLayoutBounds} + * center coincides with `rect`'s center — e.g. center a fresh layout in the + * viewport. Graphs without geometry are left untouched. + * + * @example + * ```ts + * centerGraph(laidOut, { x: 0, y: 0, width: canvas.width, height: canvas.height }); + * ``` + */ +export function centerGraph(graph: Graph, rect: EntityRect): void { + const bounds = getLayoutBounds(graph); + const dx = rect.x + rect.width / 2 - (bounds.x + bounds.width / 2); + const dy = rect.y + rect.height / 2 - (bounds.y + bounds.height / 2); + translateGraph(graph, dx, dy); +} diff --git a/tests/layout/core.test.ts b/tests/layout/core.test.ts index d2eae12..78de11c 100644 --- a/tests/layout/core.test.ts +++ b/tests/layout/core.test.ts @@ -1,10 +1,13 @@ import { describe, it, expect } from 'vitest'; -import { createGraph } from '../../src'; +import { createGraph, createVisualGraph } from '../../src'; import { DEFAULT_NODE_SIZE, applyLayoutFrame, + centerGraph, + genLayoutTransition, getLayoutBounds, getNodeSize, + translateGraph, } from '../../src/layout'; describe('getNodeSize', () => { @@ -80,3 +83,142 @@ describe('getLayoutBounds', () => { }); }); }); + +describe('genLayoutTransition', () => { + const from = createGraph({ + nodes: [ + { id: 'a', x: 0, y: 0, width: 10, height: 10 }, + { id: 'b', width: 10, height: 10 }, // unpositioned + ], + }); + const to = createVisualGraph({ + nodes: [ + { id: 'a', x: 100, y: 50, width: 10, height: 10 }, + { id: 'b', x: 30, y: 40, width: 10, height: 10 }, + ], + }); + + it('interpolates from start to end and returns the target graph', () => { + const frames = []; + const gen = genLayoutTransition(from, to, { steps: 4 }); + let step = gen.next(); + while (!step.done) { + frames.push(step.value); + step = gen.next(); + } + expect(step.value).toBe(to); + expect(frames).toHaveLength(4); + // last frame lands exactly on the target + expect(frames[3].positions.a).toEqual({ x: 100, y: 50 }); + expect(frames[3].alpha).toBe(0); + // intermediate frames are strictly between start and end + expect(frames[1].positions.a.x).toBeGreaterThan(0); + expect(frames[1].positions.a.x).toBeLessThan(100); + }); + + it('starts unmatched/unpositioned nodes at their target position', () => { + const [first] = genLayoutTransition(from, to, { steps: 2 }); + expect(first.positions.b).toEqual({ x: 30, y: 40 }); + }); + + it('supports a custom ease', () => { + const frames = [...genLayoutTransition(from, to, { steps: 2, ease: () => 1 })]; + expect(frames[0].positions.a).toEqual({ x: 100, y: 50 }); + }); + + it('drives applyLayoutFrame to morph the live graph', () => { + const live = createGraph({ + nodes: [{ id: 'a', x: 0, y: 0, width: 10, height: 10 }], + }); + const target = createVisualGraph({ + nodes: [{ id: 'a', x: 10, y: 10, width: 10, height: 10 }], + }); + for (const frame of genLayoutTransition(live, target, { steps: 5 })) { + applyLayoutFrame(live, frame); + } + expect(live.nodes[0]).toMatchObject({ x: 10, y: 10 }); + }); +}); + +describe('translateGraph', () => { + it('shifts nodes, edge points, and edge label rects in place', () => { + const g = createGraph({ + nodes: [ + { id: 'a', x: 0, y: 0, width: 10, height: 10 }, + { id: 'b', x: 100, y: 50 }, + { id: 'unpositioned' }, + ], + edges: [ + { + id: 'e', + sourceId: 'a', + targetId: 'b', + x: 40, + y: 20, + points: [ + { x: 5, y: 5 }, + { x: 100, y: 55 }, + ], + }, + ], + }); + translateGraph(g, 7, -3); + expect(g.nodes[0]).toMatchObject({ x: 7, y: -3 }); + expect(g.nodes[1]).toMatchObject({ x: 107, y: 47 }); + expect(g.nodes[2].x).toBeUndefined(); + expect(g.edges[0]).toMatchObject({ x: 47, y: 17 }); + expect(g.edges[0].points).toEqual([ + { x: 12, y: 2 }, + { x: 107, y: 52 }, + ]); + }); + + it('leaves parent-relative children and nested-edge geometry alone', () => { + const g = createGraph({ + nodes: [ + { id: 'parent', x: 10, y: 10, width: 200, height: 200 }, + { id: 'child1', parentId: 'parent', x: 5, y: 5 }, + { id: 'child2', parentId: 'parent', x: 50, y: 5 }, + ], + edges: [ + { + id: 'inner', + sourceId: 'child1', + targetId: 'child2', + points: [ + { x: 5, y: 5 }, + { x: 50, y: 5 }, + ], + }, + ], + }); + translateGraph(g, 100, 100); + expect(g.nodes[0]).toMatchObject({ x: 110, y: 110 }); + expect(g.nodes[1]).toMatchObject({ x: 5, y: 5 }); + expect(g.edges[0].points).toEqual([ + { x: 5, y: 5 }, + { x: 50, y: 5 }, + ]); + }); +}); + +describe('centerGraph', () => { + it('centers the layout bounds on the rect center', () => { + const g = createGraph({ + nodes: [ + { id: 'a', x: 0, y: 0, width: 10, height: 10 }, + { id: 'b', x: 90, y: 40, width: 10, height: 10 }, + ], + }); + centerGraph(g, { x: 0, y: 0, width: 500, height: 300 }); + const bounds = getLayoutBounds(g); + expect(bounds.x + bounds.width / 2).toBe(250); + expect(bounds.y + bounds.height / 2).toBe(150); + }); + + it('is a no-op for graphs without geometry', () => { + const g = createGraph({ nodes: [{ id: 'a' }] }); + centerGraph(g, { x: 0, y: 0, width: 500, height: 300 }); + expect(g.nodes[0].x).toBeUndefined(); + }); +}); diff --git a/tests/layout/elk.test.ts b/tests/layout/elk.test.ts index 126d13c..1e3c3d9 100644 --- a/tests/layout/elk.test.ts +++ b/tests/layout/elk.test.ts @@ -110,4 +110,29 @@ describe('getElkLayout', () => { getLayoutBounds(tight).height, ); }); + + it('maps constraints.layer to ELK partitions', async () => { + // Fan a→b, a→c: unconstrained layered puts b and c in the same layer; + // partitioning b=1, c=2 forces c into a later layer than b. + const layers: Record = { a: 0, b: 1, c: 2 }; + const make = () => + createGraph({ + direction: 'down', + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b' }, + { id: 'e2', sourceId: 'a', targetId: 'c' }, + ], + }); + const free = await getElkLayout(make()); + const freeById = Object.fromEntries(free.nodes.map((n) => [n.id, n])); + expect(freeById.c.y).toBe(freeById.b.y); + + const constrained = await getElkLayout(make(), { + constraints: { layer: (node) => layers[node.id] }, + }); + const byId = Object.fromEntries(constrained.nodes.map((n) => [n.id, n])); + expect(byId.a.y).toBeLessThan(byId.b.y); + expect(byId.b.y).toBeLessThan(byId.c.y); + }); }); diff --git a/tests/layout/graphviz.test.ts b/tests/layout/graphviz.test.ts index be4fa93..8910215 100644 --- a/tests/layout/graphviz.test.ts +++ b/tests/layout/graphviz.test.ts @@ -207,4 +207,31 @@ describe('getGraphvizLayout', () => { ); expect(laidOut.edges.map(strip)).toEqual(graph.edges.map(strip)); }); + + it('maps constraints.layer to dot rank=same groups', async () => { + // a→x and b→x: unconstrained dot puts a and b in the rank above x, but + // constraining b to x's layer forces them onto the same rank. + const make = () => + createGraph({ + direction: 'down', + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'x' }], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'x' }, + { id: 'e2', sourceId: 'b', targetId: 'x' }, + ], + }); + const center = (n: { y: number; height: number }) => n.y + n.height / 2; + + const free = await getGraphvizLayout(make()); + const freeById = Object.fromEntries(free.nodes.map((n) => [n.id, n])); + expect(center(freeById.b)).toBeCloseTo(center(freeById.a), 3); + expect(center(freeById.b)).toBeLessThan(center(freeById.x)); + + const constrained = await getGraphvizLayout(make(), { + constraints: { layer: (node) => ({ b: 1, x: 1 } as Record)[node.id] }, + }); + const byId = Object.fromEntries(constrained.nodes.map((n) => [n.id, n])); + expect(center(byId.b)).toBeCloseTo(center(byId.x), 3); + expect(center(byId.a)).toBeLessThan(center(byId.b)); + }); }); From 96ab6650c03c9e357990960dd92603b0d8dfd82f Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:17:57 -0400 Subject: [PATCH 03/15] feat(layout): ForceAtlas2, tidy-tree (d3-hierarchy), and WebCola adapters --- src/layout/d3-hierarchy.ts | 184 ++++++++++++++++++++++++++++++ src/layout/forceatlas2.ts | 135 ++++++++++++++++++++++ src/layout/webcola.ts | 139 ++++++++++++++++++++++ tests/layout/d3-hierarchy.test.ts | 112 ++++++++++++++++++ tests/layout/forceatlas2.test.ts | 84 ++++++++++++++ tests/layout/webcola.test.ts | 121 ++++++++++++++++++++ 6 files changed, 775 insertions(+) create mode 100644 src/layout/d3-hierarchy.ts create mode 100644 src/layout/forceatlas2.ts create mode 100644 src/layout/webcola.ts create mode 100644 tests/layout/d3-hierarchy.test.ts create mode 100644 tests/layout/forceatlas2.test.ts create mode 100644 tests/layout/webcola.test.ts diff --git a/src/layout/d3-hierarchy.ts b/src/layout/d3-hierarchy.ts new file mode 100644 index 0000000..bd7a496 --- /dev/null +++ b/src/layout/d3-hierarchy.ts @@ -0,0 +1,184 @@ +import { hierarchy, tree } from 'd3-hierarchy'; +import type { Graph, VisualGraph } from '../types'; +import { createVisualGraph, hasNode } from '../graph'; +import { toNodeConfig, toEdgeConfig } from '../config'; +import { getSources, getSuccessors } from '../queries'; +import { getNodeSize, type LayoutOptions } from './index'; + +export interface TidyTreeLayoutOptions extends LayoutOptions { + /** + * Node to use as the tree root. Defaults to `graph.initialNodeId`, falling + * back to the graph's zero-in-degree nodes (multiple → laid out as a + * forest). + */ + rootId?: string; +} + +/** Spanning-tree datum fed to d3.hierarchy. `id: null` is the synthetic root. */ +interface TreeDatum { + id: string | null; + children: TreeDatum[]; +} + +// Same defaults as the dagre adapter's nodesep/ranksep. +const DEFAULT_NODE_SPACING = 50; +const DEFAULT_LAYER_SPACING = 50; + +/** + * Lay out a graph as a tidy tree (Reingold–Tilford) with `d3-hierarchy` + * (an optional peer dependency). Pure and synchronous: returns a new + * {@link VisualGraph} with node positions/sizes. + * + * Root selection: `options.rootId` → `graph.initialNodeId` → the graph's + * zero-in-degree nodes. Multiple zero-in-degree nodes are laid out as a + * forest (side by side under an invisible synthetic root that is dropped + * from the output). If no root can be found (every node has incoming edges, + * i.e. the graph is cyclic), this throws — pass `rootId` to break the tie. + * + * Graphs that aren't strict trees are handled via a *spanning tree*: BFS + * from the root over effective edge direction picks each node's tree parent + * (first edge to reach it); only that spanning tree drives positions. All + * edges — including the extra cross/forward/back edges — are preserved + * untouched in the output. Tidy tree does not route edges (no `points`). + * + * @example + * ```ts + * import { getTidyTreeLayout } from '@statelyai/graph/layout/d3-hierarchy'; + * + * const laidOut = getTidyTreeLayout(graph, { direction: 'right' }); + * ``` + */ +export function getTidyTreeLayout( + graph: Graph | VisualGraph, + options?: TidyTreeLayoutOptions, +): VisualGraph { + const direction = options?.direction ?? graph.direction ?? 'down'; + + if (graph.nodes.length === 0) { + return createVisualGraph({ + id: graph.id, + mode: graph.mode, + direction, + data: graph.data, + ...(graph.style !== undefined && { style: graph.style }), + nodes: [], + edges: graph.edges.map(toEdgeConfig), + }); + } + + // --- Root selection --- + let rootIds: string[]; + if (options?.rootId !== undefined) { + if (!hasNode(graph, options.rootId)) { + throw new Error( + `getTidyTreeLayout: rootId "${options.rootId}" does not exist in graph "${graph.id}". ` + + `Pass the id of an existing node.`, + ); + } + rootIds = [options.rootId]; + } else if ( + graph.initialNodeId != null && + hasNode(graph, graph.initialNodeId) + ) { + rootIds = [graph.initialNodeId]; + } else { + rootIds = getSources(graph).map((node) => node.id); + if (rootIds.length === 0) { + throw new Error( + `getTidyTreeLayout: no tree root found in graph "${graph.id}" — all ` + + `${graph.nodes.length} nodes have incoming edges (the graph is cyclic). ` + + `Pass options.rootId or set graph.initialNodeId to choose where the tree starts.`, + ); + } + } + + // --- Spanning forest: BFS from each root over effective edge direction. + // The first edge to reach a node becomes its tree parent; remaining edges + // do not affect positions but are preserved in the output. + const visited = new Set(); + const buildSpanningTree = (rootId: string): TreeDatum => { + const root: TreeDatum = { id: rootId, children: [] }; + visited.add(rootId); + const queue = [root]; + while (queue.length > 0) { + const datum = queue.shift()!; + for (const successor of getSuccessors(graph, datum.id!)) { + if (visited.has(successor.id)) continue; + visited.add(successor.id); + const child: TreeDatum = { id: successor.id, children: [] }; + datum.children.push(child); + queue.push(child); + } + } + return root; + }; + const trees = rootIds.map(buildSpanningTree); + // Nodes unreachable from any root (e.g. a detached cyclic component) become + // extra forest roots so every node gets a position. + for (const node of graph.nodes) { + if (!visited.has(node.id)) trees.push(buildSpanningTree(node.id)); + } + + // --- Tidy tree layout --- + // d3.tree's x is the breadth coordinate, y is depth; for horizontal + // directions the node's breadth dimension is its height. + const isHorizontal = direction === 'left' || direction === 'right'; + const sizes = new Map( + graph.nodes.map((node) => [node.id, getNodeSize(node, options)]), + ); + let maxBreadth = 0; + let maxDepth = 0; + for (const size of sizes.values()) { + maxBreadth = Math.max(maxBreadth, isHorizontal ? size.height : size.width); + maxDepth = Math.max(maxDepth, isHorizontal ? size.width : size.height); + } + const breadthStep = maxBreadth + (options?.spacing?.node ?? DEFAULT_NODE_SPACING); + const depthStep = maxDepth + (options?.spacing?.layer ?? DEFAULT_LAYER_SPACING); + + const isForest = trees.length > 1; + const rootDatum: TreeDatum = isForest + ? { id: null, children: trees } // invisible synthetic root, dropped below + : trees[0]; + const laidOut = tree().nodeSize([breadthStep, depthStep])( + hierarchy(rootDatum), + ); + + // d3 reports node centers; convert depth/breadth to our axes, then to + // top-left. The synthetic root occupies depth 0 — shift it away. + const centers = new Map(); + for (const point of laidOut.descendants()) { + if (point.data.id === null) continue; + const breadth = point.x; + const depth = point.y - (isForest ? depthStep : 0); + centers.set( + point.data.id, + direction === 'down' + ? { x: breadth, y: depth } + : direction === 'up' + ? { x: breadth, y: -depth } + : direction === 'right' + ? { x: depth, y: breadth } + : { x: -depth, y: breadth }, + ); + } + + return createVisualGraph({ + id: graph.id, + mode: graph.mode, + initialNodeId: graph.initialNodeId ?? undefined, + direction, + data: graph.data, + ...(graph.style !== undefined && { style: graph.style }), + nodes: graph.nodes.map((node) => { + const size = sizes.get(node.id)!; + const center = centers.get(node.id)!; + return { + ...toNodeConfig(node), + ...size, + x: center.x - size.width / 2, + y: center.y - size.height / 2, + }; + }), + edges: graph.edges.map(toEdgeConfig), + }); +} diff --git a/src/layout/forceatlas2.ts b/src/layout/forceatlas2.ts new file mode 100644 index 0000000..29b5654 --- /dev/null +++ b/src/layout/forceatlas2.ts @@ -0,0 +1,135 @@ +import GraphologyGraph from 'graphology'; +import forceAtlas2, { + type ForceAtlas2Settings, +} from 'graphology-layout-forceatlas2'; +import type { Graph, VisualGraph } from '../types'; +import { createVisualGraph } from '../graph'; +import { toNodeConfig, toEdgeConfig } from '../config'; +import { getNodeSize, type LayoutOptions } from './index'; + +export interface ForceAtlas2LayoutOptions extends LayoutOptions { + /** Number of ForceAtlas2 iterations. Default: 100. */ + iterations?: number; + /** + * Pass-through engine settings (`scalingRatio`, `gravity`, `linLogMode`, + * `barnesHutOptimize`, …). See graphology-layout-forceatlas2. + */ + settings?: ForceAtlas2Settings; +} + +/** mulberry32 — same seeded PRNG the rest of the library uses. */ +function mulberry32(seed: number): () => number { + let s = seed | 0; + return () => { + s = (s + 0x6d2b79f5) | 0; + let t = Math.imul(s ^ (s >>> 15), 1 | s); + t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; +} + +/** + * One-shot ForceAtlas2 layout via graphology (optional peer dependencies + * `graphology` + `graphology-layout-forceatlas2`). Runs the synchronous + * engine for `options.iterations` iterations and returns a positioned + * {@link VisualGraph}. + * + * - Deterministic: FA2 itself has no randomness, but it requires initial + * positions. Positioned nodes start from their current centers + * (incremental relayout); unpositioned nodes start in a seeded scatter + * driven by `options.seed` — the same seed always produces the same + * layout. + * - `options.isFixed` pins positioned nodes at their current `x`/`y` via + * FA2's `fixed` node attribute (honored natively by the engine). + * - Per-edge `weight` feeds FA2's attraction (its default edge-weight + * getter reads the `weight` attribute; tune with + * `settings.edgeWeightInfluence`). + * - Self-loops are skipped (zero-distance edges destabilize the forces); + * parallel edges are kept (multigraph). Hierarchy is ignored (force + * layouts are flat). + * + * @example + * ```ts + * import { getForceAtlas2Layout } from '@statelyai/graph/layout/forceatlas2'; + * + * const laidOut = getForceAtlas2Layout(graph, { + * seed: 42, + * iterations: 200, + * settings: { gravity: 2 }, + * }); + * ``` + */ +export function getForceAtlas2Layout( + graph: Graph | VisualGraph, + options?: ForceAtlas2LayoutOptions, +): VisualGraph { + const rng = mulberry32(options?.seed ?? 1); + const sizes = new Map(); + const scatterRadius = Math.max(80, 30 * Math.sqrt(graph.nodes.length)); + const engineGraph = new GraphologyGraph({ multi: true }); + + for (const node of graph.nodes) { + const size = getNodeSize(node, options); + sizes.set(node.id, size); + if (node.x !== undefined && node.y !== undefined) { + // Existing positions (centers) seed the engine — incremental relayout + // starts from the current arrangement + engineGraph.addNode(node.id, { + x: node.x + size.width / 2, + y: node.y + size.height / 2, + ...(options?.isFixed?.(node) && { fixed: true }), + }); + } else { + // Unpositioned nodes start in a seeded scatter — FA2 throws on nodes + // without coordinates, and the scatter is what makes `seed` produce + // genuinely different (but reproducible) arrangements + const angle = rng() * 2 * Math.PI; + const radius = scatterRadius * Math.sqrt(rng()); + engineGraph.addNode(node.id, { + x: Math.cos(angle) * radius, + y: Math.sin(angle) * radius, + }); + } + } + for (const edge of graph.edges) { + if ( + !sizes.has(edge.sourceId) || + !sizes.has(edge.targetId) || + edge.sourceId === edge.targetId + ) { + continue; + } + engineGraph.addEdgeWithKey( + edge.id, + edge.sourceId, + edge.targetId, + edge.weight !== undefined ? { weight: edge.weight } : {}, + ); + } + + const positions = forceAtlas2(engineGraph, { + iterations: options?.iterations ?? 100, + ...(options?.settings !== undefined && { settings: options.settings }), + }); + + return createVisualGraph({ + id: graph.id, + mode: graph.mode, + initialNodeId: graph.initialNodeId ?? undefined, + direction: graph.direction, + data: graph.data, + ...(graph.style !== undefined && { style: graph.style }), + nodes: graph.nodes.map((node) => { + const size = sizes.get(node.id)!; + const position = positions[node.id]; + return { + ...toNodeConfig(node), + ...size, + // FA2 positions are centers; VisualNode.x/y are top-left + x: position.x - size.width / 2, + y: position.y - size.height / 2, + }; + }), + edges: graph.edges.map((edge) => toEdgeConfig(edge)), + }); +} diff --git a/src/layout/webcola.ts b/src/layout/webcola.ts new file mode 100644 index 0000000..dc3265c --- /dev/null +++ b/src/layout/webcola.ts @@ -0,0 +1,139 @@ +import { Layout, type InputNode, type Link } from 'webcola'; +import type { Graph, VisualGraph } from '../types'; +import { createVisualGraph } from '../graph'; +import { toNodeConfig, toEdgeConfig } from '../config'; +import { getNodeSize, type LayoutOptions } from './index'; + +export interface ColaLayoutOptions extends LayoutOptions { + /** Target distance between linked nodes. Default: 80. */ + linkDistance?: number; +} + +interface ColaNode extends InputNode { + id: string; + width: number; + height: number; +} + +/** mulberry32 — same seeded PRNG the rest of the library uses. */ +function mulberry32(seed: number): () => number { + let s = seed | 0; + return () => { + s = (s + 0x6d2b79f5) | 0; + let t = Math.imul(s ^ (s >>> 15), 1 | s); + t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; +} + +/** + * Constraint-based layout via WebCola (optional peer dependency). Runs the + * solver to convergence synchronously (`keepRunning: false`) and returns a + * positioned {@link VisualGraph}. + * + * - Overlap avoidance is always on: node rects (from `options.measure` → + * node `width`/`height` → defaults) are kept disjoint. + * - Deterministic: WebCola itself has no `Math.random` in its 2D solver + * (its descent uses an internally seeded PRNG), so the seeded initial + * scatter (`options.seed`) fully pins the result — same seed, same layout. + * - `options.isFixed` pins positioned nodes at their current `x`/`y` (cola's + * `fixed` flag). During overlap projection cola holds fixed nodes with a + * large-but-finite weight, so pinning is within a small tolerance, not + * exact. + * - `options.direction ?? graph.direction` set → DAG-flow constraints via + * cola's `flowLayout`: edges are separated along the axis ('down'/'up' → + * `y`, 'left'/'right' → `x`) by at least `spacing.layer` (default 50). + * Note: cola only separates source-before-target along the axis — 'up' and + * 'left' flow the same way as 'down'/'right', not reversed. + * - Hierarchy is ignored (flat layout); self-loops are skipped by the solver + * but kept in the output graph. + * + * @example + * ```ts + * import { getColaLayout } from '@statelyai/graph/layout/webcola'; + * + * const laidOut = getColaLayout(graph, { seed: 42, direction: 'down' }); + * ``` + */ +export function getColaLayout( + graph: Graph | VisualGraph, + options?: ColaLayoutOptions, +): VisualGraph { + const rng = mulberry32(options?.seed ?? 1); + const sizes = new Map(); + const scatterRadius = Math.max(80, 30 * Math.sqrt(graph.nodes.length)); + const colaNodes: ColaNode[] = graph.nodes.map((node) => { + const size = getNodeSize(node, options); + sizes.set(node.id, size); + const colaNode: ColaNode = { id: node.id, ...size }; + if (node.x !== undefined && node.y !== undefined) { + // Existing positions (centers) seed the solver — incremental relayout + // starts from the current arrangement + colaNode.x = node.x + size.width / 2; + colaNode.y = node.y + size.height / 2; + if (options?.isFixed?.(node)) { + colaNode.fixed = 1; + } + } else { + // Unpositioned nodes start in a seeded scatter — this is what makes + // `seed` produce genuinely different (but reproducible) arrangements; + // cola itself is deterministic given the same inputs + const angle = rng() * 2 * Math.PI; + const radius = scatterRadius * Math.sqrt(rng()); + colaNode.x = Math.cos(angle) * radius; + colaNode.y = Math.sin(angle) * radius; + } + return colaNode; + }); + const indexById = new Map(graph.nodes.map((node, i) => [node.id, i])); + const colaLinks: Array> = graph.edges + .filter( + (edge) => + indexById.has(edge.sourceId) && + indexById.has(edge.targetId) && + edge.sourceId !== edge.targetId, + ) + .map((edge) => ({ + source: indexById.get(edge.sourceId)!, + target: indexById.get(edge.targetId)!, + })); + + const layout = new Layout() + .nodes(colaNodes) + .links(colaLinks) + .linkDistance(options?.linkDistance ?? 80) + .avoidOverlaps(true); + + const direction = options?.direction ?? graph.direction; + if (direction !== undefined) { + const axis = direction === 'left' || direction === 'right' ? 'x' : 'y'; + layout.flowLayout(axis, options?.spacing?.layer ?? 50); + } + + // centerGraph would translate the settled graph (moving fixed nodes off + // their pins), so it is disabled whenever anything is pinned + const centerGraph = !colaNodes.some((colaNode) => colaNode.fixed); + layout.start(30, 30, 60, 0, false, centerGraph); + + const byId = new Map(colaNodes.map((colaNode) => [colaNode.id, colaNode])); + return createVisualGraph({ + id: graph.id, + mode: graph.mode, + initialNodeId: graph.initialNodeId ?? undefined, + direction: graph.direction, + data: graph.data, + ...(graph.style !== undefined && { style: graph.style }), + nodes: graph.nodes.map((node) => { + const size = sizes.get(node.id)!; + const colaNode = byId.get(node.id)!; + return { + ...toNodeConfig(node), + ...size, + // cola positions are centers; VisualNode.x/y are top-left + x: (colaNode.x ?? 0) - size.width / 2, + y: (colaNode.y ?? 0) - size.height / 2, + }; + }), + edges: graph.edges.map((edge) => toEdgeConfig(edge)), + }); +} diff --git a/tests/layout/d3-hierarchy.test.ts b/tests/layout/d3-hierarchy.test.ts new file mode 100644 index 0000000..289fc5b --- /dev/null +++ b/tests/layout/d3-hierarchy.test.ts @@ -0,0 +1,112 @@ +import { describe, it, expect } from 'vitest'; +import { createGraph } from '../../src'; +import { getTidyTreeLayout } from '../../src/layout/d3-hierarchy'; + +const SIZE = { width: 60, height: 30 }; +const measure = () => ({ ...SIZE }); + +const makeTree = () => + createGraph({ + nodes: [{ id: 'a', data: { n: 1 } }, { id: 'b' }, { id: 'c' }], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b', weight: 3 }, + { id: 'e2', sourceId: 'a', targetId: 'c' }, + ], + }); + +const centerX = (n: { x: number; width: number }) => n.x + n.width / 2; +const centerY = (n: { y: number; height: number }) => n.y + n.height / 2; + +describe('getTidyTreeLayout', () => { + it('places the parent above its children (direction down)', () => { + const laidOut = getTidyTreeLayout(makeTree(), { measure }); + const [a, b, c] = laidOut.nodes; + expect(centerY(a)).toBeLessThan(centerY(b)); + expect(centerY(a)).toBeLessThan(centerY(c)); + // Tidy tree centers the parent over its children + expect(centerX(a)).toBeCloseTo((centerX(b) + centerX(c)) / 2); + }); + + it('keeps siblings from overlapping (disjoint x-ranges)', () => { + const laidOut = getTidyTreeLayout(makeTree(), { measure }); + const [b, c] = [...laidOut.nodes.slice(1)].sort((m, n) => m.x - n.x); + expect(b.x + b.width).toBeLessThanOrEqual(c.x); + }); + + it('transposes for direction right', () => { + const laidOut = getTidyTreeLayout(makeTree(), { + direction: 'right', + measure, + }); + const [a, b, c] = laidOut.nodes; + expect(centerX(a)).toBeLessThan(centerX(b)); + expect(centerX(a)).toBeLessThan(centerX(c)); + // Siblings spread along y instead, without overlapping + const [top, bottom] = [b, c].sort((m, n) => m.y - n.y); + expect(top.y + top.height).toBeLessThanOrEqual(bottom.y); + }); + + it('lays out multiple roots as a forest', () => { + const forest = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }, { id: 'd' }], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b' }, + { id: 'e2', sourceId: 'c', targetId: 'd' }, + ], + }); + const laidOut = getTidyTreeLayout(forest, { measure }); + // Synthetic root is dropped — only the original nodes remain + expect(laidOut.nodes.map((n) => n.id)).toEqual(['a', 'b', 'c', 'd']); + for (const node of laidOut.nodes) { + expect(Number.isFinite(node.x)).toBe(true); + expect(Number.isFinite(node.y)).toBe(true); + } + // Both roots sit on the same (top) layer; the two trees don't overlap + const [a, , c] = laidOut.nodes; + expect(centerY(a)).toBeCloseTo(centerY(c)); + expect(centerX(a)).not.toBeCloseTo(centerX(c)); + }); + + it('throws a descriptive error when the graph is cyclic with no root', () => { + const cyclic = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b' }, + { id: 'e2', sourceId: 'b', targetId: 'a' }, + ], + }); + expect(() => getTidyTreeLayout(cyclic)).toThrowError( + /getTidyTreeLayout: no tree root found .* cyclic.* options\.rootId/s, + ); + // An explicit rootId resolves it + const laidOut = getTidyTreeLayout(cyclic, { rootId: 'a', measure }); + const [a, b] = laidOut.nodes; + expect(centerY(a)).toBeLessThan(centerY(b)); + }); + + it('preserves extra non-tree edges untouched', () => { + const withCross = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b' }, + { id: 'e2', sourceId: 'a', targetId: 'c' }, + { id: 'cross', sourceId: 'b', targetId: 'c', label: 'extra' }, + ], + }); + const laidOut = getTidyTreeLayout(withCross, { measure }); + expect(laidOut.edges).toHaveLength(3); + const cross = laidOut.edges.find((e) => e.id === 'cross')!; + expect(cross.sourceId).toBe('b'); + expect(cross.targetId).toBe('c'); + expect(cross.label).toBe('extra'); + // Tidy tree does not route edges + expect(cross.points).toBeUndefined(); + }); + + it('preserves non-geometry fields and is deterministic', () => { + const first = getTidyTreeLayout(makeTree(), { measure }); + expect(first.nodes[0].data).toEqual({ n: 1 }); + expect(first.edges[0].weight).toBe(3); + expect(getTidyTreeLayout(makeTree(), { measure })).toEqual(first); + }); +}); diff --git a/tests/layout/forceatlas2.test.ts b/tests/layout/forceatlas2.test.ts new file mode 100644 index 0000000..6a99957 --- /dev/null +++ b/tests/layout/forceatlas2.test.ts @@ -0,0 +1,84 @@ +import { describe, it, expect } from 'vitest'; +import { createGraph } from '../../src'; +import { getForceAtlas2Layout } from '../../src/layout/forceatlas2'; + +const makeGraph = () => + createGraph({ + nodes: [ + { id: 'a', data: { n: 1 } }, + { id: 'b' }, + { id: 'c' }, + { id: 'd' }, + ], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b', weight: 2 }, + { id: 'e2', sourceId: 'b', targetId: 'c' }, + { id: 'e3', sourceId: 'c', targetId: 'a' }, + { id: 'loop', sourceId: 'd', targetId: 'd' }, // self-loops are skipped by forces + ], + }); + +describe('getForceAtlas2Layout', () => { + it('is deterministic for the same seed', () => { + const first = getForceAtlas2Layout(makeGraph(), { seed: 42 }); + const second = getForceAtlas2Layout(makeGraph(), { seed: 42 }); + expect(second).toEqual(first); + }); + + it('differs across seeds', () => { + const first = getForceAtlas2Layout(makeGraph(), { seed: 1 }); + const second = getForceAtlas2Layout(makeGraph(), { seed: 2 }); + expect(second).not.toEqual(first); + }); + + it('gives every node finite positions and sizes', () => { + const laidOut = getForceAtlas2Layout(makeGraph(), { seed: 7 }); + expect(laidOut.nodes).toHaveLength(4); + for (const node of laidOut.nodes) { + expect(Number.isFinite(node.x)).toBe(true); + expect(Number.isFinite(node.y)).toBe(true); + expect(node.width).toBeGreaterThan(0); + expect(node.height).toBeGreaterThan(0); + } + }); + + it('pins fixed nodes at their current position', () => { + const g = createGraph({ + nodes: [ + { id: 'pinned', x: 100, y: 200, width: 10, height: 10 }, + { id: 'free' }, + ], + edges: [{ id: 'e', sourceId: 'pinned', targetId: 'free' }], + }); + const laidOut = getForceAtlas2Layout(g, { + seed: 3, + isFixed: (node) => node.id === 'pinned', + }); + const pinned = laidOut.nodes.find((n) => n.id === 'pinned')!; + expect(pinned.x).toBeCloseTo(100, 6); + expect(pinned.y).toBeCloseTo(200, 6); + }); + + it('keeps connected nodes reasonably near each other', () => { + const laidOut = getForceAtlas2Layout(makeGraph(), { + seed: 11, + iterations: 200, + }); + const center = (id: string) => { + const node = laidOut.nodes.find((n) => n.id === id)!; + return { x: node.x + node.width / 2, y: node.y + node.height / 2 }; + }; + const a = center('a'); + const b = center('b'); + const distance = Math.hypot(a.x - b.x, a.y - b.y); + expect(distance).toBeGreaterThan(0); + expect(distance).toBeLessThan(2000); // generous sanity bound + }); + + it('preserves non-geometry fields', () => { + const laidOut = getForceAtlas2Layout(makeGraph(), { seed: 42 }); + expect(laidOut.nodes[0].data).toEqual({ n: 1 }); + expect(laidOut.edges[0].weight).toBe(2); + expect(laidOut.edges).toHaveLength(4); + }); +}); diff --git a/tests/layout/webcola.test.ts b/tests/layout/webcola.test.ts new file mode 100644 index 0000000..cf525db --- /dev/null +++ b/tests/layout/webcola.test.ts @@ -0,0 +1,121 @@ +import { describe, it, expect } from 'vitest'; +import { createGraph } from '../../src'; +import { getColaLayout } from '../../src/layout/webcola'; + +const makeGraph = () => + createGraph({ + nodes: [ + { id: 'a', data: { n: 1 } }, + { id: 'b' }, + { id: 'c' }, + { id: 'd' }, + ], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b', weight: 2 }, + { id: 'e2', sourceId: 'b', targetId: 'c' }, + { id: 'e3', sourceId: 'c', targetId: 'a' }, + { id: 'loop', sourceId: 'd', targetId: 'd' }, // self-loops are skipped by the solver + ], + }); + +describe('getColaLayout', () => { + it('is deterministic for the same seed', () => { + const first = getColaLayout(makeGraph(), { seed: 42 }); + const second = getColaLayout(makeGraph(), { seed: 42 }); + expect(second).toEqual(first); + }); + + it('differs across seeds', () => { + const first = getColaLayout(makeGraph(), { seed: 1 }); + const second = getColaLayout(makeGraph(), { seed: 2 }); + expect(second).not.toEqual(first); + }); + + it('positions every node finitely', () => { + const laidOut = getColaLayout(makeGraph(), { seed: 7 }); + for (const node of laidOut.nodes) { + expect(Number.isFinite(node.x)).toBe(true); + expect(Number.isFinite(node.y)).toBe(true); + expect(node.width).toBeGreaterThan(0); + expect(node.height).toBeGreaterThan(0); + } + }); + + it('avoids overlaps in a small dense graph', () => { + const ids = ['a', 'b', 'c', 'd', 'e', 'f']; + const g = createGraph({ + nodes: ids.map((id) => ({ id, width: 80, height: 40 })), + // dense: every pair linked with a short ideal distance + edges: ids.flatMap((s, i) => + ids.slice(i + 1).map((t) => ({ + id: `${s}-${t}`, + sourceId: s, + targetId: t, + })), + ), + }); + const laidOut = getColaLayout(g, { seed: 5, linkDistance: 10 }); + for (let i = 0; i < laidOut.nodes.length; i++) { + for (let j = i + 1; j < laidOut.nodes.length; j++) { + const a = laidOut.nodes[i]; + const b = laidOut.nodes[j]; + const overlapX = + a.x < b.x + b.width - 1e-6 && b.x < a.x + a.width - 1e-6; + const overlapY = + a.y < b.y + b.height - 1e-6 && b.y < a.y + a.height - 1e-6; + expect(overlapX && overlapY).toBe(false); + } + } + }); + + it('pins fixed nodes at their current position (within tolerance)', () => { + const g = createGraph({ + nodes: [ + { id: 'pinned', x: 100, y: 200, width: 10, height: 10 }, + { id: 'free' }, + ], + edges: [{ id: 'e', sourceId: 'pinned', targetId: 'free' }], + }); + const laidOut = getColaLayout(g, { + seed: 3, + isFixed: (node) => node.id === 'pinned', + }); + const pinned = laidOut.nodes.find((n) => n.id === 'pinned')!; + const free = laidOut.nodes.find((n) => n.id === 'free')!; + // cola locks fixed nodes in the descent but uses a large finite weight + // during overlap projection — pinning is near-exact, not bit-exact + expect(pinned.x).toBeCloseTo(100, 1); + expect(pinned.y).toBeCloseTo(200, 1); + expect(free.x).not.toBeCloseTo(100, 1); + }); + + it("flowLayout separates source above target for direction 'down'", () => { + const g = createGraph({ + nodes: [{ id: 'top' }, { id: 'mid' }, { id: 'bottom' }], + edges: [ + { id: 'e1', sourceId: 'top', targetId: 'mid' }, + { id: 'e2', sourceId: 'mid', targetId: 'bottom' }, + ], + }); + const laidOut = getColaLayout(g, { + seed: 9, + direction: 'down', + spacing: { layer: 40 }, + }); + const centerY = (id: string) => { + const node = laidOut.nodes.find((n) => n.id === id)!; + return node.y + node.height / 2; + }; + expect(centerY('mid') - centerY('top')).toBeGreaterThanOrEqual(40 - 1e-6); + expect(centerY('bottom') - centerY('mid')).toBeGreaterThanOrEqual( + 40 - 1e-6, + ); + }); + + it('preserves non-geometry fields', () => { + const laidOut = getColaLayout(makeGraph(), { seed: 42 }); + expect(laidOut.nodes[0].data).toEqual({ n: 1 }); + expect(laidOut.edges[0].weight).toBe(2); + expect(laidOut.edges).toHaveLength(4); + }); +}); From fe6719632f5fb6994bc566442401c13c9aacef13 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:18:16 -0400 Subject: [PATCH 04/15] feat(layout): cytoscape headless layout bridge --- src/layout/cytoscape.ts | 160 +++++++++++++++++++++++++++++++++ tests/layout/cytoscape.test.ts | 160 +++++++++++++++++++++++++++++++++ 2 files changed, 320 insertions(+) create mode 100644 src/layout/cytoscape.ts create mode 100644 tests/layout/cytoscape.test.ts diff --git a/src/layout/cytoscape.ts b/src/layout/cytoscape.ts new file mode 100644 index 0000000..f0b6c9b --- /dev/null +++ b/src/layout/cytoscape.ts @@ -0,0 +1,160 @@ +import cytoscape from 'cytoscape'; +import type { Graph, VisualGraph } from '../types'; +import { createVisualGraph } from '../graph'; +import { toNodeConfig, toEdgeConfig } from '../config'; +import { getNodeSize, type LayoutOptions } from './index'; + +/** + * Minimal interface an injected cytoscape factory must satisfy — the + * `cytoscape()` function itself. Inject your own when you've registered + * layout extensions via `cytoscape.use(...)` (cola, fcose, dagre, …). + */ +export type CytoscapeLike = ( + options: cytoscape.CytoscapeOptions, +) => cytoscape.Core; + +export interface CytoscapeLayoutOptions extends LayoutOptions { + /** + * Cytoscape layout name. Built-ins: `'grid'`, `'circle'`, `'concentric'`, + * `'breadthfirst'`, `'cose'` (default), `'random'`. Extension layouts work + * when registered on an injected {@link CytoscapeLayoutOptions.cy} factory. + */ + name?: string; + /** + * Raw cytoscape layout options, merged into the layout call last (override + * everything, including `name`). Engine-specific tuning — spacing knobs, + * `boundingBox`, `roots`, iteration counts — goes here; the options vary + * too much between cytoscape layouts to map `LayoutOptions.spacing` + * generically. See https://js.cytoscape.org/#layouts + */ + layoutOptions?: Record; + /** + * Injected cytoscape factory — e.g. one with extensions registered via + * `cytoscape.use(...)`. Defaults to the imported `cytoscape`. + */ + cy?: CytoscapeLike; +} + +/** + * Lay out a graph with Cytoscape.js (`cytoscape`, an optional peer + * dependency) — one call unlocks its whole layout ecosystem. Pure: returns a + * new {@link VisualGraph} with node positions and sizes. Cytoscape layouts + * position nodes only; edges keep their fields but gain no route `points`. + * Compound graphs are supported via cytoscape `parent`; parent nodes get + * cytoscape's computed compound dimensions. All coordinates are absolute + * (cytoscape does not produce parent-relative positions). + * + * Runs headless with `styleEnabled: true` so resolved node sizes + * ({@link getNodeSize}) participate in overlap avoidance and spacing. + * + * Option mapping is deliberately minimal: `measure` resolves sizes, + * `isFixed` nodes with an existing `x`/`y` are locked in place (cytoscape + * layouts skip locked nodes), and everything else — including `direction` + * and `spacing` — is engine-specific and belongs in + * {@link CytoscapeLayoutOptions.layoutOptions}. `seed` is ignored: the + * discrete layouts (grid, circle, concentric, breadthfirst) are + * deterministic, and cose is not seedable. + * + * @example + * ```ts + * import { getCytoscapeLayout } from '@statelyai/graph/layout/cytoscape'; + * + * const laidOut = await getCytoscapeLayout(graph, { + * name: 'breadthfirst', + * layoutOptions: { roots: ['start'] }, + * }); + * ``` + */ +export async function getCytoscapeLayout( + graph: Graph | VisualGraph, + options?: CytoscapeLayoutOptions, +): Promise { + const elements: cytoscape.ElementDefinition[] = []; + for (const node of graph.nodes) { + const size = getNodeSize(node, options); + const hasPosition = node.x !== undefined && node.y !== undefined; + elements.push({ + group: 'nodes', + data: { + id: node.id, + ...(node.parentId != null && { parent: node.parentId }), + // Resolved sizes ride along in data; the style mapping below feeds + // them to the layout engine + width: size.width, + height: size.height, + }, + // Cytoscape positions are node centers; ours are top-left corners + ...(hasPosition && { + position: { + x: node.x! + size.width / 2, + y: node.y! + size.height / 2, + }, + }), + ...(hasPosition && options?.isFixed?.(node) && { locked: true }), + }); + } + for (const edge of graph.edges) { + elements.push({ + group: 'edges', + data: { id: edge.id, source: edge.sourceId, target: edge.targetId }, + }); + } + + const createCytoscape = options?.cy ?? (cytoscape as CytoscapeLike); + // styleEnabled is required headless — without it nodes have no dimensions + // and layouts treat them as points + const cy = createCytoscape({ + headless: true, + styleEnabled: true, + style: [ + { + selector: 'node', + style: { + width: 'data(width)', + height: 'data(height)', + shape: 'rectangle', + }, + }, + ], + elements, + }); + + try { + const layout = cy.layout({ + name: options?.name ?? 'cose', + animate: false, + ...options?.layoutOptions, + } as cytoscape.LayoutOptions); + // layoutstop fires for both sync (grid) and async (cose) layouts + const stopped = layout.promiseOn('layoutstop'); + layout.run(); + await stopped; + + return createVisualGraph({ + id: graph.id, + mode: graph.mode, + initialNodeId: graph.initialNodeId ?? undefined, + direction: options?.direction ?? graph.direction, + data: graph.data, + ...(graph.style !== undefined && { style: graph.style }), + nodes: graph.nodes.map((node) => { + const ele = cy.getElementById(node.id); + // Read dimensions back from cytoscape: compound parents get their + // computed size, leaves get the resolved size fed in above + const width = ele.width(); + const height = ele.height(); + const position = ele.position(); + return { + ...toNodeConfig(node), + width, + height, + x: position.x - width / 2, + y: position.y - height / 2, + }; + }), + edges: graph.edges.map((edge) => toEdgeConfig(edge)), + }); + } finally { + cy.destroy(); + } +} diff --git a/tests/layout/cytoscape.test.ts b/tests/layout/cytoscape.test.ts new file mode 100644 index 0000000..c00a31c --- /dev/null +++ b/tests/layout/cytoscape.test.ts @@ -0,0 +1,160 @@ +import { describe, it, expect } from 'vitest'; +import { createGraph } from '../../src'; +import { getCytoscapeLayout } from '../../src/layout/cytoscape'; + +const makeGraph = () => + createGraph({ + direction: 'down', + nodes: [{ id: 'a', data: { kind: 'start' } }, { id: 'b' }, { id: 'c' }], + edges: [ + { + id: 'e1', + sourceId: 'a', + targetId: 'b', + label: 'go', + weight: 2, + mode: 'undirected', + }, + { id: 'e2', sourceId: 'b', targetId: 'c' }, + ], + }); + +describe('getCytoscapeLayout', () => { + it('grid: positions every node finitely and distinctly with resolved sizes', async () => { + const laidOut = await getCytoscapeLayout(makeGraph(), { + name: 'grid', + measure: () => ({ width: 80, height: 40 }), + }); + for (const node of laidOut.nodes) { + expect(node.width).toBe(80); + expect(node.height).toBe(40); + expect(Number.isFinite(node.x)).toBe(true); + expect(Number.isFinite(node.y)).toBe(true); + } + const positions = laidOut.nodes.map((n) => `${n.x},${n.y}`); + expect(new Set(positions).size).toBe(laidOut.nodes.length); + }); + + it('breadthfirst: puts the root above its children', async () => { + const tree = createGraph({ + nodes: [{ id: 'root' }, { id: 'left' }, { id: 'right' }], + edges: [ + { id: 'e1', sourceId: 'root', targetId: 'left' }, + { id: 'e2', sourceId: 'root', targetId: 'right' }, + ], + }); + const laidOut = await getCytoscapeLayout(tree, { + name: 'breadthfirst', + layoutOptions: { roots: ['root'] }, + }); + const root = laidOut.nodes.find((n) => n.id === 'root')!; + const left = laidOut.nodes.find((n) => n.id === 'left')!; + const right = laidOut.nodes.find((n) => n.id === 'right')!; + expect(root.y).toBeLessThan(left.y); + expect(root.y).toBeLessThan(right.y); + }); + + it('cose: completes with finite positions and no coincident node rects', async () => { + const laidOut = await getCytoscapeLayout(makeGraph(), { + name: 'cose', + measure: () => ({ width: 80, height: 40 }), + }); + for (const node of laidOut.nodes) { + expect(Number.isFinite(node.x)).toBe(true); + expect(Number.isFinite(node.y)).toBe(true); + } + for (let i = 0; i < laidOut.nodes.length; i++) { + for (let j = i + 1; j < laidOut.nodes.length; j++) { + const a = laidOut.nodes[i]; + const b = laidOut.nodes[j]; + expect(a.x !== b.x || a.y !== b.y).toBe(true); + } + } + }); + + it('feeds node dimensions to the engine (wider nodes spread further)', async () => { + const centerGap = async (width: number) => { + const laidOut = await getCytoscapeLayout(makeGraph(), { + name: 'grid', + layoutOptions: { rows: 1 }, + measure: () => ({ width, height: 40 }), + }); + const centers = laidOut.nodes + .map((n) => n.x + n.width / 2) + .sort((a, b) => a - b); + return centers[1] - centers[0]; + }; + expect(await centerGap(200)).toBeGreaterThan(await centerGap(20)); + }); + + it('lays out compound graphs: child inside parent rect (absolute coords)', async () => { + const compound = createGraph({ + nodes: [ + { id: 'p' }, + { id: 'p1', parentId: 'p' }, + { id: 'p2', parentId: 'p' }, + { id: 'out' }, + ], + edges: [ + { id: 'i', sourceId: 'p1', targetId: 'p2' }, + { id: 'o', sourceId: 'p', targetId: 'out' }, + ], + }); + const laidOut = await getCytoscapeLayout(compound, { + name: 'grid', + measure: () => ({ width: 60, height: 30 }), + }); + const parent = laidOut.nodes.find((n) => n.id === 'p')!; + const child = laidOut.nodes.find((n) => n.id === 'p1')!; + expect(child.parentId).toBe('p'); + // parent gets cytoscape's computed compound size, surrounding children + expect(child.x).toBeGreaterThanOrEqual(parent.x - 1); + expect(child.y).toBeGreaterThanOrEqual(parent.y - 1); + expect(child.x + child.width).toBeLessThanOrEqual( + parent.x + parent.width + 1, + ); + expect(child.y + child.height).toBeLessThanOrEqual( + parent.y + parent.height + 1, + ); + }); + + it('passes raw layoutOptions through (grid rows: 1 ⇒ one row)', async () => { + const laidOut = await getCytoscapeLayout(makeGraph(), { + name: 'grid', + layoutOptions: { rows: 1 }, + measure: () => ({ width: 80, height: 40 }), + }); + const ys = new Set(laidOut.nodes.map((n) => n.y)); + expect(ys.size).toBe(1); + }); + + it('locks isFixed nodes at their current position', async () => { + const graph = createGraph({ + nodes: [{ id: 'a', x: 500, y: 480, width: 80, height: 40 }, { id: 'b' }], + edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }], + }); + const laidOut = await getCytoscapeLayout(graph, { + name: 'grid', + isFixed: (node) => node.id === 'a', + }); + const a = laidOut.nodes.find((n) => n.id === 'a')!; + expect(a.x).toBe(500); + expect(a.y).toBe(480); + }); + + it('preserves non-geometry fields', async () => { + const laidOut = await getCytoscapeLayout(makeGraph(), { name: 'grid' }); + expect(laidOut.direction).toBe('down'); + expect(laidOut.nodes[0].data).toEqual({ kind: 'start' }); + const e1 = laidOut.edges.find((e) => e.id === 'e1')!; + expect(e1.weight).toBe(2); + expect(e1.mode).toBe('undirected'); + expect(e1.label).toBe('go'); + }); + + it('grid is deterministic', async () => { + const first = await getCytoscapeLayout(makeGraph(), { name: 'grid' }); + const second = await getCytoscapeLayout(makeGraph(), { name: 'grid' }); + expect(second).toEqual(first); + }); +}); From e65f46e4212b5ec155f52c868913ee1a9f9f1a65 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:20:52 -0400 Subject: [PATCH 05/15] build: wire forceatlas2/d3-hierarchy/webcola/cytoscape layout subpaths (exports, optional peers, smoke coverage) --- package.json | 29 ++++++++++++++++---- pnpm-lock.yaml | 10 ------- scripts/smoke-package.ts | 57 ++++++++++++++++++++++++++++++++++++++++ tsdown.config.ts | 4 +++ 4 files changed, 85 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index b45db9a..a121810 100644 --- a/package.json +++ b/package.json @@ -42,10 +42,14 @@ "./tgf": "./dist/formats/tgf/index.mjs", "./xyflow": "./dist/formats/xyflow/index.mjs", "./layout": "./dist/layout/index.mjs", + "./layout/cytoscape": "./dist/layout/cytoscape.mjs", "./layout/d3-force": "./dist/layout/d3-force.mjs", + "./layout/d3-hierarchy": "./dist/layout/d3-hierarchy.mjs", "./layout/dagre": "./dist/layout/dagre.mjs", "./layout/elk": "./dist/layout/elk.mjs", + "./layout/forceatlas2": "./dist/layout/forceatlas2.mjs", "./layout/graphviz": "./dist/layout/graphviz.mjs", + "./layout/webcola": "./dist/layout/webcola.mjs", "./queries": "./dist/queries.mjs", "./schemas": "./dist/schemas.mjs", "./package.json": "./package.json" @@ -80,7 +84,6 @@ "@dagrejs/dagre": "^3.0.0", "@dagrejs/graphlib": "^4.0.1", "@hpcc-js/wasm-graphviz": "^1.22.0", - "@types/cytoscape": "^3.31.0", "@types/d3-array": "^3.2.2", "@types/d3-force": "^3.0.10", "@types/d3-hierarchy": "^3.1.7", @@ -117,18 +120,31 @@ "@hpcc-js/wasm-graphviz": "^1.0.0", "cytoscape": "^3.0.0", "d3-force": "^3.0.0", + "d3-hierarchy": "^3.0.0", "dotparser": "^1.0.0", "elkjs": "^0.9.0 || ^0.10.0 || ^0.11.0", "fast-xml-parser": "^5.0.0", + "graphology": "^0.26.0", + "graphology-layout-forceatlas2": "^0.10.0", + "webcola": "^3.4.0", "zod": "^4.0.0" }, "peerDependenciesMeta": { + "@dagrejs/dagre": { + "optional": true + }, + "@hpcc-js/wasm-graphviz": { + "optional": true + }, "cytoscape": { "optional": true }, "d3-force": { "optional": true }, + "d3-hierarchy": { + "optional": true + }, "dotparser": { "optional": true }, @@ -138,14 +154,17 @@ "fast-xml-parser": { "optional": true }, - "zod": { + "graphology": { "optional": true }, - "@dagrejs/dagre": { + "graphology-layout-forceatlas2": { "optional": true }, - "@hpcc-js/wasm-graphviz": { + "webcola": { + "optional": true + }, + "zod": { "optional": true } } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 07c0017..0aba3e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,9 +20,6 @@ devDependencies: '@hpcc-js/wasm-graphviz': specifier: ^1.22.0 version: 1.22.0 - '@types/cytoscape': - specifier: ^3.31.0 - version: 3.31.0 '@types/d3-array': specifier: ^3.2.2 version: 3.2.2 @@ -1216,13 +1213,6 @@ packages: assertion-error: 2.0.1 dev: true - /@types/cytoscape@3.31.0: - resolution: {integrity: sha512-EXHOHxqQjGxLDEh5cP4te6J0bi7LbCzmZkzsR6f703igUac8UGMdEohMyU3GHAayCTZrLQOMnaE/lqB2Ekh8Ww==, tarball: https://registry.npmjs.org/@types/cytoscape/-/cytoscape-3.31.0.tgz} - deprecated: This is a stub types definition. cytoscape provides its own type definitions, so you do not need this installed. - dependencies: - cytoscape: 3.34.0 - dev: true - /@types/d3-array@3.2.2: resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==, tarball: https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz} dev: true diff --git a/scripts/smoke-package.ts b/scripts/smoke-package.ts index 2bde685..ba31689 100644 --- a/scripts/smoke-package.ts +++ b/scripts/smoke-package.ts @@ -293,6 +293,58 @@ async function main(): Promise { `void pending;`, ], }, + './layout/forceatlas2': { + phase: 'optional', + runtime: [ + `const graph = m0.createGraph({ nodes: [{ id: 'a' }, { id: 'b' }], edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }] });`, + `const laidOut = $MOD.getForceAtlas2Layout(graph, { seed: 1, iterations: 10 });`, + `assert.equal(laidOut.nodes.length, 2);`, + ], + types: [ + `const graph = m0.createGraph({ nodes: [{ id: 'a' }], edges: [] });`, + `const laidOut: m0.VisualGraph = $MOD.getForceAtlas2Layout(graph);`, + `void laidOut;`, + ], + }, + './layout/d3-hierarchy': { + phase: 'optional', + runtime: [ + `const graph = m0.createGraph({ nodes: [{ id: 'a' }, { id: 'b' }], edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }] });`, + `const laidOut = $MOD.getTidyTreeLayout(graph);`, + `assert.ok(laidOut.nodes[1].y > laidOut.nodes[0].y);`, + ], + types: [ + `const graph = m0.createGraph({ nodes: [{ id: 'a' }], edges: [] });`, + `const laidOut: m0.VisualGraph = $MOD.getTidyTreeLayout(graph, { rootId: 'a' });`, + `void laidOut;`, + ], + }, + './layout/webcola': { + phase: 'optional', + runtime: [ + `const graph = m0.createGraph({ nodes: [{ id: 'a' }, { id: 'b' }], edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }] });`, + `const laidOut = $MOD.getColaLayout(graph, { seed: 1 });`, + `assert.equal(laidOut.nodes.length, 2);`, + ], + types: [ + `const graph = m0.createGraph({ nodes: [{ id: 'a' }], edges: [] });`, + `const laidOut: m0.VisualGraph = $MOD.getColaLayout(graph, { linkDistance: 100 });`, + `void laidOut;`, + ], + }, + './layout/cytoscape': { + phase: 'optional', + runtime: [ + `const graph = m0.createGraph({ nodes: [{ id: 'a' }, { id: 'b' }], edges: [{ id: 'e1', sourceId: 'a', targetId: 'b' }] });`, + `const laidOut = await $MOD.getCytoscapeLayout(graph, { name: 'grid' });`, + `assert.equal(laidOut.nodes.length, 2);`, + ], + types: [ + `const graph = m0.createGraph({ nodes: [{ id: 'a' }], edges: [] });`, + `const pending: Promise = $MOD.getCytoscapeLayout(graph);`, + `void pending;`, + ], + }, './gexf': { phase: 'optional', runtime: [ @@ -526,6 +578,11 @@ async function main(): Promise { '@dagrejs/dagre', 'd3-force', '@hpcc-js/wasm-graphviz', + 'graphology', + 'graphology-layout-forceatlas2', + 'd3-hierarchy', + 'webcola', + 'cytoscape', ], { cwd: consumerDir, diff --git a/tsdown.config.ts b/tsdown.config.ts index 157a7aa..f34fdf1 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -29,6 +29,10 @@ export default defineConfig({ 'src/layout/dagre.ts', 'src/layout/d3-force.ts', 'src/layout/graphviz.ts', + 'src/layout/forceatlas2.ts', + 'src/layout/d3-hierarchy.ts', + 'src/layout/webcola.ts', + 'src/layout/cytoscape.ts', ], exports: { customExports(exports) { From a0a3957c3d83f9b59f492414bfd752aa2b1d8ca0 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:22:17 -0400 Subject: [PATCH 06/15] perf(paths): lazy path materialization + typed-array heap in Dijkstra/A*/bidirectional hot loops --- bench/paths-lazy.ts | 104 +++++++++++ src/algorithms/paths.ts | 332 ++++++++++++++++++++++++---------- tests/perf-regression.test.ts | 78 +++++++- 3 files changed, 419 insertions(+), 95 deletions(-) create mode 100644 bench/paths-lazy.ts diff --git a/bench/paths-lazy.ts b/bench/paths-lazy.ts new file mode 100644 index 0000000..ed78541 --- /dev/null +++ b/bench/paths-lazy.ts @@ -0,0 +1,104 @@ +/** + * Standalone before/after bench for the paths.ts perf backlog: + * 1. lazy path materialization (all-targets gen/getShortestPaths) + * 2. typed-array heap for the Dijkstra hot loop + * + * Run: pnpm tsx bench/paths-lazy.ts + * + * Reports medians over TRIALS runs on a seeded 10k-node random graph. + */ +import { makeRandomGraph } from '../tests/differential/generators'; +import { + genShortestPaths, + getShortestPath, + getShortestPaths, +} from '../src/algorithms/paths'; +import { getCSR } from '../src/algorithms/csr'; + +const TRIALS = 15; +const N = 10_000; + +function median(samples: number[]): number { + const sorted = [...samples].sort((a, b) => a - b); + return sorted[Math.floor(sorted.length / 2)]; +} + +function bench(label: string, fn: () => void): void { + // warm-up (also warms index/CSR caches) + for (let i = 0; i < 3; i++) fn(); + const samples: number[] = []; + for (let i = 0; i < TRIALS; i++) { + const start = performance.now(); + fn(); + samples.push(performance.now() - start); + } + console.log(`${label.padEnd(58)} median ${median(samples).toFixed(2)} ms`); +} + +const weighted = makeRandomGraph(42, { + mode: 'directed', + nodeCount: N, + density: 3, + connected: true, + weighted: true, +}); +const unweighted = makeRandomGraph(43, { + mode: 'directed', + nodeCount: N, + density: 3, + connected: true, +}); + +// Warm CSR for both graphs so builds don't pollute first samples +getCSR(weighted); +getCSR(unweighted); + +let sink = 0; + +console.log(`graph: ${N} nodes, ~${weighted.edges.length} edges, seeded\n`); + +bench('weighted genShortestPaths first path only (abandoned)', () => { + for (const path of genShortestPaths(weighted, { from: 'n0' })) { + sink += path.steps.length; + break; + } +}); + +bench('weighted genShortestPaths first 10 paths (abandoned)', () => { + let count = 0; + for (const path of genShortestPaths(weighted, { from: 'n0' })) { + sink += path.steps.length; + if (++count >= 10) break; + } +}); + +bench('weighted getShortestPaths all targets (full)', () => { + sink += getShortestPaths(weighted, { from: 'n0' }).length; +}); + +bench('unweighted genShortestPaths first path only (abandoned)', () => { + for (const path of genShortestPaths(unweighted, { from: 'n0' })) { + sink += path.steps.length; + break; + } +}); + +bench('unweighted getShortestPaths all targets (full)', () => { + sink += getShortestPaths(unweighted, { from: 'n0' }).length; +}); + +bench('weighted getShortestPath single pair x20 (bidi heap)', () => { + for (let i = 0; i < 20; i++) { + const path = getShortestPath(weighted, { + from: `n${i}`, + to: `n${N - 1 - i}`, + }); + sink += path ? path.steps.length : 0; + } +}); + +bench('weighted getShortestPaths to single target (early exit)', () => { + sink += getShortestPaths(weighted, { from: 'n0', to: `n${N - 1}` }).length; +}); + +console.log(`\n(sink=${sink})`); diff --git a/src/algorithms/paths.ts b/src/algorithms/paths.ts index 00c83f9..efef1b8 100644 --- a/src/algorithms/paths.ts +++ b/src/algorithms/paths.ts @@ -16,11 +16,106 @@ import { getNeighborEdges, getNeighborEdgesAll, getNeighborIds, - MinPriorityQueue, resolveFrom, } from './shared'; import { getCSR } from './csr'; +/** + * Flat binary min-heap of `(distance, node position)` entries in parallel + * typed arrays. The Dijkstra/A* hot loops push one entry per relaxation, so + * avoiding a `{ pos, dist }` wrapper object per push (allocation + property + * loads in the sift comparisons) is a measurable win on 10k+ node graphs. + * Sifts move "holes" instead of swapping, halving array writes. + */ +class TypedMinHeap { + private keys: Float64Array; + private vals: Int32Array; + size = 0; + + constructor(capacity: number) { + const cap = Math.max(capacity, 16); + this.keys = new Float64Array(cap); + this.vals = new Int32Array(cap); + } + + push(key: number, val: number): void { + if (this.size === this.keys.length) { + const keys = new Float64Array(this.keys.length * 2); + const vals = new Int32Array(this.vals.length * 2); + keys.set(this.keys); + vals.set(this.vals); + this.keys = keys; + this.vals = vals; + } + const { keys, vals } = this; + let hole = this.size++; + while (hole > 0) { + const parent = (hole - 1) >> 1; + if (keys[parent] <= key) break; + keys[hole] = keys[parent]; + vals[hole] = vals[parent]; + hole = parent; + } + keys[hole] = key; + vals[hole] = val; + } + + /** Key of the minimum entry; garbage when empty (check `size` first). */ + peekKey(): number { + return this.keys[0]; + } + + /** Value of the minimum entry; garbage when empty (check `size` first). */ + peekVal(): number { + return this.vals[0]; + } + + /** Remove the minimum entry (no-op shape: read via peek* first). */ + pop(): void { + const { keys, vals } = this; + const last = --this.size; + if (last === 0) return; + const key = keys[last]; + const val = vals[last]; + let hole = 0; + for (;;) { + let child = hole * 2 + 1; + if (child >= last) break; + const right = child + 1; + if (right < last && keys[right] < keys[child]) child = right; + if (keys[child] >= key) break; + keys[hole] = keys[child]; + vals[hole] = vals[child]; + hole = child; + } + keys[hole] = key; + vals[hole] = val; + } +} + +/** + * Result of a single-source shortest-distance search, kept in typed-array + * form keyed by CSR node position. Paths are *not* materialized here — + * {@link reconstructPathsAt} walks `prevArr` on demand, so abandoning a + * `genShortestPaths` iterator early never pays for paths it didn't yield. + */ +interface ShortestDistancesResult { + /** CSR position of the source, or -1 if the source id is unknown. */ + source: number; + /** Distance per node position; `Infinity` = unreached. */ + distArr: Float64Array; + /** + * Tie predecessors per node position as flat `(fromPos, edgeIndex)` pairs; + * `undefined` = unreached. Entries for nodes with distance beyond + * `stopDistance` are tentative (unsettled) — callers must filter targets + * by `stopDistance`; predecessors of any valid target are always settled + * (their distance is ≤ the target's). + */ + prevArr: Array; + /** Settled horizon after an early exit; `Infinity` for a full search. */ + stopDistance: number; +} + function computeShortestDistances( graph: Graph, sourceId: string, @@ -33,31 +128,27 @@ function computeShortestDistances( * the target survive). Bellman-Ford ignores this (it must relax globally). */ stopAtId?: string, -): { - dist: Map; - prev: Map }>>; -} { +): ShortestDistancesResult { if (algorithm === 'bellman-ford') { - return bellmanFord(graph, sourceId, getWeight); + return bellmanFordTyped(graph, sourceId, getWeight); } - const dist = new Map(); - const prev = new Map }>>(); - - dist.set(sourceId, 0); - prev.set(sourceId, []); - const csr = getCSR(graph); + const n = csr.ids.length; const source = csr.indexOf.get(sourceId); if (source === undefined) { // Unknown source id: nothing is reachable (matches pre-CSR behavior) - return { dist, prev }; + return { + source: -1, + distArr: new Float64Array(0), + prevArr: [], + stopDistance: Infinity, + }; } - const n = csr.ids.length; const distArr = new Float64Array(n).fill(Infinity); // Tie predecessors per node as (fromPos, edgeIndex) pairs - const prevArr: Array = new Array(n); + const prevArr: Array = new Array(n); distArr[source] = 0; prevArr[source] = []; @@ -99,20 +190,20 @@ function computeShortestDistances( prevArr[v] = [u, csr.outEdgeIndex[a]]; queue[tail++] = v; } else if (distArr[v] === nextDistance) { - prevArr[v].push(u, csr.outEdgeIndex[a]); + prevArr[v]!.push(u, csr.outEdgeIndex[a]); } } } } else { const effectiveWeight = getWeight ?? ((edge: GraphEdge) => edge.weight ?? 1); const visited = new Uint8Array(n); - const pq = new MinPriorityQueue<{ pos: number; dist: number }>( - (a, b) => a.dist - b.dist, - ); - pq.push({ pos: source, dist: 0 }); + const pq = new TypedMinHeap(n); + pq.push(0, source); while (pq.size > 0) { - const { pos: u, dist: distance } = pq.pop()!; + const distance = pq.peekKey(); + const u = pq.peekVal(); + pq.pop(); if (visited[u] || distance !== distArr[u]) continue; // Early exit: all nodes at distance ≤ dist(target) are settled if (distance > stopDistance) break; @@ -133,33 +224,54 @@ function computeShortestDistances( if (nextDistance < distArr[v]) { distArr[v] = nextDistance; prevArr[v] = [u, csr.outEdgeIndex[a]]; - pq.push({ pos: v, dist: nextDistance }); + pq.push(nextDistance, v); } else if (nextDistance === distArr[v] && distArr[v] !== Infinity) { - prevArr[v].push(u, csr.outEdgeIndex[a]); + prevArr[v]!.push(u, csr.outEdgeIndex[a]); } } } } - // Convert reached nodes back to the id-keyed shape reconstruction expects. - // After an early exit, nodes beyond the stop distance hold tentative - // (unsettled) values — exclude them; they cannot lie on any shortest path - // to the target. - for (let i = 0; i < n; i++) { - if (distArr[i] === Infinity || distArr[i] > stopDistance) continue; - dist.set(csr.ids[i], distArr[i]); - const pairs = prevArr[i]; - const predecessors: Array<{ from: string; edge: GraphEdge }> = []; - for (let k = 0; k < pairs.length; k += 2) { - predecessors.push({ - from: csr.ids[pairs[k]], - edge: graph.edges[pairs[k + 1]] as GraphEdge, - }); + return { source, distArr, prevArr, stopDistance }; +} + +/** + * Bellman-Ford adapted to the typed-array result shape. The O(VE) relaxation + * dominates, so the id→position conversion here is noise — and it keeps a + * single reconstruction path for both algorithms. + */ +function bellmanFordTyped( + graph: Graph, + sourceId: string, + getWeight?: (edge: GraphEdge) => number, +): ShortestDistancesResult { + const { dist, prev } = bellmanFord(graph, sourceId, getWeight); + const csr = getCSR(graph); + const idx = getIndex(graph); + const n = csr.ids.length; + const distArr = new Float64Array(n).fill(Infinity); + const prevArr: Array = new Array(n); + + for (const [id, distance] of dist) { + const pos = csr.indexOf.get(id); + if (pos === undefined) continue; + distArr[pos] = distance; + const pairs: number[] = []; + for (const { from, edge } of prev.get(id) ?? []) { + const fromPos = csr.indexOf.get(from); + const edgeIndex = idx.edgeById.get(edge.id); + if (fromPos === undefined || edgeIndex === undefined) continue; + pairs.push(fromPos, edgeIndex); } - prev.set(csr.ids[i], predecessors); + prevArr[pos] = pairs; } - return { dist, prev }; + return { + source: csr.indexOf.get(sourceId) ?? -1, + distArr, + prevArr, + stopDistance: Infinity, + }; } function bellmanFord( @@ -244,51 +356,56 @@ function bellmanFord( return { dist, prev }; } -function* reconstructPaths( +function* reconstructPathsAt( graph: Graph, - prev: Map }>>, + prevArr: Array, sourceNode: GraphNode, - targetId: string, - onPath: Set = new Set(), + sourcePos: number, + targetPos: number, + onPath: Set = new Set(), ): Generator> { - if (targetId === sourceNode.id) { + if (targetPos === sourcePos) { yield { source: sourceNode, steps: [] }; return; } - const predecessors = prev.get(targetId); - if (!predecessors || predecessors.length === 0) return; + const pairs = prevArr[targetPos]; + if (!pairs || pairs.length === 0) return; - const idx = getIndex(graph); - const targetNi = idx.nodeById.get(targetId); - const targetNode = - targetNi !== undefined - ? graph.nodes[targetNi] - : graph.nodes.find((node) => node.id === targetId)!; + // CSR positions are `graph.nodes` positions, so no id lookup is needed. + const targetNode = graph.nodes[targetPos] as GraphNode; // Track nodes on the current partial path — zero-weight cycles can make - // the `prev` structure cyclic via equal-distance tie predecessors, so - // never revisit a node already on the path being reconstructed. - onPath.add(targetId); - for (const { from, edge } of predecessors) { - if (onPath.has(from)) continue; - for (const prefix of reconstructPaths(graph, prev, sourceNode, from, onPath)) { + // the predecessor structure cyclic via equal-distance tie predecessors, + // so never revisit a node already on the path being reconstructed. + onPath.add(targetPos); + for (let k = 0; k < pairs.length; k += 2) { + const fromPos = pairs[k]; + if (onPath.has(fromPos)) continue; + const edge = graph.edges[pairs[k + 1]] as GraphEdge; + for (const prefix of reconstructPathsAt( + graph, + prevArr, + sourceNode, + sourcePos, + fromPos, + onPath, + )) { yield { source: sourceNode, steps: [...prefix.steps, { edge, node: targetNode }], }; } } - onPath.delete(targetId); + onPath.delete(targetPos); } export function* genShortestPaths( graph: Graph, opts?: PathOptions, ): Generator> { - const idx = getIndex(graph); const sourceId = resolveFrom(graph, opts); - const { dist, prev } = computeShortestDistances( + const { source, distArr, prevArr, stopDistance } = computeShortestDistances( graph, sourceId, opts?.getWeight, @@ -296,18 +413,44 @@ export function* genShortestPaths( opts?.to, // single-target queries early-exit the search ); - const targets = opts?.to - ? [opts.to].filter((id) => dist.has(id)) - : [...dist.keys()].filter((id) => id !== sourceId); - - const sourceNi = idx.nodeById.get(sourceId); const sourceNode = - sourceNi !== undefined - ? graph.nodes[sourceNi] + source !== -1 + ? (graph.nodes[source] as GraphNode) : graph.nodes.find((node) => node.id === sourceId)!; - for (const targetId of targets) { - yield* reconstructPaths(graph, prev, sourceNode, targetId); + if (source === -1) { + // Unknown source id: nothing is reachable; only the trivial self-path + // when it is explicitly requested. + if (opts?.to === sourceId) yield { source: sourceNode, steps: [] }; + return; + } + + const csr = getCSR(graph); + + if (opts?.to) { + const target = csr.indexOf.get(opts.to); + // After an early exit, distances beyond the settled horizon are + // tentative — such nodes are not valid targets. + if ( + target === undefined || + distArr[target] === Infinity || + distArr[target] > stopDistance + ) { + return; + } + yield* reconstructPathsAt(graph, prevArr, sourceNode, source, target); + return; + } + + for (let target = 0; target < distArr.length; target++) { + if ( + target === source || + distArr[target] === Infinity || + distArr[target] > stopDistance + ) { + continue; + } + yield* reconstructPathsAt(graph, prevArr, sourceNode, source, target); } } @@ -411,37 +554,39 @@ function bidirectionalShortestPath( const predBEdge = new Int32Array(n).fill(-1); const settledF = new Uint8Array(n); const settledB = new Uint8Array(n); - const compare = (a: { dist: number }, b: { dist: number }) => a.dist - b.dist; - const pqF = new MinPriorityQueue<{ pos: number; dist: number }>(compare); - const pqB = new MinPriorityQueue<{ pos: number; dist: number }>(compare); + const pqF = new TypedMinHeap(n); + const pqB = new TypedMinHeap(n); distF[source] = 0; distB[target] = 0; - pqF.push({ pos: source, dist: 0 }); - pqB.push({ pos: target, dist: 0 }); + pqF.push(0, source); + pqB.push(0, target); let mu = Infinity; let meet = -1; /** Discard stale/settled heap entries; return the next valid key. */ const validTop = ( - pq: MinPriorityQueue<{ pos: number; dist: number }>, + pq: TypedMinHeap, dist: Float64Array, settled: Uint8Array, ): number | undefined => { - for (;;) { - const top = pq.peek(); - if (top === undefined) return undefined; - if (settled[top.pos] || top.dist !== dist[top.pos]) { + while (pq.size > 0) { + const key = pq.peekKey(); + const pos = pq.peekVal(); + if (settled[pos] || key !== dist[pos]) { pq.pop(); continue; } - return top.dist; + return key; } + return undefined; }; const scanForward = () => { - const { pos: u, dist: d } = pqF.pop()!; + const d = pqF.peekKey(); + const u = pqF.peekVal(); + pqF.pop(); settledF[u] = 1; for (let a = csr.outOffsets[u]; a < csr.outOffsets[u + 1]; a++) { const edge = graph.edges[csr.outEdgeIndex[a]] as GraphEdge; @@ -452,7 +597,7 @@ function bidirectionalShortestPath( distF[v] = next; predF[v] = u; predFEdge[v] = csr.outEdgeIndex[a]; - pqF.push({ pos: v, dist: next }); + pqF.push(next, v); } // distB[v] is the cost of a real backward path (tentative or settled), // so next + distB[v] is the cost of a real s→t path @@ -464,7 +609,9 @@ function bidirectionalShortestPath( }; const scanBackward = () => { - const { pos: u, dist: d } = pqB.pop()!; + const d = pqB.peekKey(); + const u = pqB.peekVal(); + pqB.pop(); settledB[u] = 1; for (let a = csr.inOffsets[u]; a < csr.inOffsets[u + 1]; a++) { const edge = graph.edges[csr.inEdgeIndex[a]] as GraphEdge; @@ -475,7 +622,7 @@ function bidirectionalShortestPath( distB[v] = next; predB[v] = u; predBEdge[v] = csr.inEdgeIndex[a]; - pqB.push({ pos: v, dist: next }); + pqB.push(next, v); } if (distF[v] !== Infinity && next + distF[v] < mu) { mu = next + distF[v]; @@ -1017,9 +1164,8 @@ export function getAStarPath( const cameFromPos = new Int32Array(n).fill(-1); const cameFromEdge = new Int32Array(n).fill(-1); const closed = new Uint8Array(n); - const openSet = new MinPriorityQueue<{ pos: number; f: number }>( - (a, b) => a.f - b.f, - ); + // Heap key is the f-score (g + heuristic) + const openSet = new TypedMinHeap(n); // A* with a heuristic may finish without scanning a reachable negative // edge — enforce the throw-on-negative contract up front @@ -1032,10 +1178,11 @@ export function getAStarPath( ); gScore[source] = 0; - openSet.push({ pos: source, f: heuristic(sourceId) }); + openSet.push(heuristic(sourceId), source); while (openSet.size > 0) { - const { pos: current } = openSet.pop()!; + const current = openSet.peekVal(); + openSet.pop(); if (closed[current]) continue; if (current === target) { @@ -1064,10 +1211,7 @@ export function getAStarPath( cameFromPos[neighbor] = current; cameFromEdge[neighbor] = csr.outEdgeIndex[a]; gScore[neighbor] = tentativeScore; - openSet.push({ - pos: neighbor, - f: tentativeScore + heuristic(csr.ids[neighbor]), - }); + openSet.push(tentativeScore + heuristic(csr.ids[neighbor]), neighbor); } } } diff --git a/tests/perf-regression.test.ts b/tests/perf-regression.test.ts index 52346ce..5e554d4 100644 --- a/tests/perf-regression.test.ts +++ b/tests/perf-regression.test.ts @@ -1,5 +1,11 @@ import { describe, it, expect } from 'vitest'; -import { createGraph, getNode, getSuccessors } from '../src'; +import { + createGraph, + genShortestPaths, + getNode, + getShortestPaths, + getSuccessors, +} from '../src'; import { getBetweennessCentrality } from '../src/algorithms'; /** @@ -68,3 +74,73 @@ describe('index read-path performance', () => { expect(elapsed).toBeLessThan(500); }); }); + +/** + * Guards the lazy-materialization contract of genShortestPaths: the search + * keeps its result as typed arrays (distances + parent pointers) and each + * path is reconstructed only when the iterator yields it. An abandoned + * iterator must not pay for paths (or per-target predecessor objects) it + * never yielded. + * + * All assertions count element reads via proxies — fully deterministic, no + * timing. + */ +describe('genShortestPaths lazy path materialization', () => { + const N = 1_000; + + /** Directed chain n0 -> n1 -> ... with counting proxies on nodes/edges. */ + const makeCountingChain = () => { + const g = createGraph({ + nodes: Array.from({ length: N }, (_, i) => ({ id: `n${i}` })), + edges: Array.from({ length: N - 1 }, (_, i) => ({ + id: `e${i}`, + sourceId: `n${i}`, + targetId: `n${i + 1}`, + })), + }); + const counts = { nodeReads: 0, edgeReads: 0 }; + const countingProxy = ( + arr: T, + key: 'nodeReads' | 'edgeReads', + ): T => + new Proxy(arr, { + get(target, prop, receiver) { + if (typeof prop === 'string' && /^\d+$/.test(prop)) counts[key]++; + return Reflect.get(target, prop, receiver); + }, + }); + g.nodes = countingProxy(g.nodes, 'nodeReads'); + g.edges = countingProxy(g.edges, 'edgeReads'); + // Warm the index + CSR (their builds sweep both arrays once) + getShortestPaths(g, { from: 'n0', to: 'n1' }); + counts.nodeReads = 0; + counts.edgeReads = 0; + return { g, counts }; + }; + + it('an iterator abandoned after the first yield does not materialize other paths', () => { + const { g, counts } = makeCountingChain(); + + for (const path of genShortestPaths(g, { from: 'n0' })) { + expect(path.steps.length).toBe(1); + break; + } + + // Only the source node and the first target node may be touched. Full + // (eager) materialization reads ≥ N node elements. + expect(counts.nodeReads).toBeLessThan(10); + // The unweighted-search check sweeps edges once (N-1 reads) and the one + // yielded path reads its single edge. The old eager implementation also + // converted every node's predecessor list to objects up front (~2x). + expect(counts.edgeReads).toBeLessThan(N + 100); + }); + + it('full consumption still materializes every path (sanity check)', () => { + const { g, counts } = makeCountingChain(); + + const paths = getShortestPaths(g, { from: 'n0' }); + + expect(paths.length).toBe(N - 1); + expect(counts.nodeReads).toBeGreaterThanOrEqual(N - 1); + }); +}); From 7742b52aa11d494eef239b13006fc416c86f8c5f Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:22:52 -0400 Subject: [PATCH 07/15] docs: benchmarks page, graphlib migration guide, React Flow + ELK pipeline cookbook; fix JSDoc subpaths in format examples --- docs/benchmarks.md | 182 +++++++++++++++++++++++ docs/migrating-from-graphlib.md | 122 +++++++++++++++ docs/react-flow-elk-pipeline.md | 254 ++++++++++++++++++++++++++++++++ src/formats/cytoscape/index.ts | 6 +- src/formats/d3/index.ts | 6 +- src/formats/gml/index.ts | 6 +- src/formats/jgf/index.ts | 6 +- src/formats/tgf/index.ts | 6 +- src/formats/xyflow/index.ts | 6 +- 9 files changed, 576 insertions(+), 18 deletions(-) create mode 100644 docs/benchmarks.md create mode 100644 docs/migrating-from-graphlib.md create mode 100644 docs/react-flow-elk-pipeline.md diff --git a/docs/benchmarks.md b/docs/benchmarks.md new file mode 100644 index 0000000..8e45eb5 --- /dev/null +++ b/docs/benchmarks.md @@ -0,0 +1,182 @@ +# Benchmarks + +Cross-library comparison of `@statelyai/graph` against [graphology](https://graphology.github.io/), [ngraph](https://github.com/anvaka/ngraph.graph), [@dagrejs/graphlib](https://github.com/dagrejs/graphlib), and [cytoscape](https://js.cytoscape.org/) (headless) on seven workloads: graph construction, BFS reachability, single-pair shortest path, PageRank, connected components, betweenness centrality, and a full degree sweep. + +- **Measured:** 2026-06-11 on an Apple M1 Max (10 cores), Node v25.9.0 (darwin/arm64). Library versions: graphology 0.26, ngraph.graph 20.1 / ngraph.path 1.6, @dagrejs/graphlib 4.0, cytoscape 3.34. +- **Numbers are medians** (milliseconds) of ≥5 runs after warmup, within a 1.5 s sampling budget per cell. +- Machine specifics matter. Reproduce on your own hardware with: + + ```bash + pnpm bench:compare # 1k / 10k / 100k nodes + pnpm bench:compare -- --quick # 1k / 10k only + ``` + +Cell legend: **bold** = fastest for that row; `(n.n×)` = multiple of the fastest; `—` = the library has no equivalent API; `>10s` = skipped after a prior run exceeded 10 s; `crash` = the library threw (the error is recorded in the JSON results). + +> **Sub-millisecond caveat:** cells under ~0.1 ms (notably scaleFree traversals, which reach few nodes from the start node) are dominated by call overhead. Treat their ratios as noise, in either direction. + +## Build + +Construct the graph from an identical node/edge list. + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **1.7** | 5.3 (3.2×) | 2.3 (1.4×) | 15.3 (9.2×) | 36.7 (22.2×) | +| scaleFree 1,000 | **1.1** | 3.5 (3.3×) | 1.8 (1.7×) | 12.7 (12.0×) | 27.4 (25.8×) | +| grid 1,000 | **0.84** | 2.0 (2.3×) | 1.3 (1.5×) | 4.3 (5.1×) | 17.2 (20.5×) | +| layeredDag 1,000 | **0.95** | 3.1 (3.3×) | 1.5 (1.6×) | 12.2 (12.8×) | 23.4 (24.7×) | +| random 10,000 | **7.0** | 55.9 (8.0×) | 18.9 (2.7×) | 110 (15.7×) | 407 (58.2×) | +| scaleFree 10,000 | **8.1** | 39.3 (4.8×) | 35.3 (4.3×) | 103 (12.7×) | 411 (50.6×) | +| grid 10,000 | **5.1** | 25.8 (5.1×) | 9.0 (1.8×) | 53.3 (10.5×) | 256 (50.6×) | +| layeredDag 10,000 | **5.6** | 31.6 (5.6×) | 12.8 (2.3×) | 68.4 (12.2×) | 330 (58.9×) | +| random 100,000 | **56.0** | 660 (11.8×) | 291 (5.2×) | 1500 (26.8×) | 4477 (80.0×) | +| scaleFree 100,000 | **96.3** | 651 (6.8×) | 254 (2.6×) | 1525 (15.8×) | 3718 (38.6×) | +| grid 100,000 | **63.0** | 497 (7.9×) | 209 (3.3×) | 848 (13.5×) | 2442 (38.8×) | +| layeredDag 100,000 | **54.2** | 511 (9.4×) | 194 (3.6×) | 1014 (18.7×) | 3419 (63.1×) | + +## BFS + +Full directed reachability sweep from node 0. Libraries without a built-in traversal get a minimal queue loop over their neighbor API. + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **0.04** | 0.23 (6.4×) | 0.32 (8.9×) | 0.24 (6.7×) | 16.4 (457.5×) | +| scaleFree 1,000 | 0.00 (9.7×) | 0.00 (1.7×) | 0.01 (75.7×) | **0.00** | 1.1 (9097.0×) | +| grid 1,000 | **0.03** | 0.17 (6.5×) | 0.16 (6.2×) | 0.08 (3.1×) | 10.8 (415.7×) | +| layeredDag 1,000 | **0.02** | 0.16 (6.8×) | 0.22 (9.1×) | 0.08 (3.1×) | 12.1 (501.7×) | +| random 10,000 | **0.40** | 9.7 (23.9×) | 4.3 (10.6×) | 3.8 (9.5×) | 228 (565.6×) | +| scaleFree 10,000 | 0.01 (71.4×) | 0.00 (2.0×) | 0.05 (539.2×) | **0.00** | 19.6 (232978.2×) | +| grid 10,000 | **0.21** | 2.8 (12.9×) | 3.0 (13.9×) | 1.7 (7.8×) | 123 (579.1×) | +| layeredDag 10,000 | **0.32** | 3.5 (10.8×) | 2.6 (8.1×) | 1.4 (4.2×) | 171 (530.2×) | +| random 100,000 | **4.6** | 126 (27.6×) | 92.7 (20.3×) | 60.5 (13.3×) | 6555 (1438.5×) | +| scaleFree 100,000 | 0.04 (265.8×) | **0.00** | 0.05 (325.6×) | 0.00 (1.3×) | 309 (1863689.7×) | +| grid 100,000 | **2.3** | 86.2 (38.3×) | 41.4 (18.4×) | 58.4 (25.9×) | 1722 (764.7×) | +| layeredDag 100,000 | **3.4** | 81.9 (23.8×) | 33.1 (9.6×) | 46.4 (13.5×) | 2396 (696.8×) | + +The scaleFree rows are sub-millisecond for everyone (few nodes are reachable from node 0); their ratios are noise. + +## Single-pair shortest path (sssp) + +Weighted shortest path from node 0 to node n−1. `@statelyai/graph` uses `getShortestPath` (bidirectional Dijkstra); graphology uses `dijkstra.bidirectional`; ngraph uses `ngraph.path` A\*. graphlib's only shortest-path API is full single-source Dijkstra, so its cell pays the all-targets cost — that is the cost a graphlib user pays for one query. + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **0.11** | 0.11 (1.0×) | 0.35 (3.3×) | 2.8 (25.9×) | 22.9 (212.2×) | +| scaleFree 1,000 | 0.01 (5.0×) | **0.00** | 0.01 (8.8×) | 1.5 (1296.7×) | 4.1 (3511.2×) | +| grid 1,000 | **0.22** | 0.96 (4.4×) | 0.30 (1.4×) | 0.95 (4.3×) | 14.8 (67.3×) | +| layeredDag 1,000 | **0.16** | 0.65 (4.1×) | 0.35 (2.2×) | 2.3 (14.8×) | 18.5 (117.0×) | +| random 10,000 | **0.14** | 0.33 (2.3×) | 5.9 (40.7×) | 28.0 (194.6×) | 360 (2496.0×) | +| scaleFree 10,000 | 0.04 (25.8×) | **0.00** | 0.01 (7.1×) | 6.0 (3488.9×) | 42.8 (25033.5×) | +| grid 10,000 | **1.7** | 16.2 (9.4×) | 3.4 (2.0×) | 18.9 (11.1×) | 193 (112.4×) | +| layeredDag 10,000 | **2.0** | 13.0 (6.4×) | 4.3 (2.1×) | 18.8 (9.2×) | 269 (131.9×) | +| random 100,000 | **0.60** | 1.3 (2.2×) | 125 (207.9×) | 431 (715.9×) | 5941 (9861.4×) | +| scaleFree 100,000 | 0.34 (199.2×) | **0.00** | 0.02 (14.2×) | 67.0 (39215.9×) | 637 (372866.4×) | +| grid 100,000 | **27.4** | 383 (14.0×) | 66.0 (2.4×) | 338 (12.3×) | 3710 (135.4×) | +| layeredDag 100,000 | **35.2** | 408 (11.6×) | 68.6 (2.0×) | 386 (11.0×) | 5268 (149.9×) | + +graphology wins the scaleFree rows; on those graphs node n−1 is typically unreachable from node 0 and the search terminates almost immediately, so the cells are sub-millisecond for both bidirectional implementations. + +## PageRank + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **0.62** | 1.1 (1.8×) | — | — | 20.2 (32.4×) | +| scaleFree 1,000 | **0.79** | 1.00 (1.3×) | — | — | 28.1 (35.7×) | +| grid 1,000 | 0.84 (1.6×) | **0.52** | — | — | 30.6 (59.2×) | +| layeredDag 1,000 | **0.54** | 0.93 (1.7×) | — | — | 36.6 (68.4×) | +| random 10,000 | **5.3** | 11.5 (2.2×) | — | — | 7703 (1454.0×) | +| scaleFree 10,000 | **5.1** | 6.4 (1.3×) | — | — | 11869 (2331.2×) | +| grid 10,000 | **5.7** | 6.5 (1.1×) | — | — | 6258 (1105.2×) | +| layeredDag 10,000 | **6.9** | 7.2 (1.0×) | — | — | 7486 (1085.3×) | +| random 100,000 | **54.6** | 190 (3.5×) | — | — | crash | +| scaleFree 100,000 | **95.9** | 157 (1.6×) | — | — | >10s | +| grid 100,000 | 127 (1.1×) | **120** | — | — | crash | +| layeredDag 100,000 | **92.4** | 197 (2.1×) | — | — | crash | + +ngraph and graphlib have no PageRank. cytoscape's PageRank threw `Invalid array length` on three of the four 100k graphs. + +## Connected components + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **0.02** | 0.42 (17.9×) | — | 1.1 (45.1×) | 37.1 (1577.3×) | +| scaleFree 1,000 | **0.02** | 0.48 (22.7×) | — | 0.69 (33.1×) | 36.0 (1722.1×) | +| grid 1,000 | **0.01** | 0.26 (23.1×) | — | 0.25 (22.9×) | 24.8 (2225.7×) | +| layeredDag 1,000 | **0.02** | 0.46 (30.1×) | — | 0.28 (18.7×) | 38.8 (2562.9×) | +| random 10,000 | **0.35** | 9.6 (27.1×) | — | crash | 526 (1490.3×) | +| scaleFree 10,000 | **0.22** | 12.1 (54.4×) | — | 7.6 (34.2×) | 510 (2293.0×) | +| grid 10,000 | **0.10** | 3.6 (35.0×) | — | crash | 302 (2980.0×) | +| layeredDag 10,000 | **0.30** | 5.9 (19.7×) | — | crash | 464 (1541.3×) | +| random 100,000 | **4.4** | 225 (51.0×) | — | >10s | 13448 (3047.4×) | +| scaleFree 100,000 | **3.3** | 248 (75.0×) | — | crash | 16249 (4906.7×) | +| grid 100,000 | **1.9** | 90.1 (48.3×) | — | >10s | 3921 (2100.9×) | +| layeredDag 100,000 | **3.9** | 196 (50.0×) | — | >10s | 8171 (2086.8×) | + +graphlib's `alg.components` uses recursive DFS and overflowed the call stack (`Maximum call stack size exceeded`) at 10,000 nodes on the random, grid, and layeredDag graphs, and at 100,000 on scaleFree. Where it survived, it was 19–34× slower; the remaining 100k cells were skipped after exceeding 10 s. + +## Betweenness centrality + +Run only at n=1,000 — Brandes is O(V·E) for every library, so larger sizes are capped for everyone. + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **42.5** | 80.3 (1.9×) | — | — | 938 (22.1×) | +| scaleFree 1,000 | **2.7** | 4.1 (1.5×) | — | — | 153 (56.6×) | +| grid 1,000 | **3.8** | 18.6 (4.9×) | — | — | 304 (80.8×) | +| layeredDag 1,000 | **15.9** | 35.5 (2.2×) | — | — | 458 (28.8×) | + +## Degree sweep + +Sum the degree of every node via each library's degree API. + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | 0.29 (9.3×) | 0.03 (1.1×) | **0.03** | 0.87 (27.9×) | 3.2 (103.1×) | +| scaleFree 1,000 | 0.20 (4.0×) | **0.05** | 0.10 (1.9×) | 1.1 (21.0×) | 3.2 (61.5×) | +| grid 1,000 | 0.17 (5.3×) | 0.05 (1.5×) | **0.03** | 0.24 (7.5×) | 2.0 (60.8×) | +| layeredDag 1,000 | 0.20 (4.8×) | **0.04** | 0.08 (2.0×) | 0.76 (18.3×) | 3.6 (84.9×) | +| random 10,000 | 4.6 (14.0×) | 0.42 (1.3×) | **0.33** | 22.0 (67.2×) | 54.9 (167.9×) | +| scaleFree 10,000 | 3.2 (9.3×) | 0.40 (1.2×) | **0.34** | 46.3 (135.2×) | 57.0 (166.2×) | +| grid 10,000 | 1.8 (5.1×) | 0.45 (1.3×) | **0.35** | 11.4 (33.0×) | 27.3 (78.6×) | +| layeredDag 10,000 | 2.7 (8.1×) | 0.44 (1.3×) | **0.33** | 16.3 (48.9×) | 39.7 (119.2×) | +| random 100,000 | 104 (21.9×) | 5.2 (1.1×) | **4.7** | 412 (87.1×) | 753 (159.2×) | +| scaleFree 100,000 | 94.2 (21.2×) | 6.2 (1.4×) | **4.4** | 617 (138.7×) | 831 (186.9×) | +| grid 100,000 | 107 (19.2×) | 11.9 (2.1×) | **5.6** | 200 (35.8×) | 335 (59.9×) | +| layeredDag 100,000 | 93.5 (22.9×) | 11.3 (2.8×) | **4.1** | 301 (73.7×) | 634 (155.4×) | + +## Reading the numbers + +Where `@statelyai/graph` is fastest: + +- **Build** — fastest in every cell, 1.4–80× ahead. Plain-object graphs with lazy WeakMap indexing have very little construction overhead. +- **BFS** — fastest on every non-degenerate row, 4–28× ahead of the next library at 10k–100k. +- **Connected components** — fastest in every cell, 18–75× ahead of graphology (the next-fastest with the API). +- **Single-pair shortest path** — fastest on every row where the search does real work; bidirectional Dijkstra is why `random 100,000` completes in 0.6 ms while full single-source Dijkstra (graphlib) takes 431 ms. +- **PageRank and betweenness** — fastest in most cells, but only by 1.0–3.5× over graphology, and graphology wins `grid` PageRank at 1,000 (0.52 vs 0.84 ms) and 100,000 (120 vs 127 ms). These two are effectively at parity with graphology. + +Where it is not fastest: + +- **Degree sweep** — ngraph and graphology are consistently faster, by 4–23×. `getDegree` recomputes per call against the edge index, while ngraph/graphology maintain adjacency structures that make per-node degree nearly free. If your workload is dominated by per-node degree queries in a tight loop, this matters. +- **scaleFree traversal/sssp cells** — graphology and graphlib post faster sub-millisecond times. These cells terminate after touching a handful of nodes and are mostly call overhead, but the raw numbers are what they are. + +Other findings worth knowing regardless of which library you pick: + +- graphlib's recursive-DFS `components` overflows the Node call stack at 10,000 nodes on three of the four graph shapes. +- cytoscape's PageRank throws `Invalid array length` at 100,000 nodes on three of the four shapes; headless cytoscape is generally 2–4 orders of magnitude slower across the board, which is unsurprising — it is a visualization toolkit, not an algorithms library. +- ngraph has no built-in PageRank, components, or betweenness; graphlib has no PageRank or betweenness. + +## Methodology + +Source: [`bench/compare/run.ts`](../bench/compare/run.ts), [`bench/compare/generate.ts`](../bench/compare/generate.ts), [`bench/compare/adapters.ts`](../bench/compare/adapters.ts). Raw output: [`bench/compare/results/2026-06-11.md`](../bench/compare/results/2026-06-11.md) and [`2026-06-11.json`](../bench/compare/results/2026-06-11.json). + +- **Identical inputs.** Seeded generators emit a neutral edge list (integer endpoints, weights); every library builds from the same list. Simple directed graphs only (no parallel edges or self-loops) — the lowest common denominator across libraries. +- **Four shapes × three sizes** (1,000 / 10,000 / 100,000 nodes): + - `random` — uniform random, ~3 edges/node, with a spanning chain so traversals reach most of the graph + - `scaleFree` — preferential attachment (k=3); hub-heavy, with most nodes unreachable from node 0 + - `grid` — square lattice with right/down directed edges + - `layeredDag` — layered DAG with local fanout and occasional skip edges (statechart/workflow-like) +- **Idiomatic usage.** Each library runs through a thin adapter calling its public API the way a user would — no hand-tuned ports. Libraries lacking a built-in BFS get a minimal queue loop over their neighbor API. `—` means no equivalent API exists. +- **Timing.** One warmup run, then samples until ≥5 runs or a 1.5 s budget; the table reports the median. +- **`crash`** means the library threw during the workload (e.g. stack overflow, `Invalid array length`); the error message is recorded in the JSON. A crash is treated as a result, not a harness failure. +- **`>10s`** means a single run exceeded 10 s, so the workload was skipped for that library at that and larger sizes. +- **Fairness notes.** graphlib's only shortest-path API is full single-source Dijkstra, so its `sssp` cells pay the all-targets cost. Betweenness is capped at n=1,000 for every library because Brandes is O(V·E). diff --git a/docs/migrating-from-graphlib.md b/docs/migrating-from-graphlib.md new file mode 100644 index 0000000..89e951f --- /dev/null +++ b/docs/migrating-from-graphlib.md @@ -0,0 +1,122 @@ +# Migrating from @dagrejs/graphlib + +A guide for developers moving an existing `@dagrejs/graphlib` (often plus `dagre`) codebase to `@statelyai/graph`. + +## Why migrate + +- **Plain JSON data model.** A graph is a plain object (`{ nodes: [], edges: [] }`), not a class instance. It serializes with `JSON.stringify`, diffs structurally, and crosses worker/process boundaries with no hydration step. graphlib requires `graphlib.json.write`/`read` round-trips. +- **Performance.** Standalone algorithm functions over indexed plain arrays are competitive with or faster than graphlib across traversal, shortest-path, and component workloads. See [benchmarks](./benchmarks.md). +- **Maintained, broader algorithms.** Everything in `graphlib.alg` has an equivalent here, plus centrality, communities, max-flow, isomorphism, dominators, and more. +- **Dagre still works.** `getDagreLayout` from `@statelyai/graph/layout/dagre` runs dagre for you and returns a new positioned graph. + +## Concept mapping + +| graphlib | @statelyai/graph | +| --- | --- | +| `new Graph({ directed: true })` | `createGraph({ mode: 'directed' })` (the default) | +| `new Graph({ directed: false })` | `createGraph({ mode: 'undirected' })` — plus per-edge `mode` overrides for mixed graphs | +| `new Graph({ multigraph: true })` | Native — every edge has an explicit `id`, so parallel edges just work | +| `new Graph({ compound: true })` | Native — set `parentId` on nodes | +| `g.setNode('a', label)` | `addNode(graph, { id: 'a', label: 'A', data: {...} })` | +| `g.setEdge('a', 'b', label, name)` | `addEdge(graph, { id: 'e1', sourceId: 'a', targetId: 'b', data: {...} })` | +| `g.removeNode(v)` / `g.removeEdge(v, w)` | `deleteNode(graph, id)` / `deleteEdge(graph, id)` | +| `g.setNode(v, newLabel)` (upsert) | `updateNode(graph, id, { ... })` / `updateEdge(graph, id, { ... })` | +| Node/edge label (arbitrary value) | `data` (arbitrary JSON); `label` here is a display string; numeric weight goes in `weight` | +| `g.node(v)` / `g.hasNode(v)` | `getNode(graph, id)` / `hasNode(graph, id)` | +| `g.edge(v, w)` | `getEdge(graph, edgeId)` or `getEdgesBetween(graph, sourceId, targetId)` | +| `g.nodes()` / `g.edges()` | `graph.nodes` / `graph.edges` — plain arrays, just read them | +| `g.successors(v)` / `g.predecessors(v)` / `g.neighbors(v)` | `getSuccessors` / `getPredecessors` / `getNeighbors` | +| `g.inEdges(v)` / `g.outEdges(v)` / `g.nodeEdges(v)` | `getInEdges` / `getOutEdges` / `getEdgesOf` | +| `g.setParent(v, p)` / `g.parent(v)` / `g.children(v)` | `parentId` on the node config / `getParent(graph, id)` / `getChildren(graph, id)` | +| `g.sources()` / `g.sinks()` | `getSources(graph)` / `getSinks(graph)` | +| `g.setGraph(label)` / `g.graph()` | `data` on the graph config / `graph.data` | +| `g.filterNodes(fn)` | `getSubgraph(graph, nodeIds)` | +| `graphlib.json.write(g)` / `read` | Not needed — the graph already *is* JSON | + +### `graphlib.alg.*` + +| graphlib | @statelyai/graph | +| --- | --- | +| `alg.dijkstra(g, source, weightFn)` | `getShortestPaths(graph, { from })` (all reachable targets) or `getShortestPath(graph, { from, to })` (single pair, bidirectional Dijkstra) | +| `alg.dijkstraAll` / `alg.floydWarshall` | `getAllPairsShortestPaths(graph, { algorithm: 'dijkstra' \| 'floyd-warshall' \| 'bellman-ford' })` | +| `alg.tarjan(g)` | `getStronglyConnectedComponents(graph)` | +| `alg.topsort(g)` | `getTopologicalSort(graph)` — returns `null` on cycles instead of throwing `CycleException` | +| `alg.components(g)` | `getConnectedComponents(graph)` | +| `alg.preorder(g, vs)` / `alg.postorder(g, vs)` | `getPreorder(graph, { from })` / `getPostorder(graph, { from })` (also `getPreorders`/`getPostorders` and lazy `genPreorders`/`genPostorders`) | +| `alg.dfs(g, vs, order)` | `dfs(graph, startId)` / `bfs(graph, startId)` — lazy generators yielding nodes | +| `alg.isAcyclic(g)` | `isAcyclic(graph)` | +| `alg.findCycles(g)` | `getCycles(graph)` (or lazy `genCycles(graph)`) | +| `alg.prim(g, weightFn)` | `getMinimumSpanningTree(graph, { algorithm: 'prim' \| 'kruskal', getWeight })` | + +## Worked example + +### Before: graphlib + dagre + +```ts +import * as graphlib from '@dagrejs/graphlib'; +import dagre from '@dagrejs/dagre'; + +const g = new graphlib.Graph({ directed: true, multigraph: true }); +g.setGraph({ rankdir: 'LR' }); +g.setDefaultEdgeLabel(() => ({})); + +g.setNode('a', { label: 'Start', width: 100, height: 40 }); +g.setNode('b', { label: 'Middle', width: 100, height: 40 }); +g.setNode('c', { label: 'End', width: 100, height: 40 }); +g.setEdge('a', 'b', { weight: 1 }, 'e1'); +g.setEdge('b', 'c', { weight: 2 }, 'e2'); + +const distances = graphlib.alg.dijkstra(g, 'a', (e) => g.edge(e).weight); +// distances['c'].distance === 3 + +dagre.layout(g); // mutates g; positions on g.node('a').x / .y (centers) +``` + +### After: @statelyai/graph + +```ts +import { createGraph, getShortestPath } from '@statelyai/graph'; +import { getDagreLayout } from '@statelyai/graph/layout/dagre'; + +const graph = createGraph({ + nodes: [ + { id: 'a', label: 'Start', width: 100, height: 40 }, + { id: 'b', label: 'Middle', width: 100, height: 40 }, + { id: 'c', label: 'End', width: 100, height: 40 }, + ], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b', weight: 1 }, + { id: 'e2', sourceId: 'b', targetId: 'c', weight: 2 }, + ], +}); + +const path = getShortestPath(graph, { from: 'a', to: 'c' }); +// path.source.id === 'a' +// path.steps.map((s) => s.node.id) → ['b', 'c'] + +const laidOut = getDagreLayout(graph, { direction: 'right' }); +// Pure: returns a new VisualGraph; `graph` is untouched. +// laidOut.nodes[0].x / .y are top-left coordinates (dagre reports centers; +// the adapter converts). Edge polylines land on edge.points. +``` + +`getDagreLayout` requires `@dagrejs/dagre` as an optional peer dependency, sets up the multigraph/compound graphlib graph internally (including `parentId` → `setParent`), and accepts raw dagre options via `graphOptions` for anything not covered by `direction`/`spacing`. + +## Gotchas + +- **Mutations throw; graphlib upserts silently.** `g.setNode` creates-or-updates and `g.removeNode` is a silent no-op. Here, `addNode`/`addEdge` throw if the id already exists (or an edge endpoint is missing), and `deleteNode`/`deleteEdge`/`updateNode`/`updateEdge` throw if the id doesn't exist. Pick `add*` vs `update*` deliberately during migration. +- **Edge ids are explicit.** graphlib identifies edges by `(v, w, name)`; here every edge has a required `id`, which is also what makes multigraphs free. Lookup by endpoints is `getEdgesBetween(graph, sourceId, targetId)` (returns an array — there may be parallel edges). +- **Label vs data vs weight.** graphlib's "label" is one arbitrary value per node/edge. Here it splits three ways: `label` (display string), `data` (arbitrary JSON payload, defaults to `null`), `weight` (number on edges). +- **Default weight is 1, not your label.** `graphlib.alg.dijkstra` defaults every edge to weight 1 unless you pass a `weightFn` reading your label. Here weighted algorithms default to `edge.weight ?? 1`; pass `getWeight: (edge) => ...` to read from `data` instead. +- **Directedness is a mode, and it can be mixed.** Instead of a constructor-time `directed` boolean, the graph has `mode: 'directed' | 'undirected' | 'bidirectional'` and individual edges may override it — something graphlib cannot express. +- **`topsort` doesn't throw.** `getTopologicalSort` returns `null` for cyclic graphs instead of raising `CycleException`. Check the return value. +- **Layout is pure.** `dagre.layout(g)` mutates your graph in place; `getDagreLayout(graph)` returns a new `VisualGraph` and leaves the input alone. Node positions are top-left based, not centers. +- **Compound is always on.** No `compound: true` flag — set `parentId` on any node. `addNode` validates that the parent exists. +- **In-place field mutation needs `invalidateIndex`.** Indexes rebuild automatically when you replace arrays or use the mutation API, but if you reach in and edit a node/edge field directly, call `invalidateIndex(graph)`. + +## Coverage gaps + +Every `graphlib.alg.*` function has a direct equivalent (see table above). What has no one-line counterpart: + +- `setDefaultNodeLabel` / `setDefaultEdgeLabel` — no default-data factories; supply `data` per entity. +- `graphlib.json.write`/`read` produce graphlib's specific JSON shape; if you have stored graphs in that format, you'll need a small one-time conversion to `GraphConfig` (nodes/edges arrays with `id`/`sourceId`/`targetId`). diff --git a/docs/react-flow-elk-pipeline.md b/docs/react-flow-elk-pipeline.md new file mode 100644 index 0000000..e6d72ee --- /dev/null +++ b/docs/react-flow-elk-pipeline.md @@ -0,0 +1,254 @@ +# React Flow + ELK: automatic layout cookbook + +A recipe for building a React Flow (xyflow v12) node-graph UI where layout is +computed by ELK and the graph — not React Flow's node array — is the single +source of truth. + +## The pipeline + +``` +domain model ─createGraph→ @statelyai/graph ─getElkLayout→ VisualGraph + ▲ │ toXYFlow + └────── fromXYFlow ◄── user edits ◄── +``` + +Layout is a pure function: `getElkLayout(graph)` returns a new `VisualGraph` +with node positions/sizes, routed edge `points`, and edge-label rects. Child +node coordinates are parent-relative — the same convention React Flow uses, so +positions map 1:1. + +## 1. Build the graph + +```ts +import { createGraph } from '@statelyai/graph'; + +const graph = createGraph({ + id: 'pipeline', + nodes: [ + { id: 'fetch', label: 'Fetch', ports: [{ name: 'result', direction: 'out' }] }, + { id: 'transform', label: 'Transform', parentId: 'stage' }, + { id: 'stage', label: 'Stage' }, // compound parent + { id: 'render', label: 'Render', ports: [{ name: 'input', direction: 'in' }] }, + ], + edges: [ + { id: 'e1', sourceId: 'fetch', sourcePort: 'result', targetId: 'transform' }, + { id: 'e2', sourceId: 'transform', targetId: 'render', targetPort: 'input' }, + ], +}); +``` + +## 2. Layout, convert, render + +```tsx +import { useEffect, useState } from 'react'; +import { ReactFlow, type Node, type Edge } from '@xyflow/react'; +import '@xyflow/react/dist/style.css'; +import { getElkLayout } from '@statelyai/graph/layout/elk'; +import { toXYFlow } from '@statelyai/graph/xyflow'; + +export function Diagram() { + const [nodes, setNodes] = useState([]); + const [edges, setEdges] = useState([]); + + useEffect(() => { + let cancelled = false; + getElkLayout(graph, { algorithm: 'layered', direction: 'right' }).then( + (laidOut) => { + if (cancelled) return; + const flow = toXYFlow(laidOut); + setNodes(flow.nodes as Node[]); + setEdges(flow.edges as Edge[]); + }, + ); + return () => { cancelled = true; }; + }, []); + + return ; +} +``` + +`toXYFlow` maps `node.x/y → position.{x,y}` and `width`/`height` directly, +emits parents before children (a React Flow requirement), and maps +`edge.sourcePort/targetPort → sourceHandle/targetHandle`. Everything it can't +express natively (label, color, ports, weight, …) rides along under a reserved +`__statelyai` key in `data`, so `fromXYFlow` can round-trip it losslessly. + +Two render-side notes: + +- React Flow renders the *top-level* `edge.label`, but `toXYFlow` stores the + label at `edge.data.label`. Lift it if you want built-in edge labels: + `flow.edges.map((e) => ({ ...e, label: (e.data as any)?.label }))`. +- `node.shape` becomes React Flow's `type`. Only set `shape` to values you've + registered in `nodeTypes`, or React Flow falls back to the default node. + +## 3. Measure real node sizes (two-pass) + +ELK needs node dimensions before it can lay anything out, but real dimensions +come from the DOM. The honest pattern is two passes: **render → measure → +layout → re-render**. React Flow measures nodes for you and exposes the result +on `node.measured`; `useNodesInitialized()` tells you when that's done. + +```tsx +import { useNodesInitialized, useReactFlow } from '@xyflow/react'; +import { DEFAULT_NODE_SIZE } from '@statelyai/graph/layout'; + +function useElkLayout(setNodes: (n: Node[]) => void, setEdges: (e: Edge[]) => void) { + const nodesInitialized = useNodesInitialized(); + const { getNodes } = useReactFlow(); + + useEffect(() => { + if (!nodesInitialized) return; // pass 1 rendered at (0,0); DOM now measured + const sizes = new Map(getNodes().map((n) => [n.id, n.measured])); + + getElkLayout(graph, { + measure: (node) => { + const m = sizes.get(node.id); + return m?.width && m?.height + ? { width: m.width, height: m.height } + : DEFAULT_NODE_SIZE; + }, + }).then((laidOut) => { + const flow = toXYFlow(laidOut); + setNodes(flow.nodes as Node[]); + setEdges(flow.edges as Edge[]); + }); + }, [nodesInitialized]); +} +``` + +Pass 1 renders `toXYFlow(graph)` with whatever positions exist (all `0,0` for +a fresh graph — hide or fade the canvas to avoid a flash). Sizes resolve as +`measure` → the node's own `width`/`height` → `DEFAULT_NODE_SIZE` (100×50); +layout adapters never guess text sizes. Reuse measured sizes on later runs. + +## 4. Layout in a web worker + +ELK layouts of large graphs can block the main thread. `elkjs` can run in a +worker, and `getElkLayout` accepts any pre-constructed instance via its +**`elk`** option (anything with a `layout(graph): Promise` method): + +```ts +import ELK from 'elkjs/lib/elk-api'; // slim API — no bundled engine +import { getElkLayout } from '@statelyai/graph/layout/elk'; + +const elk = new ELK({ + workerFactory: () => + new Worker(new URL('elkjs/lib/elk-worker.min.js', import.meta.url)), +}); +// or, serving the worker file yourself: +// const elk = new ELK({ workerUrl: '/elk-worker.min.js' }); + +const laidOut = await getElkLayout(graph, { elk }); +``` + +Without `elk`, the adapter constructs a default in-process `new ELK()` once +and reuses it. + +## 5. Smooth re-layout + +When the graph changes (node added, edge removed), lay out again and tween +between the old and new positions. `genLayoutTransition` yields interpolated +frames; `applyLayoutFrame` writes a frame's positions onto the graph in place. +Drive it with `requestAnimationFrame`: + +```tsx +import { + genLayoutTransition, + applyLayoutFrame, +} from '@statelyai/graph/layout'; + +let current: VisualGraph = laidOut; // last settled layout + +async function relayout() { + const next = await getElkLayout(current, { elk }); + const frames = genLayoutTransition(current, next, { steps: 20 }); + + const tick = () => { + const { value, done } = frames.next(); + if (done) { + current = value; // generator returns the settled VisualGraph + const flow = toXYFlow(current); + setNodes(flow.nodes as Node[]); + setEdges(flow.edges as Edge[]); + return; + } + applyLayoutFrame(current, value); // mutate positions in place + setNodes(toXYFlow(current).nodes as Node[]); + requestAnimationFrame(tick); + }; + requestAnimationFrame(tick); +} +``` + +Frames carry node positions only — edge routes are not interpolated, so apply +the final edge geometry once at the end (as above) or hide edges mid-tween. +Alternatively, skip the tween entirely and just `setNodes` with the new +layout; add CSS transitions on `.react-flow__node` if you want easing without +a loop. `getLayoutBounds(graph)` and `centerGraph(graph, rect)` help keep a +fresh layout centered in your viewport before converting. + +## 6. Compound nodes and ports + +**Compound:** ELK is the engine of choice here — `parentId` hierarchy is +first-class, parents are sized around their children, and child coordinates +come back parent-relative, which is exactly what React Flow expects. +`toXYFlow` sets `parentId` on child nodes and orders parents first. It does +*not* set `extent` — add it yourself if children should stay confined: + +```ts +const nodes = flow.nodes.map((n) => + n.parentId ? { ...n, extent: 'parent' as const } : n, +) as Node[]; +``` + +**Ports:** edges reference ports by name, and `toXYFlow` maps them to +`sourceHandle`/`targetHandle`. The port definitions themselves travel in node +metadata — render them as handles in a custom node, with `Handle.id` equal to +the port name: + +```tsx +import { Handle, Position, type NodeProps } from '@xyflow/react'; + +function PortNode({ data }: NodeProps) { + const meta = (data as any).__statelyai?.node; + return ( +
+ {meta?.label} + {(meta?.ports ?? []).map((port: { name: string; direction?: string }) => ( + + ))} +
+ ); +} +``` + +Port `direction` is advisory; ELK uses it for port-side placement during +layout, and you choose how to render it. + +## 7. Back to the graph + +After the user drags nodes or rewires edges, fold React Flow's state back into +a graph with `fromXYFlow`. Keep the `data` blob from `toXYFlow` — it carries +graph-level metadata (`id`, `mode`, `direction`, …): + +```ts +import { fromXYFlow } from '@statelyai/graph/xyflow'; + +const updated = fromXYFlow({ + nodes: getNodes(), + edges: getEdges(), + data: flowData, // the `data` returned by toXYFlow +}); +``` + +`fromXYFlow` prefers `node.measured` sizes (React Flow's DOM measurements) +over declared `width`/`height`, maps `sourceHandle`/`targetHandle` back to +ports, and restores original node/edge `data` from the `__statelyai` metadata. +The result is a `VisualGraph` — your single source of truth — ready for the +next `getElkLayout` pass, persistence, or any of the library's queries and +algorithms. diff --git a/src/formats/cytoscape/index.ts b/src/formats/cytoscape/index.ts index 8b605dc..dd99cfa 100644 --- a/src/formats/cytoscape/index.ts +++ b/src/formats/cytoscape/index.ts @@ -28,7 +28,7 @@ export interface CytoscapeJSON { * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { toCytoscapeJSON } from '@statelyai/graph/formats/cytoscape'; + * import { toCytoscapeJSON } from '@statelyai/graph/cytoscape'; * * const graph = createGraph({ * nodes: [{ id: 'a' }, { id: 'b' }], @@ -102,7 +102,7 @@ export function toCytoscapeJSON(graph: Graph): CytoscapeJSON { * * @example * ```ts - * import { fromCytoscapeJSON } from '@statelyai/graph/formats/cytoscape'; + * import { fromCytoscapeJSON } from '@statelyai/graph/cytoscape'; * * const graph = fromCytoscapeJSON({ * elements: { @@ -176,7 +176,7 @@ export function fromCytoscapeJSON(cyto: CytoscapeJSON): Graph { * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { cytoscapeConverter } from '@statelyai/graph/formats/cytoscape'; + * import { cytoscapeConverter } from '@statelyai/graph/cytoscape'; * * const graph = createGraph({ * nodes: [{ id: 'a' }, { id: 'b' }], diff --git a/src/formats/d3/index.ts b/src/formats/d3/index.ts index 2ae9460..3e0c237 100644 --- a/src/formats/d3/index.ts +++ b/src/formats/d3/index.ts @@ -34,7 +34,7 @@ export interface D3Graph { * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { toD3Graph } from '@statelyai/graph/formats/d3'; + * import { toD3Graph } from '@statelyai/graph/d3'; * * const graph = createGraph({ * nodes: [{ id: 'a' }, { id: 'b' }], @@ -99,7 +99,7 @@ export function toD3Graph(graph: Graph): D3Graph { * * @example * ```ts - * import { fromD3Graph } from '@statelyai/graph/formats/d3'; + * import { fromD3Graph } from '@statelyai/graph/d3'; * * const graph = fromD3Graph({ * nodes: [{ id: 'a' }, { id: 'b' }], @@ -169,7 +169,7 @@ export function fromD3Graph(d3: D3Graph): Graph { * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { d3Converter } from '@statelyai/graph/formats/d3'; + * import { d3Converter } from '@statelyai/graph/d3'; * * const graph = createGraph({ * nodes: [{ id: 'a' }, { id: 'b' }], diff --git a/src/formats/gml/index.ts b/src/formats/gml/index.ts index 6ee03e6..54475b8 100644 --- a/src/formats/gml/index.ts +++ b/src/formats/gml/index.ts @@ -9,7 +9,7 @@ import { createFormatConverter } from '../converter'; * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { toGML } from '@statelyai/graph/formats/gml'; + * import { toGML } from '@statelyai/graph/gml'; * * const graph = createGraph({ * nodes: [{ id: 'a' }, { id: 'b' }], @@ -157,7 +157,7 @@ function gmlString(s: string): string { * * @example * ```ts - * import { fromGML } from '@statelyai/graph/formats/gml'; + * import { fromGML } from '@statelyai/graph/gml'; * * const graph = fromGML(` * graph [ @@ -454,7 +454,7 @@ function parseNumber( * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { gmlConverter } from '@statelyai/graph/formats/gml'; + * import { gmlConverter } from '@statelyai/graph/gml'; * * const graph = createGraph({ * nodes: [{ id: 'a' }, { id: 'b' }], diff --git a/src/formats/jgf/index.ts b/src/formats/jgf/index.ts index 2132455..94e228b 100644 --- a/src/formats/jgf/index.ts +++ b/src/formats/jgf/index.ts @@ -35,7 +35,7 @@ export interface JGFGraph { * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { toJGF } from '@statelyai/graph/formats/jgf'; + * import { toJGF } from '@statelyai/graph/jgf'; * * const graph = createGraph({ * nodes: [{ id: 'a' }, { id: 'b' }], @@ -111,7 +111,7 @@ export function toJGF(graph: Graph): JGFGraph { * * @example * ```ts - * import { fromJGF } from '@statelyai/graph/formats/jgf'; + * import { fromJGF } from '@statelyai/graph/jgf'; * * const graph = fromJGF({ * graph: { @@ -193,7 +193,7 @@ export function fromJGF(jgf: JGFGraph): Graph { * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { jgfConverter } from '@statelyai/graph/formats/jgf'; + * import { jgfConverter } from '@statelyai/graph/jgf'; * * const graph = createGraph({ * nodes: [{ id: 'a' }, { id: 'b' }], diff --git a/src/formats/tgf/index.ts b/src/formats/tgf/index.ts index 89282ae..c63e24a 100644 --- a/src/formats/tgf/index.ts +++ b/src/formats/tgf/index.ts @@ -9,7 +9,7 @@ import { createFormatConverter } from '../converter'; * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { toTGF } from '@statelyai/graph/formats/tgf'; + * import { toTGF } from '@statelyai/graph/tgf'; * * const graph = createGraph({ * nodes: [{ id: 'a', label: 'A' }, { id: 'b', label: 'B' }], @@ -43,7 +43,7 @@ export function toTGF(graph: Graph): string { * * @example * ```ts - * import { fromTGF } from '@statelyai/graph/formats/tgf'; + * import { fromTGF } from '@statelyai/graph/tgf'; * * const graph = fromTGF('a A\nb B\n#\na b go'); * // graph.nodes = [{ id: 'a', label: 'A' }, { id: 'b', label: 'B' }] @@ -109,7 +109,7 @@ export function fromTGF(tgf: string): Graph { * @example * ```ts * import { createGraph } from '@statelyai/graph'; - * import { tgfConverter } from '@statelyai/graph/formats/tgf'; + * import { tgfConverter } from '@statelyai/graph/tgf'; * * const graph = createGraph({ * nodes: [{ id: 'a' }, { id: 'b' }], diff --git a/src/formats/xyflow/index.ts b/src/formats/xyflow/index.ts index c9c7726..da2cca3 100644 --- a/src/formats/xyflow/index.ts +++ b/src/formats/xyflow/index.ts @@ -109,7 +109,7 @@ function orderParentsFirst(nodes: XYFlowNode[]): XYFlowNode[] { * @example * ```ts * import { createVisualGraph } from '@statelyai/graph'; - * import { toXYFlow } from '@statelyai/graph/formats/xyflow'; + * import { toXYFlow } from '@statelyai/graph/xyflow'; * * const graph = createVisualGraph({ * nodes: [ @@ -191,7 +191,7 @@ export function toXYFlow(graph: VisualGraph): XYFlow { * * @example * ```ts - * import { fromXYFlow } from '@statelyai/graph/formats/xyflow'; + * import { fromXYFlow } from '@statelyai/graph/xyflow'; * * const graph = fromXYFlow({ * nodes: [ @@ -303,7 +303,7 @@ export function fromXYFlow(flow: XYFlow): VisualGraph { * @example * ```ts * import { createVisualGraph } from '@statelyai/graph'; - * import { xyflowConverter } from '@statelyai/graph/formats/xyflow'; + * import { xyflowConverter } from '@statelyai/graph/xyflow'; * * const graph = createVisualGraph({ * nodes: [ From 0498d52e7f55e9aa495d5870ab59a54613b75f6c Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:26:17 -0400 Subject: [PATCH 08/15] =?UTF-8?q?feat(algorithms):=20k-core,=20Katz,=20har?= =?UTF-8?q?dened=20eigenvector,=20bipartite=20matching=20(Hopcroft?= =?UTF-8?q?=E2=80=93Karp),=20min-cut,=20seeded=20LPA,=20graph=20generators?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/bright-layout-suite.md | 15 +++ .changeset/keen-analysis-tail.md | 13 ++ .changeset/quick-lazy-paths.md | 5 + src/algorithms.ts | 20 ++- src/algorithms/bipartite.ts | 209 +++++++++++++++++++++++++++++ src/algorithms/centrality.ts | 125 ++++++++++++++++-- src/algorithms/community.ts | 67 +++++++++- src/algorithms/cores.ts | 131 +++++++++++++++++++ src/algorithms/flow.ts | 147 +++++++++++++++++---- src/algorithms/shared.ts | 14 ++ src/generators.ts | 128 ++++++++++++++++++ src/index.ts | 18 +++ tests/bipartite.test.ts | 211 ++++++++++++++++++++++++++++++ tests/centrality.test.ts | 113 ++++++++++++++++ tests/community.test.ts | 31 +++++ tests/cores.test.ts | 88 +++++++++++++ tests/differential/oracle.test.ts | 89 +++++++++++++ tests/flow.test.ts | 87 +++++++++++- tests/generators.test.ts | 118 +++++++++++++++++ 19 files changed, 1585 insertions(+), 44 deletions(-) create mode 100644 .changeset/bright-layout-suite.md create mode 100644 .changeset/keen-analysis-tail.md create mode 100644 .changeset/quick-lazy-paths.md create mode 100644 src/algorithms/bipartite.ts create mode 100644 src/algorithms/cores.ts create mode 100644 src/generators.ts create mode 100644 tests/bipartite.test.ts create mode 100644 tests/cores.test.ts create mode 100644 tests/generators.test.ts diff --git a/.changeset/bright-layout-suite.md b/.changeset/bright-layout-suite.md new file mode 100644 index 0000000..8fc0bf8 --- /dev/null +++ b/.changeset/bright-layout-suite.md @@ -0,0 +1,15 @@ +--- +'@statelyai/graph': minor +--- + +Layout suite round two: transitions, geometry utilities, portable constraints, and four more engines. + +- **`genLayoutTransition(from, to, options?)`** (`@statelyai/graph/layout`, zero-dep) — tween between two layouts of the same graph: yields interpolated `LayoutFrame`s (drive with `applyLayoutFrame`, one per animation frame) and returns the target layout. Lay out with one engine, re-lay out with another, morph live. Options: `steps` (default 30), `ease` (default smoothstep). +- **Geometry utilities** (`@statelyai/graph/layout`) — `translateGraph(graph, dx, dy)` and `centerGraph(graph, rect)` (**mutable**, in place): shift/center node positions, edge route `points`, and edge label rects. Hierarchy-aware — parent-relative children and container-relative edge routes are left alone. +- **`LayoutOptions.constraints`** — portable, advisory layout constraints. First constraint: `layer(node)` assigns nodes to ordered layers along the flow axis. ELK maps it to partitions (`elk.partitioning.partition`); the Graphviz `dot` engine maps it to `{ rank=same; … }` groups; engines without a layer concept ignore it. +- **`@statelyai/graph/layout/forceatlas2`** — `getForceAtlas2Layout` (sync; optional peers `graphology` + `graphology-layout-forceatlas2`): seeded determinism, native pinning via `isFixed`, edge `weight` influence. +- **`@statelyai/graph/layout/d3-hierarchy`** — `getTidyTreeLayout` (sync; optional peer `d3-hierarchy`): Reingold–Tilford tidy tree. Root from `rootId` → `initialNodeId` → unique source; forests supported; non-tree extra edges preserved (spanning-tree layout). +- **`@statelyai/graph/layout/webcola`** — `getColaLayout` (sync; optional peer `webcola`): constraint-based layout with overlap avoidance, seeded determinism, `isFixed` pinning, DAG flow via `direction`. +- **`@statelyai/graph/layout/cytoscape`** — `getCytoscapeLayout` (async; optional peer `cytoscape`, headless): bridges cytoscape's layout ecosystem (`grid`, `circle`, `concentric`, `breadthfirst`, `cose`, plus caller-registered extensions via the injectable `cy` option). Compound nodes map to cytoscape parents. + +The package smoke test exercises all nine layout entry points against the packed tarball. diff --git a/.changeset/keen-analysis-tail.md b/.changeset/keen-analysis-tail.md new file mode 100644 index 0000000..b915095 --- /dev/null +++ b/.changeset/keen-analysis-tail.md @@ -0,0 +1,13 @@ +--- +'@statelyai/graph': minor +--- + +Analytical coverage tail: cores, Katz, bipartite matching, min-cut, seeded label propagation, and graph generators. + +- **k-core** — `getCoreNumbers(graph)` (Batagelj–Zaveršnik, O(m)) and `getKCore(graph, k)`; degrees are undirected per the standard definition. +- **Katz centrality** — `getKatzCentrality(graph, { alpha, beta, getWeight, ... })`; throws a descriptive error when `alpha` exceeds the spectral bound and iteration diverges. +- **Eigenvector centrality** hardened — `(A+I)`-shifted power iteration (no more bipartite oscillation), `getWeight` support, descriptive non-convergence error. Differentially tested against graphology. +- **Bipartite** — `isBipartite(graph)` and `getMaximumBipartiteMatching(graph)` (Hopcroft–Karp, O(m√n)); the non-bipartite error names the edge that closes the odd cycle. +- **Min-cut** — `getMinCut(graph, { source, sink, getCapacity? })` → `{ value, cutEdges, partition }`, sharing the max-flow solver (`value` always equals `getMaxFlow(...)` by construction). +- **Seeded label propagation** — `getLabelPropagationCommunities` gains `seed`: asynchronous LPA with seeded shuffling/tie-breaking, deterministic per seed. +- **Generators** — `createCompleteGraph(n)`, `createGridGraph(rows, cols)`, `createRandomGraph(n, p, { seed })` (G(n,p), deterministic per seed) in the root export. diff --git a/.changeset/quick-lazy-paths.md b/.changeset/quick-lazy-paths.md new file mode 100644 index 0000000..682dba7 --- /dev/null +++ b/.changeset/quick-lazy-paths.md @@ -0,0 +1,5 @@ +--- +'@statelyai/graph': patch +--- + +Pathfinding internals: lazy path materialization and a typed-array heap. `genShortestPaths` now reconstructs a path only when it is actually yielded (abandoning the generator early skips the work), and the Dijkstra/A*/bidirectional hot loops use a Float64Array/Int32Array binary heap instead of object nodes. Same API, same results — measured −70% on first-path-then-stop, −41% on all-targets, −71% on single-target early exit (10k-node graph). diff --git a/src/algorithms.ts b/src/algorithms.ts index 76bdb98..cb065f9 100644 --- a/src/algorithms.ts +++ b/src/algorithms.ts @@ -44,12 +44,23 @@ export { getPageRank, getHITS, getEigenvectorCentrality, + getKatzCentrality, } from './algorithms/centrality'; export type { IterativeCentralityOptions, + EigenvectorCentralityOptions, + KatzCentralityOptions, HITSResult, } from './algorithms/centrality'; +export { getCoreNumbers, getKCore } from './algorithms/cores'; + +export { + isBipartite, + getMaximumBipartiteMatching, +} from './algorithms/bipartite'; +export type { BipartiteMatch } from './algorithms/bipartite'; + export { getLabelPropagationCommunities, genGirvanNewmanCommunities, @@ -74,8 +85,13 @@ export type { IsomorphismOptions } from './algorithms/isomorphism'; export { getLouvainCommunities } from './algorithms/louvain'; export type { LouvainOptions } from './algorithms/louvain'; -export { getMaxFlow } from './algorithms/flow'; -export type { MaxFlowOptions, MaxFlowResult } from './algorithms/flow'; +export { getMaxFlow, getMinCut } from './algorithms/flow'; +export type { + MaxFlowOptions, + MaxFlowResult, + MinCutOptions, + MinCutResult, +} from './algorithms/flow'; export { getDominatorTree } from './algorithms/dominators'; export type { DominatorTreeOptions } from './algorithms/dominators'; diff --git a/src/algorithms/bipartite.ts b/src/algorithms/bipartite.ts new file mode 100644 index 0000000..f39e266 --- /dev/null +++ b/src/algorithms/bipartite.ts @@ -0,0 +1,209 @@ +import type { Graph } from '../types'; +import { getCSR } from './csr'; + +export interface BipartiteMatch { + /** Source node id of the matched edge (as stored on the edge). */ + sourceId: string; + /** Target node id of the matched edge (as stored on the edge). */ + targetId: string; + /** Id of the edge realizing the match. */ + edgeId: string; +} + +interface TwoColoring { + /** 0/1 color per node position (CSR order). */ + colors: Int8Array; +} + +interface ColoringConflict { + /** Edge whose endpoints received the same color (or a self-loop). */ + conflictEdgeId: string; +} + +/** + * BFS 2-coloring over undirected adjacency. Edges are treated as undirected + * regardless of mode/direction. Returns either the coloring or the edge that + * proves the graph is not bipartite. + */ +function getTwoColoring(graph: Graph): TwoColoring | ColoringConflict { + const csr = getCSR(graph); + const n = csr.ids.length; + const m = graph.edges.length; + + // Undirected adjacency with the originating edge index per arc. + const degree = new Int32Array(n); + for (let e = 0; e < m; e++) { + const edge = graph.edges[e]; + if (edge.sourceId === edge.targetId) { + return { conflictEdgeId: edge.id }; + } + degree[csr.indexOf.get(edge.sourceId)!]++; + degree[csr.indexOf.get(edge.targetId)!]++; + } + const offsets = new Int32Array(n + 1); + for (let i = 0; i < n; i++) offsets[i + 1] = offsets[i] + degree[i]; + const targets = new Int32Array(offsets[n]); + const arcEdge = new Int32Array(offsets[n]); + const cursor = Int32Array.from(offsets.subarray(0, n)); + for (let e = 0; e < m; e++) { + const edge = graph.edges[e]; + const s = csr.indexOf.get(edge.sourceId)!; + const t = csr.indexOf.get(edge.targetId)!; + targets[cursor[s]] = t; + arcEdge[cursor[s]++] = e; + targets[cursor[t]] = s; + arcEdge[cursor[t]++] = e; + } + + const colors = new Int8Array(n).fill(-1); + const queue = new Int32Array(n); + for (let root = 0; root < n; root++) { + if (colors[root] !== -1) continue; + colors[root] = 0; + queue[0] = root; + let head = 0; + let tail = 1; + while (head < tail) { + const u = queue[head++]; + for (let a = offsets[u]; a < offsets[u + 1]; a++) { + const v = targets[a]; + if (colors[v] === -1) { + colors[v] = (1 - colors[u]) as 0 | 1; + queue[tail++] = v; + } else if (colors[v] === colors[u]) { + return { conflictEdgeId: graph.edges[arcEdge[a]].id }; + } + } + } + } + + return { colors }; +} + +/** + * Returns whether the graph is bipartite (2-colorable). + * + * Edges are treated as undirected; self-loops make a graph non-bipartite. + * Runs a BFS 2-coloring per connected component — O(n + m). + */ +export function isBipartite(graph: Graph): boolean { + return 'colors' in getTwoColoring(graph); +} + +/** + * Returns a maximum-cardinality matching of a bipartite graph using + * Hopcroft–Karp — O(m·√n). + * + * The bipartition is derived by 2-coloring (edges treated as undirected). + * Each match reports the realizing edge with its stored `sourceId`/ + * `targetId` orientation; for parallel edges between a matched pair, the + * first edge used by the algorithm is reported. + * + * Throws if the graph is not bipartite, naming the offending edge. + */ +export function getMaximumBipartiteMatching(graph: Graph): BipartiteMatch[] { + const coloring = getTwoColoring(graph); + if (!('colors' in coloring)) { + throw new Error( + `getMaximumBipartiteMatching: graph is not bipartite — edge "${coloring.conflictEdgeId}" closes an odd cycle (or is a self-loop); a maximum bipartite matching requires a bipartite graph, check with isBipartite() first`, + ); + } + + const { colors } = coloring; + const csr = getCSR(graph); + const n = csr.ids.length; + const m = graph.edges.length; + + // Left→right adjacency (left = color 0), with edge index per arc. + const degree = new Int32Array(n); + for (let e = 0; e < m; e++) { + const edge = graph.edges[e]; + const s = csr.indexOf.get(edge.sourceId)!; + const t = csr.indexOf.get(edge.targetId)!; + degree[colors[s] === 0 ? s : t]++; + } + const offsets = new Int32Array(n + 1); + for (let i = 0; i < n; i++) offsets[i + 1] = offsets[i] + degree[i]; + const targets = new Int32Array(offsets[n]); + const arcEdge = new Int32Array(offsets[n]); + const cursor = Int32Array.from(offsets.subarray(0, n)); + for (let e = 0; e < m; e++) { + const edge = graph.edges[e]; + const s = csr.indexOf.get(edge.sourceId)!; + const t = csr.indexOf.get(edge.targetId)!; + const left = colors[s] === 0 ? s : t; + const right = colors[s] === 0 ? t : s; + targets[cursor[left]] = right; + arcEdge[cursor[left]++] = e; + } + + const INF = 0x7fffffff; + const matchLeft = new Int32Array(n).fill(-1); // left pos → right pos + const matchRight = new Int32Array(n).fill(-1); // right pos → left pos + const matchEdge = new Int32Array(n).fill(-1); // left pos → edge index + const dist = new Int32Array(n); + const queue = new Int32Array(n); + + function bfs(): boolean { + let head = 0; + let tail = 0; + for (let u = 0; u < n; u++) { + if (colors[u] !== 0) continue; + if (matchLeft[u] === -1) { + dist[u] = 0; + queue[tail++] = u; + } else { + dist[u] = INF; + } + } + let foundAugmenting = false; + while (head < tail) { + const u = queue[head++]; + for (let a = offsets[u]; a < offsets[u + 1]; a++) { + const w = matchRight[targets[a]]; + if (w === -1) { + foundAugmenting = true; + } else if (dist[w] === INF) { + dist[w] = dist[u] + 1; + queue[tail++] = w; + } + } + } + return foundAugmenting; + } + + function dfs(u: number): boolean { + for (let a = offsets[u]; a < offsets[u + 1]; a++) { + const v = targets[a]; + const w = matchRight[v]; + if (w === -1 || (dist[w] === dist[u] + 1 && dfs(w))) { + matchLeft[u] = v; + matchRight[v] = u; + matchEdge[u] = arcEdge[a]; + return true; + } + } + dist[u] = INF; + return false; + } + + while (bfs()) { + for (let u = 0; u < n; u++) { + if (colors[u] === 0 && matchLeft[u] === -1) { + dfs(u); + } + } + } + + const matches: BipartiteMatch[] = []; + for (let u = 0; u < n; u++) { + if (matchEdge[u] === -1) continue; + const edge = graph.edges[matchEdge[u]]; + matches.push({ + sourceId: edge.sourceId, + targetId: edge.targetId, + edgeId: edge.id, + }); + } + return matches; +} diff --git a/src/algorithms/centrality.ts b/src/algorithms/centrality.ts index a39557f..d998b3d 100644 --- a/src/algorithms/centrality.ts +++ b/src/algorithms/centrality.ts @@ -1,4 +1,4 @@ -import type { Graph } from '../types'; +import type { Graph, GraphEdge } from '../types'; import { getDegree, getInDegree, getOutDegree } from '../queries'; import { getCSR } from './csr'; @@ -8,6 +8,20 @@ export interface IterativeCentralityOptions { tolerance?: number; } +export interface EigenvectorCentralityOptions + extends IterativeCentralityOptions { + /** Edge weight accessor. Defaults to unweighted (every edge counts 1). */ + getWeight?: (edge: GraphEdge) => number; +} + +export interface KatzCentralityOptions + extends IterativeCentralityOptions { + /** Constant added to every node each iteration. Defaults to `1`. */ + beta?: number; + /** Edge weight accessor. Defaults to unweighted (every edge counts 1). */ + getWeight?: (edge: GraphEdge) => number; +} + export interface HITSResult { hubs: Record; authorities: Record; @@ -360,12 +374,18 @@ export function getHITS( /** * Returns eigenvector centrality scores for all nodes. * - * Uses power iteration over incoming neighbors for directed graphs and - * undirected adjacency for undirected graphs. + * Power iteration with the `A + I` shift (same scheme as graphology and + * networkx, so bipartite structures converge instead of oscillating). + * Scores flow along edge direction: a node's score is fed by its incoming + * neighbors; undirected edges feed both endpoints. The result vector is + * Euclidean (L2) normalized. + * + * Throws when the iteration has not converged (L1 error < `n × tolerance`) + * within `maxIterations`. */ -export function getEigenvectorCentrality( - graph: Graph, - options?: IterativeCentralityOptions, +export function getEigenvectorCentrality( + graph: Graph, + options?: EigenvectorCentralityOptions, ): Record { const nodeIds = getNodeIds(graph); if (nodeIds.length === 0) { @@ -374,28 +394,107 @@ export function getEigenvectorCentrality( const maxIterations = options?.maxIterations ?? 100; const tolerance = options?.tolerance ?? 1e-6; + const getWeight = options?.getWeight; const csr = getCSR(graph); const n = csr.ids.length; - let current = new Float64Array(n).fill(1); - normalizeTypedVector(current); + let current = new Float64Array(n).fill(1 / n); + let converged = false; for (let iteration = 0; iteration < maxIterations; iteration++) { - const next = new Float64Array(n); + // Start from `current` (the implicit +I) so bipartite graphs converge. + const next = Float64Array.from(current); for (let w = 0; w < n; w++) { for (let a = csr.inOffsets[w]; a < csr.inOffsets[w + 1]; a++) { - next[w] += current[csr.inOrigins[a]]; + const weight = getWeight + ? getWeight(graph.edges[csr.inEdgeIndex[a]] as GraphEdge) + : 1; + next[w] += current[csr.inOrigins[a]] * weight; } } normalizeTypedVector(next); - let diff = 0; + let error = 0; for (let i = 0; i < n; i++) { - diff = Math.max(diff, Math.abs(current[i] - next[i])); + error += Math.abs(next[i] - current[i]); } current = next; - if (diff <= tolerance) break; + if (error < n * tolerance) { + converged = true; + break; + } + } + + if (!converged) { + throw new Error( + `getEigenvectorCentrality: power iteration failed to converge within ${maxIterations} iterations (tolerance ${tolerance}) — increase options.maxIterations or loosen options.tolerance`, + ); + } + + const scores = createEmptyScoreMap(graph); + for (let i = 0; i < n; i++) scores[csr.ids[i]] = current[i]; + return scores; +} + +/** + * Returns Katz centrality scores for all nodes. + * + * Iterates `x' = alpha · Aᵀx + beta` to its fixed point (networkx-style), + * then Euclidean (L2) normalizes the result. Scores flow along edge + * direction: a node's score is fed by its incoming neighbors; undirected + * edges feed both endpoints. + * + * Converges only when `alpha` is below the reciprocal of the largest + * eigenvalue of the adjacency matrix; throws when the iteration has not + * converged (L1 error < `n × tolerance`) within `maxIterations`. + */ +export function getKatzCentrality( + graph: Graph, + options?: KatzCentralityOptions, +): Record { + const nodeIds = getNodeIds(graph); + if (nodeIds.length === 0) { + return {}; } + const alpha = options?.alpha ?? 0.1; + const beta = options?.beta ?? 1; + const maxIterations = options?.maxIterations ?? 100; + const tolerance = options?.tolerance ?? 1e-6; + const getWeight = options?.getWeight; + const csr = getCSR(graph); + const n = csr.ids.length; + let current = new Float64Array(n); + let converged = false; + + for (let iteration = 0; iteration < maxIterations; iteration++) { + const next = new Float64Array(n).fill(beta); + for (let w = 0; w < n; w++) { + for (let a = csr.inOffsets[w]; a < csr.inOffsets[w + 1]; a++) { + const weight = getWeight + ? getWeight(graph.edges[csr.inEdgeIndex[a]] as GraphEdge) + : 1; + next[w] += alpha * current[csr.inOrigins[a]] * weight; + } + } + + let error = 0; + for (let i = 0; i < n; i++) { + error += Math.abs(next[i] - current[i]); + } + current = next; + if (error < n * tolerance) { + converged = true; + break; + } + } + + if (!converged) { + throw new Error( + `getKatzCentrality: iteration failed to converge within ${maxIterations} iterations — alpha ${alpha} may be >= 1/λ_max of the adjacency matrix; decrease options.alpha or increase options.maxIterations`, + ); + } + + normalizeTypedVector(current); const scores = createEmptyScoreMap(graph); for (let i = 0; i < n; i++) scores[csr.ids[i]] = current[i]; return scores; diff --git a/src/algorithms/community.ts b/src/algorithms/community.ts index 3f4dac5..fc18ce8 100644 --- a/src/algorithms/community.ts +++ b/src/algorithms/community.ts @@ -1,5 +1,6 @@ import type { Graph, GraphEdge, GraphNode } from '../types'; import { getIndex } from '../indexing'; +import { mulberry32 } from './shared'; export interface GirvanNewmanOptions { level?: number; @@ -8,6 +9,12 @@ export interface GirvanNewmanOptions { export interface LabelPropagationOptions { maxIterations?: number; + /** + * When provided, runs *asynchronous* label propagation with a shuffled + * node order per round and random tie-breaking, seeded with mulberry32 — + * deterministic per seed. Without a seed, ties break lexicographically. + */ + seed?: number; } type Community = GraphNode[]; @@ -197,11 +204,66 @@ function toCommunityIds( return communities.map((community) => new Set(community.map((node) => node.id))); } +/** + * Asynchronous LPA: labels update in place as the (seeded-shuffled) round + * proceeds; ties among maximal neighbor labels break uniformly at random, + * keeping the current label when it is already maximal so rounds terminate. + * Deterministic per seed. + */ +function getSeededLabelPropagation( + graph: Graph, + seed: number, + maxIterations: number, +): Community[] { + const rng = mulberry32(seed); + const labels = Object.fromEntries( + graph.nodes.map((node) => [node.id, node.id]), + ) as Record; + const order = graph.nodes.map((node) => node.id); + + for (let iteration = 0; iteration < maxIterations; iteration++) { + // Fisher-Yates shuffle of the visit order. + for (let i = order.length - 1; i > 0; i--) { + const j = Math.floor(rng() * (i + 1)); + [order[i], order[j]] = [order[j], order[i]]; + } + + let changed = false; + for (const nodeId of order) { + const counts = new Map(); + for (const neighbor of getUndirectedNeighbors(graph, nodeId)) { + const label = labels[neighbor.nodeId]; + counts.set(label, (counts.get(label) ?? 0) + 1); + } + if (counts.size === 0) continue; + + let maxCount = 0; + for (const count of counts.values()) { + if (count > maxCount) maxCount = count; + } + const best: string[] = []; + for (const [label, count] of counts) { + if (count === maxCount) best.push(label); + } + if (best.includes(labels[nodeId])) continue; + + labels[nodeId] = best[Math.floor(rng() * best.length)]; + changed = true; + } + + if (!changed) break; + } + + return normalizeCommunities(graph, labels); +} + /** * Returns label-propagation communities for the graph. * * The implementation is deterministic: ties are broken by lexicographic label - * order so test results remain stable. + * order so test results remain stable. Pass `options.seed` for the classic + * asynchronous variant (shuffled node order per round, random tie-breaking) + * — still deterministic per seed. */ export function getLabelPropagationCommunities( graph: Graph, @@ -212,6 +274,9 @@ export function getLabelPropagationCommunities( } const maxIterations = options?.maxIterations ?? 50; + if (options?.seed !== undefined) { + return getSeededLabelPropagation(graph, options.seed, maxIterations); + } let labels = Object.fromEntries( graph.nodes.map((node) => [node.id, node.id]), ) as Record; diff --git a/src/algorithms/cores.ts b/src/algorithms/cores.ts new file mode 100644 index 0000000..4fe66f8 --- /dev/null +++ b/src/algorithms/cores.ts @@ -0,0 +1,131 @@ +import type { Graph } from '../types'; +import { getCSR } from './csr'; + +/** + * Undirected adjacency over node positions: every edge (regardless of mode + * or direction) contributes both arcs, matching the standard k-core + * definition. Self-loops are ignored. Positions come from the CSR snapshot + * so `ids` order matches `graph.nodes`. + */ +function buildUndirectedAdjacency(graph: Graph): { + ids: string[]; + offsets: Int32Array; + targets: Int32Array; +} { + const csr = getCSR(graph); + const n = csr.ids.length; + const m = graph.edges.length; + const sourcePos = new Int32Array(m); + const targetPos = new Int32Array(m); + const degree = new Int32Array(n); + let arcCount = 0; + + for (let e = 0; e < m; e++) { + const edge = graph.edges[e]; + const s = csr.indexOf.get(edge.sourceId)!; + const t = csr.indexOf.get(edge.targetId)!; + if (s === t) { + sourcePos[e] = -1; // self-loop: no core contribution + continue; + } + sourcePos[e] = s; + targetPos[e] = t; + degree[s]++; + degree[t]++; + arcCount += 2; + } + + const offsets = new Int32Array(n + 1); + for (let i = 0; i < n; i++) offsets[i + 1] = offsets[i] + degree[i]; + const targets = new Int32Array(arcCount); + const cursor = Int32Array.from(offsets.subarray(0, n)); + for (let e = 0; e < m; e++) { + if (sourcePos[e] === -1) continue; + targets[cursor[sourcePos[e]]++] = targetPos[e]; + targets[cursor[targetPos[e]]++] = sourcePos[e]; + } + + return { ids: csr.ids, offsets, targets }; +} + +/** + * Returns the core number of every node (largest `k` such that the node + * belongs to the k-core). + * + * Uses Batagelj–Zaveršnik bucket peeling — O(m). Edges are treated as + * undirected (the standard k-core definition); self-loops are ignored. + * + * @example + * ```ts + * const cores = getCoreNumbers(graph); + * console.log(cores.a); // 3 + * ``` + */ +export function getCoreNumbers(graph: Graph): Record { + const { ids, offsets, targets } = buildUndirectedAdjacency(graph); + const n = ids.length; + const core = new Int32Array(n); + let maxDegree = 0; + for (let i = 0; i < n; i++) { + core[i] = offsets[i + 1] - offsets[i]; + if (core[i] > maxDegree) maxDegree = core[i]; + } + + // Bucket sort node positions by degree. + const bin = new Int32Array(maxDegree + 1); + for (let i = 0; i < n; i++) bin[core[i]]++; + let start = 0; + for (let d = 0; d <= maxDegree; d++) { + const count = bin[d]; + bin[d] = start; + start += count; + } + const vert = new Int32Array(n); + const pos = new Int32Array(n); + for (let i = 0; i < n; i++) { + pos[i] = bin[core[i]]; + vert[pos[i]] = i; + bin[core[i]]++; + } + for (let d = maxDegree; d > 0; d--) bin[d] = bin[d - 1]; + bin[0] = 0; + + // Peel in non-decreasing degree order, demoting higher-degree neighbors. + for (let k = 0; k < n; k++) { + const v = vert[k]; + for (let a = offsets[v]; a < offsets[v + 1]; a++) { + const u = targets[a]; + if (core[u] > core[v]) { + const du = core[u]; + const pu = pos[u]; + const pw = bin[du]; + const w = vert[pw]; + if (u !== w) { + vert[pu] = w; + pos[w] = pu; + vert[pw] = u; + pos[u] = pw; + } + bin[du]++; + core[u]--; + } + } + } + + const result: Record = {}; + for (let i = 0; i < n; i++) result[ids[i]] = core[i]; + return result; +} + +/** + * Returns the ids of all nodes in the k-core: the maximal subgraph in which + * every node has at least `k` neighbors (edges treated as undirected). + * + * Node order follows `graph.nodes`. `k <= 0` returns every node id. + */ +export function getKCore(graph: Graph, k: number): string[] { + const cores = getCoreNumbers(graph); + return graph.nodes + .filter((node) => cores[node.id] >= k) + .map((node) => node.id); +} diff --git a/src/algorithms/flow.ts b/src/algorithms/flow.ts index 3d87e78..c2741a8 100644 --- a/src/algorithms/flow.ts +++ b/src/algorithms/flow.ts @@ -20,6 +20,24 @@ export interface MaxFlowResult { cutEdges: GraphEdge[]; } +export interface MinCutOptions { + /** Source node id. */ + source: string; + /** Sink node id. */ + sink: string; + /** Edge capacity accessor. Defaults to `edge.weight ?? 1`. */ + getCapacity?: (edge: GraphEdge) => number; +} + +export interface MinCutResult { + /** Total capacity of the cut (equals the max-flow value). */ + value: number; + /** Ids of the edges crossing the cut. */ + cutEdges: string[]; + /** Node ids on each side of the cut, in `graph.nodes` order. */ + partition: { source: string[]; sink: string[] }; +} + interface Arc { to: string; capacity: number; @@ -30,46 +48,38 @@ interface Arc { sign?: 1 | -1; } +interface MaxFlowSolution extends MaxFlowResult { + /** Node ids reachable from the source in the final residual graph. */ + sourceSide: Set; +} + /** - * Returns the maximum flow from `from` to `to` using the Edmonds-Karp - * algorithm (BFS augmenting paths). - * - * Directed edges carry capacity from source to target only. Edges whose - * effective mode is not `'directed'` (undirected/bidirectional) are modeled - * as two independent opposite arcs, each with the edge's full capacity. - * - * The returned `flows` record maps every edge id to its net flow (positive - * in the source→target direction). `cutEdges` is a minimum s-t cut: the - * edges crossing from the source side to the sink side of the final - * residual graph; the sum of their capacities equals `value`. - * - * @example - * ```ts - * const { value, cutEdges } = getMaxFlow(graph, { from: 's', to: 't' }); - * ``` + * Shared Edmonds-Karp solver behind {@link getMaxFlow} and {@link getMinCut}. + * `caller`/`fromOption`/`toOption` only shape the error messages. */ -export function getMaxFlow( +function solveMaxFlow( graph: Graph, - options: MaxFlowOptions, -): MaxFlowResult { - const { from, to } = options; - const getCapacity = - options.getCapacity ?? ((edge: GraphEdge) => edge.weight ?? 1); - + caller: string, + fromOption: string, + toOption: string, + from: string, + to: string, + getCapacity: (edge: GraphEdge) => number, +): MaxFlowSolution { const idx = getIndex(graph); if (!idx.nodeById.has(from)) { throw new Error( - `getMaxFlow: source node "${from}" not found in graph — pass an existing node id as options.from`, + `${caller}: source node "${from}" not found in graph — pass an existing node id as ${fromOption}`, ); } if (!idx.nodeById.has(to)) { throw new Error( - `getMaxFlow: sink node "${to}" not found in graph — pass an existing node id as options.to`, + `${caller}: sink node "${to}" not found in graph — pass an existing node id as ${toOption}`, ); } if (from === to) { throw new Error( - `getMaxFlow: source and sink are both "${from}" — they must be different nodes`, + `${caller}: source and sink are both "${from}" — they must be different nodes`, ); } @@ -95,7 +105,7 @@ export function getMaxFlow( const capacity = getCapacity(edge as GraphEdge); if (capacity < 0) { throw new Error( - `getMaxFlow: edge "${edge.id}" has negative capacity ${capacity} — capacities must be >= 0; fix edge.weight or provide a non-negative getCapacity`, + `${caller}: edge "${edge.id}" has negative capacity ${capacity} — capacities must be >= 0; fix edge.weight or provide a non-negative getCapacity`, ); } if (edge.sourceId === edge.targetId) continue; // self-loops carry no s-t flow @@ -186,5 +196,88 @@ export function getMaxFlow( cutEdgeIds.has(edge.id), ) as GraphEdge[]; + return { value, flows, cutEdges, sourceSide }; +} + +/** + * Returns the maximum flow from `from` to `to` using the Edmonds-Karp + * algorithm (BFS augmenting paths). + * + * Directed edges carry capacity from source to target only. Edges whose + * effective mode is not `'directed'` (undirected/bidirectional) are modeled + * as two independent opposite arcs, each with the edge's full capacity. + * + * The returned `flows` record maps every edge id to its net flow (positive + * in the source→target direction). `cutEdges` is a minimum s-t cut: the + * edges crossing from the source side to the sink side of the final + * residual graph; the sum of their capacities equals `value`. + * + * @example + * ```ts + * const { value, cutEdges } = getMaxFlow(graph, { from: 's', to: 't' }); + * ``` + */ +export function getMaxFlow( + graph: Graph, + options: MaxFlowOptions, +): MaxFlowResult { + const getCapacity = + options.getCapacity ?? ((edge: GraphEdge) => edge.weight ?? 1); + const { value, flows, cutEdges } = solveMaxFlow( + graph, + 'getMaxFlow', + 'options.from', + 'options.to', + options.from, + options.to, + getCapacity, + ); return { value, flows, cutEdges }; } + +/** + * Returns a minimum s-t cut between `source` and `sink` via the max-flow + * min-cut theorem: runs the same Edmonds-Karp solver as {@link getMaxFlow}, + * then splits the nodes by residual reachability from the source. + * + * `partition.source` holds every node reachable from `source` in the final + * residual graph; `partition.sink` holds the rest (both in `graph.nodes` + * order). `cutEdges` are the ids of the edges crossing the cut, and their + * total capacity equals `value` (the max-flow value). + * + * @example + * ```ts + * const { value, cutEdges, partition } = getMinCut(graph, { + * source: 's', + * sink: 't', + * }); + * ``` + */ +export function getMinCut( + graph: Graph, + options: MinCutOptions, +): MinCutResult { + const getCapacity = + options.getCapacity ?? ((edge: GraphEdge) => edge.weight ?? 1); + const { value, cutEdges, sourceSide } = solveMaxFlow( + graph, + 'getMinCut', + 'options.source', + 'options.sink', + options.source, + options.sink, + getCapacity, + ); + + const sourcePartition: string[] = []; + const sinkPartition: string[] = []; + for (const node of graph.nodes) { + (sourceSide.has(node.id) ? sourcePartition : sinkPartition).push(node.id); + } + + return { + value, + cutEdges: cutEdges.map((edge) => edge.id), + partition: { source: sourcePartition, sink: sinkPartition }, + }; +} diff --git a/src/algorithms/shared.ts b/src/algorithms/shared.ts index 76f8a40..26406c0 100644 --- a/src/algorithms/shared.ts +++ b/src/algorithms/shared.ts @@ -78,6 +78,20 @@ export class MinPriorityQueue { } } +/** + * Seeded PRNG (mulberry32). Same generator as src/walks.ts — kept here so + * algorithm modules and generators can share it without importing walks. + */ +export function mulberry32(seed: number): () => number { + let s = seed | 0; + return () => { + s = (s + 0x6d2b79f5) | 0; + let t = Math.imul(s ^ (s >>> 15), 1 | s); + t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; +} + /** * Classify a graph by the *effective* mode of its edges (per-edge `mode` * overrides included): all-directed, all-non-directed, or genuinely mixed. diff --git a/src/generators.ts b/src/generators.ts new file mode 100644 index 0000000..924438e --- /dev/null +++ b/src/generators.ts @@ -0,0 +1,128 @@ +import { createGraph } from './graph'; +import type { EdgeConfig, Graph, NodeConfig } from './types'; +import { mulberry32 } from './algorithms/shared'; + +function assertNonNegativeInteger( + caller: string, + name: string, + value: number, +): void { + if (!Number.isInteger(value) || value < 0) { + throw new Error( + `${caller}: ${name} ${value} is invalid — pass a non-negative integer`, + ); + } +} + +/** + * Create the complete graph K_n: every pair of distinct nodes connected by + * one undirected edge. Nodes are `n0..n{n-1}` (`options.idPrefix` overrides + * the `n` prefix); edges are `e0..`. + */ +export function createCompleteGraph( + n: number, + options?: { idPrefix?: string }, +): Graph { + assertNonNegativeInteger('createCompleteGraph', 'node count', n); + const prefix = options?.idPrefix ?? 'n'; + + const nodes: NodeConfig[] = []; + for (let i = 0; i < n; i++) nodes.push({ id: `${prefix}${i}` }); + + const edges: EdgeConfig[] = []; + let edgeId = 0; + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + edges.push({ + id: `e${edgeId++}`, + sourceId: `${prefix}${i}`, + targetId: `${prefix}${j}`, + }); + } + } + + return createGraph({ mode: 'undirected', nodes, edges }); +} + +/** + * Create a `rows × cols` grid graph: node `(r, c)` is connected to its right + * and down neighbors by undirected edges. Nodes are `n{r}_{c}` + * (`options.idPrefix` overrides the `n` prefix); edges are `e0..`. + */ +export function createGridGraph( + rows: number, + cols: number, + options?: { idPrefix?: string }, +): Graph { + assertNonNegativeInteger('createGridGraph', 'row count', rows); + assertNonNegativeInteger('createGridGraph', 'column count', cols); + const prefix = options?.idPrefix ?? 'n'; + const nodeId = (r: number, c: number): string => `${prefix}${r}_${c}`; + + const nodes: NodeConfig[] = []; + const edges: EdgeConfig[] = []; + let edgeId = 0; + for (let r = 0; r < rows; r++) { + for (let c = 0; c < cols; c++) { + nodes.push({ id: nodeId(r, c) }); + if (c + 1 < cols) { + edges.push({ + id: `e${edgeId++}`, + sourceId: nodeId(r, c), + targetId: nodeId(r, c + 1), + }); + } + if (r + 1 < rows) { + edges.push({ + id: `e${edgeId++}`, + sourceId: nodeId(r, c), + targetId: nodeId(r + 1, c), + }); + } + } + } + + return createGraph({ mode: 'undirected', nodes, edges }); +} + +/** + * Create an Erdős–Rényi G(n, p) random graph: each of the n·(n-1)/2 node + * pairs gets an undirected edge with probability `probability`. With + * `options.seed` the result is deterministic per seed (mulberry32); + * otherwise `Math.random` is used. Nodes are `n0..n{n-1}` + * (`options.idPrefix` overrides the `n` prefix); edges are `e0..`. + */ +export function createRandomGraph( + n: number, + probability: number, + options?: { seed?: number; idPrefix?: string }, +): Graph { + assertNonNegativeInteger('createRandomGraph', 'node count', n); + if (!(probability >= 0 && probability <= 1)) { + throw new Error( + `createRandomGraph: probability ${probability} is invalid — pass a number between 0 and 1`, + ); + } + const prefix = options?.idPrefix ?? 'n'; + const rng = + options?.seed !== undefined ? mulberry32(options.seed) : Math.random; + + const nodes: NodeConfig[] = []; + for (let i = 0; i < n; i++) nodes.push({ id: `${prefix}${i}` }); + + const edges: EdgeConfig[] = []; + let edgeId = 0; + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + if (rng() < probability) { + edges.push({ + id: `e${edgeId++}`, + sourceId: `${prefix}${i}`, + targetId: `${prefix}${j}`, + }); + } + } + } + + return createGraph({ mode: 'undirected', nodes, edges }); +} diff --git a/src/index.ts b/src/index.ts index d9defda..22b3066 100644 --- a/src/index.ts +++ b/src/index.ts @@ -47,6 +47,8 @@ export type { } from './types'; export type { IterativeCentralityOptions, + EigenvectorCentralityOptions, + KatzCentralityOptions, HITSResult, GirvanNewmanOptions, LabelPropagationOptions, @@ -54,6 +56,9 @@ export type { LouvainOptions, MaxFlowOptions, MaxFlowResult, + MinCutOptions, + MinCutResult, + BipartiteMatch, DominatorTreeOptions, } from './algorithms'; @@ -166,6 +171,11 @@ export { getPageRank, getHITS, getEigenvectorCentrality, + getKatzCentrality, + getCoreNumbers, + getKCore, + isBipartite, + getMaximumBipartiteMatching, getLabelPropagationCommunities, genGirvanNewmanCommunities, getGirvanNewmanCommunities, @@ -177,10 +187,18 @@ export { isIsomorphic, getLouvainCommunities, getMaxFlow, + getMinCut, getDominatorTree, getTransitiveReduction, } from './algorithms'; +// Generators +export { + createCompleteGraph, + createGridGraph, + createRandomGraph, +} from './generators'; + // Equivalence export { areEntitiesEqual, diff --git a/tests/bipartite.test.ts b/tests/bipartite.test.ts new file mode 100644 index 0000000..0206a69 --- /dev/null +++ b/tests/bipartite.test.ts @@ -0,0 +1,211 @@ +import { describe, expect, it } from 'vitest'; +import { createGraph } from '../src/graph'; +import { + isBipartite, + getMaximumBipartiteMatching, + getMaxFlow, +} from '../src/algorithms'; +import { createGridGraph } from '../src/generators'; +import type { Graph } from '../src/types'; +import type { BipartiteMatch } from '../src/algorithms'; + +function makeCycle(n: number): Graph { + return createGraph({ + mode: 'undirected', + nodes: Array.from({ length: n }, (_, i) => ({ id: `n${i}` })), + edges: Array.from({ length: n }, (_, i) => ({ + id: `e${i}`, + sourceId: `n${i}`, + targetId: `n${(i + 1) % n}`, + })), + }); +} + +/** A matching is valid when its edges exist as claimed and share no node. */ +function expectValidMatching(graph: Graph, matches: BipartiteMatch[]): void { + const used = new Set(); + for (const match of matches) { + const edge = graph.edges.find((e) => e.id === match.edgeId); + expect(edge).toBeDefined(); + expect(edge!.sourceId).toBe(match.sourceId); + expect(edge!.targetId).toBe(match.targetId); + expect(used.has(match.sourceId)).toBe(false); + expect(used.has(match.targetId)).toBe(false); + used.add(match.sourceId); + used.add(match.targetId); + } +} + +describe('isBipartite', () => { + it('accepts even cycles and rejects odd cycles', () => { + expect(isBipartite(makeCycle(4))).toBe(true); + expect(isBipartite(makeCycle(6))).toBe(true); + expect(isBipartite(makeCycle(3))).toBe(false); + expect(isBipartite(makeCycle(5))).toBe(false); + }); + + it('accepts trees and the empty graph', () => { + const tree = createGraph({ + mode: 'undirected', + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }], + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b' }, + { id: 'ac', sourceId: 'a', targetId: 'c' }, + ], + }); + + expect(isBipartite(tree)).toBe(true); + expect(isBipartite(createGraph())).toBe(true); + }); + + it('treats directed edges as undirected (directed odd cycle is not bipartite)', () => { + const graph = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }], + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b' }, + { id: 'bc', sourceId: 'b', targetId: 'c' }, + { id: 'ca', sourceId: 'c', targetId: 'a' }, + ], + }); + + expect(isBipartite(graph)).toBe(false); + }); + + it('rejects self-loops', () => { + const graph = createGraph({ + nodes: [{ id: 'a' }], + edges: [{ id: 'loop', sourceId: 'a', targetId: 'a' }], + }); + + expect(isBipartite(graph)).toBe(false); + }); + + it('rejects a graph whose only odd cycle sits in a later component', () => { + const graph = createGraph({ + mode: 'undirected', + nodes: ['a', 'b', 'x', 'y', 'z'].map((id) => ({ id })), + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b' }, + { id: 'xy', sourceId: 'x', targetId: 'y' }, + { id: 'yz', sourceId: 'y', targetId: 'z' }, + { id: 'zx', sourceId: 'z', targetId: 'x' }, + ], + }); + + expect(isBipartite(graph)).toBe(false); + }); + + it('considers grid graphs bipartite', () => { + expect(isBipartite(createGridGraph(3, 4))).toBe(true); + }); +}); + +describe('getMaximumBipartiteMatching', () => { + it('finds the known maximum on an instance where greedy gets stuck', () => { + // l1:{r1,r2}, l2:{r1}, l3:{r2,r3}. Greedy l1→r1 strands l2; the maximum + // matching has size 3 (l1-r2, l2-r1, l3-r3) — hand-verified. + const graph = createGraph({ + mode: 'undirected', + nodes: ['l1', 'l2', 'l3', 'r1', 'r2', 'r3'].map((id) => ({ id })), + edges: [ + { id: 'e1', sourceId: 'l1', targetId: 'r1' }, + { id: 'e2', sourceId: 'l1', targetId: 'r2' }, + { id: 'e3', sourceId: 'l2', targetId: 'r1' }, + { id: 'e4', sourceId: 'l3', targetId: 'r2' }, + { id: 'e5', sourceId: 'l3', targetId: 'r3' }, + ], + }); + + const matches = getMaximumBipartiteMatching(graph); + + expect(matches).toHaveLength(3); + expectValidMatching(graph, matches); + }); + + it('finds the known maximum on a graph without a perfect matching', () => { + // l1:{r1,r2}, l2:{r1}, l3:{r2}: only 2 right nodes are reachable by + // {l2, l3}, so the maximum matching has size 2 — hand-verified (König). + const graph = createGraph({ + mode: 'undirected', + nodes: ['l1', 'l2', 'l3', 'r1', 'r2'].map((id) => ({ id })), + edges: [ + { id: 'e1', sourceId: 'l1', targetId: 'r1' }, + { id: 'e2', sourceId: 'l1', targetId: 'r2' }, + { id: 'e3', sourceId: 'l2', targetId: 'r1' }, + { id: 'e4', sourceId: 'l3', targetId: 'r2' }, + ], + }); + + const matches = getMaximumBipartiteMatching(graph); + + expect(matches).toHaveLength(2); + expectValidMatching(graph, matches); + }); + + it('finds a perfect matching on an even cycle', () => { + const graph = makeCycle(6); + const matches = getMaximumBipartiteMatching(graph); + + expect(matches).toHaveLength(3); + expectValidMatching(graph, matches); + }); + + it('matches floor(n·m / 2) nodes on grid graphs', () => { + const grid3x3 = createGridGraph(3, 3); + const grid4x4 = createGridGraph(4, 4); + + const matches3x3 = getMaximumBipartiteMatching(grid3x3); + const matches4x4 = getMaximumBipartiteMatching(grid4x4); + + expect(matches3x3).toHaveLength(4); + expect(matches4x4).toHaveLength(8); + expectValidMatching(grid3x3, matches3x3); + expectValidMatching(grid4x4, matches4x4); + }); + + it('agrees with the unit-capacity max-flow formulation', () => { + // Cross-check on the 3x4 grid: matching size must equal max flow in + // the network s→left (cap 1), left→right (cap 1), right→t (cap 1). + const grid = createGridGraph(3, 4); + const matches = getMaximumBipartiteMatching(grid); + + // Bipartition by checkerboard parity of `n{r}_{c}` ids. + const isLeft = (id: string): boolean => { + const [r, c] = id.slice(1).split('_').map(Number); + return (r + c) % 2 === 0; + }; + const flowGraph = createGraph({ + nodes: [{ id: 's' }, { id: 't' }, ...grid.nodes.map((n) => ({ id: n.id }))], + edges: [ + ...grid.nodes.map((n) => ({ + id: `cap-${n.id}`, + sourceId: isLeft(n.id) ? 's' : n.id, + targetId: isLeft(n.id) ? n.id : 't', + weight: 1, + })), + ...grid.edges.map((e) => ({ + id: e.id, + sourceId: isLeft(e.sourceId) ? e.sourceId : e.targetId, + targetId: isLeft(e.sourceId) ? e.targetId : e.sourceId, + weight: 1, + })), + ], + }); + + const { value } = getMaxFlow(flowGraph, { from: 's', to: 't' }); + expect(matches).toHaveLength(value); + }); + + it('returns an empty matching for empty and edgeless graphs', () => { + expect(getMaximumBipartiteMatching(createGraph())).toEqual([]); + expect( + getMaximumBipartiteMatching(createGraph({ nodes: [{ id: 'a' }] })), + ).toEqual([]); + }); + + it('throws a descriptive error on non-bipartite graphs', () => { + expect(() => getMaximumBipartiteMatching(makeCycle(5))).toThrow( + /not bipartite/, + ); + }); +}); diff --git a/tests/centrality.test.ts b/tests/centrality.test.ts index f7d57dc..5e23ee4 100644 --- a/tests/centrality.test.ts +++ b/tests/centrality.test.ts @@ -9,6 +9,7 @@ import { getPageRank, getHITS, getEigenvectorCentrality, + getKatzCentrality, } from '../src/algorithms'; describe('centrality and link analysis', () => { @@ -143,6 +144,117 @@ describe('centrality and link analysis', () => { expect(scores.c).toBeCloseTo(scores.d, 6); }); + it('getEigenvectorCentrality matches the known star eigenvector (L2 normalized)', () => { + // Hand-verified: K1,3 has dominant eigenvalue √3 with eigenvector + // (√3, 1, 1, 1); normalized: center √3/√6 ≈ 0.7071, leaves 1/√6 ≈ 0.4082. + const graph = createGraph({ + mode: 'undirected', + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }, { id: 'd' }], + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b' }, + { id: 'ac', sourceId: 'a', targetId: 'c' }, + { id: 'ad', sourceId: 'a', targetId: 'd' }, + ], + }); + + const scores = getEigenvectorCentrality(graph); + + expect(scores.a).toBeCloseTo(Math.sqrt(3 / 6), 4); + expect(scores.b).toBeCloseTo(Math.sqrt(1 / 6), 4); + }); + + it('getEigenvectorCentrality supports a getWeight accessor', () => { + // Heavier edge pulls its leaf above the others. + const graph = createGraph({ + mode: 'undirected', + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }, { id: 'd' }], + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b', weight: 5 }, + { id: 'ac', sourceId: 'a', targetId: 'c', weight: 1 }, + { id: 'ad', sourceId: 'a', targetId: 'd', weight: 1 }, + ], + }); + + const scores = getEigenvectorCentrality(graph, { + getWeight: (edge) => edge.weight ?? 1, + }); + + expect(scores.b).toBeGreaterThan(scores.c); + expect(scores.c).toBeCloseTo(scores.d, 6); + }); + + it('getEigenvectorCentrality throws a descriptive error on non-convergence', () => { + const graph = createGraph({ + mode: 'undirected', + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }], + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b' }, + { id: 'bc', sourceId: 'b', targetId: 'c' }, + ], + }); + + expect(() => + getEigenvectorCentrality(graph, { maxIterations: 1, tolerance: 0 }), + ).toThrow(/failed to converge within 1 iterations.*maxIterations/); + }); + + it('getKatzCentrality matches the known fixed point of a directed path', () => { + // Hand-verified for a->b->c with alpha 0.1, beta 1: the fixed point of + // x = 0.1·Aᵀx + 1 is (1, 1.1, 1.11); L2 normalization preserves ratios. + const graph = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }], + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b' }, + { id: 'bc', sourceId: 'b', targetId: 'c' }, + ], + }); + + const scores = getKatzCentrality(graph); + + expect(scores.b / scores.a).toBeCloseTo(1.1, 5); + expect(scores.c / scores.a).toBeCloseTo(1.11, 5); + const norm = Math.sqrt( + scores.a ** 2 + scores.b ** 2 + scores.c ** 2, + ); + expect(norm).toBeCloseTo(1, 6); + }); + + it('getKatzCentrality respects alpha, beta, and getWeight', () => { + const graph = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }], + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b', weight: 2 }, + { id: 'ac', sourceId: 'a', targetId: 'c', weight: 1 }, + ], + }); + + // Fixed point with alpha 0.2, beta 3: a = 3, b = 3 + 0.2·2·3 = 4.2, + // c = 3 + 0.2·1·3 = 3.6 — hand-verified, ratios survive normalization. + const scores = getKatzCentrality(graph, { + alpha: 0.2, + beta: 3, + getWeight: (edge) => edge.weight ?? 1, + }); + + expect(scores.b / scores.a).toBeCloseTo(1.4, 6); + expect(scores.c / scores.a).toBeCloseTo(1.2, 6); + }); + + it('getKatzCentrality throws when alpha exceeds the spectral radius bound', () => { + // 2-cycle has λ_max = 1; alpha 1 diverges. + const graph = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }], + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b' }, + { id: 'ba', sourceId: 'b', targetId: 'a' }, + ], + }); + + expect(() => getKatzCentrality(graph, { alpha: 1 })).toThrow( + /failed to converge.*alpha 1/, + ); + }); + it('returns empty maps for an empty graph', () => { const graph = createGraph(); @@ -154,5 +266,6 @@ describe('centrality and link analysis', () => { expect(getPageRank(graph)).toEqual({}); expect(getHITS(graph)).toEqual({ hubs: {}, authorities: {} }); expect(getEigenvectorCentrality(graph)).toEqual({}); + expect(getKatzCentrality(graph)).toEqual({}); }); }); diff --git a/tests/community.test.ts b/tests/community.test.ts index 4354d51..33f47f6 100644 --- a/tests/community.test.ts +++ b/tests/community.test.ts @@ -113,6 +113,37 @@ describe('community detection', () => { ]); }); + it('getLabelPropagationCommunities with a seed is deterministic per seed', () => { + const graph = makeDisconnectedTriangles(); + + const first = getLabelPropagationCommunities(graph, { seed: 42 }); + const second = getLabelPropagationCommunities(graph, { seed: 42 }); + + expect(toIdGroups(first)).toEqual(toIdGroups(second)); + }); + + it('seeded label propagation separates disconnected cliques', () => { + const graph = makeDisconnectedTriangles(); + + for (const seed of [1, 2, 3, 99]) { + const communities = getLabelPropagationCommunities(graph, { seed }); + expect(toIdGroups(communities)).toEqual([ + ['a', 'b', 'c'], + ['d', 'e', 'f'], + ]); + } + }); + + it('seeded label propagation returns a partition covering every node once', () => { + const graph = makeTrianglesWithBridge(); + const communities = getLabelPropagationCommunities(graph, { seed: 7 }); + + const allIds = communities.flatMap((community) => + community.map((node) => node.id), + ); + expect([...allIds].sort()).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); + }); + it('returns empty community collections for an empty graph', () => { const graph = createGraph(); diff --git a/tests/cores.test.ts b/tests/cores.test.ts new file mode 100644 index 0000000..db07b23 --- /dev/null +++ b/tests/cores.test.ts @@ -0,0 +1,88 @@ +import { describe, expect, it } from 'vitest'; +import { createGraph } from '../src/graph'; +import { getCoreNumbers, getKCore } from '../src/algorithms'; + +// Hand-verified fixture: K4 {a,b,c,d} (every node has 3 neighbors inside it +// → core 3), e hangs off a and b (degree 2, but never part of a subgraph of +// min degree 3 → core 2), f hangs off e (degree 1 → core 1), g isolated +// (core 0). +function makeLayeredCoreGraph(mode: 'directed' | 'undirected') { + return createGraph({ + mode, + nodes: ['a', 'b', 'c', 'd', 'e', 'f', 'g'].map((id) => ({ id })), + edges: [ + { id: 'ab', sourceId: 'a', targetId: 'b' }, + { id: 'ac', sourceId: 'a', targetId: 'c' }, + { id: 'ad', sourceId: 'a', targetId: 'd' }, + { id: 'bc', sourceId: 'b', targetId: 'c' }, + { id: 'bd', sourceId: 'b', targetId: 'd' }, + { id: 'cd', sourceId: 'c', targetId: 'd' }, + { id: 'ea', sourceId: 'e', targetId: 'a' }, + { id: 'eb', sourceId: 'e', targetId: 'b' }, + { id: 'fe', sourceId: 'f', targetId: 'e' }, + ], + }); +} + +describe('getCoreNumbers', () => { + it('computes the known core numbers of the layered fixture', () => { + expect(getCoreNumbers(makeLayeredCoreGraph('undirected'))).toEqual({ + a: 3, + b: 3, + c: 3, + d: 3, + e: 2, + f: 1, + g: 0, + }); + }); + + it('treats directed edges as undirected (standard k-core definition)', () => { + expect(getCoreNumbers(makeLayeredCoreGraph('directed'))).toEqual( + getCoreNumbers(makeLayeredCoreGraph('undirected')), + ); + }); + + it('ignores self-loops', () => { + const graph = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }], + edges: [ + { id: 'loop', sourceId: 'a', targetId: 'a' }, + { id: 'ab', sourceId: 'a', targetId: 'b' }, + ], + }); + + expect(getCoreNumbers(graph)).toEqual({ a: 1, b: 1 }); + }); + + it('counts parallel edges toward degree', () => { + const graph = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }], + edges: [ + { id: 'p1', sourceId: 'a', targetId: 'b' }, + { id: 'p2', sourceId: 'a', targetId: 'b' }, + ], + }); + + expect(getCoreNumbers(graph)).toEqual({ a: 2, b: 2 }); + }); + + it('returns an empty record for an empty graph', () => { + expect(getCoreNumbers(createGraph())).toEqual({}); + }); +}); + +describe('getKCore', () => { + it('returns the nodes of each k-core of the layered fixture', () => { + const graph = makeLayeredCoreGraph('undirected'); + + expect(getKCore(graph, 3)).toEqual(['a', 'b', 'c', 'd']); + expect(getKCore(graph, 2)).toEqual(['a', 'b', 'c', 'd', 'e']); + expect(getKCore(graph, 1)).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); + expect(getKCore(graph, 0)).toEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g']); + }); + + it('returns an empty array when no node reaches k', () => { + expect(getKCore(makeLayeredCoreGraph('undirected'), 4)).toEqual([]); + }); +}); diff --git a/tests/differential/oracle.test.ts b/tests/differential/oracle.test.ts index 5912c92..f2190b3 100644 --- a/tests/differential/oracle.test.ts +++ b/tests/differential/oracle.test.ts @@ -4,6 +4,7 @@ import { connectedComponents } from 'graphology-components'; import { dijkstra } from 'graphology-shortest-path'; import pagerank from 'graphology-metrics/centrality/pagerank'; import betweennessCentrality from 'graphology-metrics/centrality/betweenness'; +import eigenvectorCentrality from 'graphology-metrics/centrality/eigenvector'; import { createGraph } from '../../src/graph'; import { @@ -11,6 +12,7 @@ import { getShortestPath, getBetweennessCentrality, getPageRank, + getEigenvectorCentrality, } from '../../src/algorithms'; import { getDegree, getInDegree, getOutDegree } from '../../src/queries'; import type { Graph } from '../../src/types'; @@ -430,3 +432,90 @@ describe('oracle: betweenness centrality', () => { } } }); + +// --------------------------------------------------------------------------- +// 6. Eigenvector centrality +// --------------------------------------------------------------------------- + +// Both implementations run the same (A + I)-shifted power iteration with L2 +// normalization and an L1 < N * tolerance convergence check, so per-node +// agreement within 1e-4 is meaningful. Connected undirected graphs only: +// that is the well-defined setting both libraries document. +const EIGENVECTOR_TOLERANCE = 1e-4; +const EIGENVECTOR_OPTIONS = { maxIterations: 1000, tolerance: 1e-9 }; + +describe('oracle: eigenvector centrality', () => { + it('hand-verified: undirected star K1,3 gives center sqrt(3/6), leaves sqrt(1/6)', () => { + const ours = createGraph({ + mode: 'undirected', + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }, { id: 'd' }], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b' }, + { id: 'e2', sourceId: 'a', targetId: 'c' }, + { id: 'e3', sourceId: 'a', targetId: 'd' }, + ], + }); + const theirs = toGraphology(ours, 'undirected'); + + const ourScores = getEigenvectorCentrality(ours, EIGENVECTOR_OPTIONS); + const theirScores = eigenvectorCentrality(theirs, { + ...EIGENVECTOR_OPTIONS, + getEdgeWeight: null, + }); + + expect(ourScores['a']).toBeCloseTo(Math.sqrt(3 / 6), 6); + expect(ourScores['b']).toBeCloseTo(Math.sqrt(1 / 6), 6); + expect(theirScores['a']).toBeCloseTo(Math.sqrt(3 / 6), 6); + expect(theirScores['b']).toBeCloseTo(Math.sqrt(1 / 6), 6); + }); + + for (const seed of SEEDS) { + it(`unweighted agrees with graphology within ${EIGENVECTOR_TOLERANCE} (undirected, seed ${seed})`, () => { + const ours = makeRandomGraph(seed, { + mode: 'undirected', + connected: true, + density: 1.6, + maxNodes: 80, + }); + const theirs = toGraphology(ours, 'undirected'); + + const ourScores = getEigenvectorCentrality(ours, EIGENVECTOR_OPTIONS); + const theirScores = eigenvectorCentrality(theirs, { + ...EIGENVECTOR_OPTIONS, + getEdgeWeight: null, + }); + + for (const node of ours.nodes) { + expect( + Math.abs(ourScores[node.id] - theirScores[node.id]), + `eigenvector(${node.id})`, + ).toBeLessThan(EIGENVECTOR_TOLERANCE); + } + }); + + it(`weighted agrees with graphology within ${EIGENVECTOR_TOLERANCE} (undirected, seed ${seed})`, () => { + const ours = makeRandomGraph(seed, { + mode: 'undirected', + connected: true, + weighted: true, + density: 1.6, + maxNodes: 80, + }); + const theirs = toGraphology(ours, 'undirected'); + + const ourScores = getEigenvectorCentrality(ours, { + ...EIGENVECTOR_OPTIONS, + getWeight: (edge) => edge.weight ?? 1, + }); + // graphology reads the 'weight' attribute by default. + const theirScores = eigenvectorCentrality(theirs, EIGENVECTOR_OPTIONS); + + for (const node of ours.nodes) { + expect( + Math.abs(ourScores[node.id] - theirScores[node.id]), + `eigenvector(${node.id})`, + ).toBeLessThan(EIGENVECTOR_TOLERANCE); + } + }); + } +}); diff --git a/tests/flow.test.ts b/tests/flow.test.ts index 50c9ffa..bcc676d 100644 --- a/tests/flow.test.ts +++ b/tests/flow.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; import { createGraph } from '../src/graph'; -import { getMaxFlow } from '../src/algorithms'; +import { getMaxFlow, getMinCut } from '../src/algorithms'; // Classic CLRS network (Introduction to Algorithms, Fig. 26.1). // Known answer: max flow s→t = 23; min cut = ({s,v1,v2,v4},{v3,t}) @@ -171,3 +171,88 @@ describe('getMaxFlow', () => { ); }); }); + +describe('getMinCut', () => { + it('returns the known min cut of the CLRS network', () => { + const graph = makeClrsNetwork(); + const { value, cutEdges, partition } = getMinCut(graph, { + source: 's', + sink: 't', + }); + + // Hand-verified (CLRS Fig. 26.1): cut ({s,v1,v2,v4},{v3,t}) of capacity + // 12 + 7 + 4 = 23. + expect(value).toBe(23); + expect([...cutEdges].sort()).toEqual(['v1v3', 'v4t', 'v4v3']); + expect(partition.source).toEqual(['s', 'v1', 'v2', 'v4']); + expect(partition.sink).toEqual(['v3', 't']); + }); + + it('matches the max-flow value and the cut capacity', () => { + const graph = makeClrsNetwork(); + const cut = getMinCut(graph, { source: 's', sink: 't' }); + const flow = getMaxFlow(graph, { from: 's', to: 't' }); + + expect(cut.value).toBe(flow.value); + const cutCapacity = cut.cutEdges.reduce( + (sum, edgeId) => + sum + (graph.edges.find((edge) => edge.id === edgeId)!.weight ?? 1), + 0, + ); + expect(cutCapacity).toBe(cut.value); + }); + + it('partitions every node exactly once', () => { + const graph = makeClrsNetwork(); + const { partition } = getMinCut(graph, { source: 's', sink: 't' }); + + expect( + [...partition.source, ...partition.sink].sort(), + ).toEqual(graph.nodes.map((node) => node.id).sort()); + }); + + it('returns an empty cut when source cannot reach sink', () => { + const graph = createGraph({ + nodes: [{ id: 's' }, { id: 't' }, { id: 'x' }], + edges: [{ id: 'xt', sourceId: 'x', targetId: 't', weight: 5 }], + }); + + const { value, cutEdges, partition } = getMinCut(graph, { + source: 's', + sink: 't', + }); + expect(value).toBe(0); + expect(cutEdges).toEqual([]); + expect(partition.source).toEqual(['s']); + expect(partition.sink).toEqual(['t', 'x']); + }); + + it('supports a custom getCapacity accessor', () => { + const graph = createGraph({ + nodes: [{ id: 's' }, { id: 't' }], + edges: [{ id: 'st', sourceId: 's', targetId: 't', data: { cap: 9 } }], + }); + + const { value, cutEdges } = getMinCut(graph, { + source: 's', + sink: 't', + getCapacity: (edge) => edge.data.cap, + }); + expect(value).toBe(9); + expect(cutEdges).toEqual(['st']); + }); + + it('throws with getMinCut-specific messages on invalid options', () => { + const graph = createGraph({ nodes: [{ id: 's' }, { id: 't' }] }); + + expect(() => getMinCut(graph, { source: 'nope', sink: 't' })).toThrow( + /getMinCut: source node "nope" not found in graph — pass an existing node id as options\.source/, + ); + expect(() => getMinCut(graph, { source: 's', sink: 'nope' })).toThrow( + /getMinCut: sink node "nope" not found .* options\.sink/, + ); + expect(() => getMinCut(graph, { source: 's', sink: 's' })).toThrow( + /must be different nodes/, + ); + }); +}); diff --git a/tests/generators.test.ts b/tests/generators.test.ts new file mode 100644 index 0000000..17f4109 --- /dev/null +++ b/tests/generators.test.ts @@ -0,0 +1,118 @@ +import { describe, expect, it } from 'vitest'; +import { + createCompleteGraph, + createGridGraph, + createRandomGraph, +} from '../src/generators'; +import { getDegree } from '../src/queries'; + +describe('createCompleteGraph', () => { + it('creates K4 with all n·(n-1)/2 pairs', () => { + const graph = createCompleteGraph(4); + + expect(graph.mode).toBe('undirected'); + expect(graph.nodes.map((n) => n.id)).toEqual(['n0', 'n1', 'n2', 'n3']); + expect(graph.edges).toHaveLength(6); + const pairs = new Set( + graph.edges.map((e) => `${e.sourceId}|${e.targetId}`), + ); + expect(pairs.size).toBe(6); + for (const node of graph.nodes) { + expect(getDegree(graph, node.id)).toBe(3); + } + }); + + it('handles trivial sizes', () => { + expect(createCompleteGraph(0).nodes).toEqual([]); + expect(createCompleteGraph(1).nodes).toHaveLength(1); + expect(createCompleteGraph(1).edges).toEqual([]); + }); + + it('supports id prefixing', () => { + const graph = createCompleteGraph(2, { idPrefix: 'v' }); + expect(graph.nodes.map((n) => n.id)).toEqual(['v0', 'v1']); + }); + + it('throws on an invalid node count', () => { + expect(() => createCompleteGraph(-1)).toThrow(/non-negative integer/); + expect(() => createCompleteGraph(1.5)).toThrow(/non-negative integer/); + }); +}); + +describe('createGridGraph', () => { + it('creates a 2x3 grid with rows·(cols-1) + cols·(rows-1) edges', () => { + const graph = createGridGraph(2, 3); + + expect(graph.mode).toBe('undirected'); + expect(graph.nodes).toHaveLength(6); + expect(graph.edges).toHaveLength(7); // 2·2 horizontal + 3·1 vertical + expect(graph.nodes.map((n) => n.id)).toContain('n1_2'); + // Corner has degree 2, edge-center degree 3. + expect(getDegree(graph, 'n0_0')).toBe(2); + expect(getDegree(graph, 'n0_1')).toBe(3); + }); + + it('handles degenerate dimensions', () => { + expect(createGridGraph(1, 1).nodes).toHaveLength(1); + expect(createGridGraph(1, 1).edges).toEqual([]); + expect(createGridGraph(0, 5).nodes).toEqual([]); + // A 1×n grid is a path. + expect(createGridGraph(1, 4).edges).toHaveLength(3); + }); + + it('supports id prefixing', () => { + const graph = createGridGraph(1, 2, { idPrefix: 'cell' }); + expect(graph.nodes.map((n) => n.id)).toEqual(['cell0_0', 'cell0_1']); + }); + + it('throws on invalid dimensions', () => { + expect(() => createGridGraph(-1, 2)).toThrow(/non-negative integer/); + expect(() => createGridGraph(2, 2.5)).toThrow(/non-negative integer/); + }); +}); + +describe('createRandomGraph', () => { + it('is deterministic per seed', () => { + const a = createRandomGraph(30, 0.3, { seed: 42 }); + const b = createRandomGraph(30, 0.3, { seed: 42 }); + const c = createRandomGraph(30, 0.3, { seed: 43 }); + + expect(a).toEqual(b); + expect(a.edges.map((e) => `${e.sourceId}|${e.targetId}`)).not.toEqual( + c.edges.map((e) => `${e.sourceId}|${e.targetId}`), + ); + }); + + it('produces no edges at p=0 and the complete graph at p=1', () => { + expect(createRandomGraph(10, 0, { seed: 1 }).edges).toEqual([]); + expect(createRandomGraph(10, 1, { seed: 1 }).edges).toHaveLength(45); + }); + + it('produces only valid simple undirected edges', () => { + const graph = createRandomGraph(25, 0.4, { seed: 7 }); + const nodeIds = new Set(graph.nodes.map((n) => n.id)); + const pairs = new Set(); + + expect(graph.mode).toBe('undirected'); + for (const edge of graph.edges) { + expect(nodeIds.has(edge.sourceId)).toBe(true); + expect(nodeIds.has(edge.targetId)).toBe(true); + expect(edge.sourceId).not.toBe(edge.targetId); + const key = `${edge.sourceId}|${edge.targetId}`; + expect(pairs.has(key)).toBe(false); + pairs.add(key); + } + }); + + it('supports id prefixing', () => { + const graph = createRandomGraph(2, 1, { seed: 1, idPrefix: 'x' }); + expect(graph.nodes.map((n) => n.id)).toEqual(['x0', 'x1']); + expect(graph.edges[0].sourceId).toBe('x0'); + }); + + it('throws on invalid arguments', () => { + expect(() => createRandomGraph(-2, 0.5)).toThrow(/non-negative integer/); + expect(() => createRandomGraph(5, 1.2)).toThrow(/between 0 and 1/); + expect(() => createRandomGraph(5, Number.NaN)).toThrow(/between 0 and 1/); + }); +}); From f33ed2a89e0b0ed97b9b4850679b1223ad8eabc5 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:27:48 -0400 Subject: [PATCH 09/15] fix(layout): elk constraint spread typecheck (closure-mutated flag narrowed to false) --- src/layout/elk.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/layout/elk.ts b/src/layout/elk.ts index bee2178..f794c04 100644 --- a/src/layout/elk.ts +++ b/src/layout/elk.ts @@ -74,7 +74,9 @@ export async function getElkLayout( // constraints.layer → ELK partitions (same value = same layer, ordered // along the flow axis) const layerOf = options?.constraints?.layer; - let hasPartitions = false; + // `boolean` annotation: assigned inside the visitor closure, which TS's + // narrowing doesn't see — without it the spread below narrows to `false`. + let hasPartitions: boolean = false; if (layerOf) { const nodeById = new Map(sized.nodes.map((node) => [node.id, node])); const visit = (elkNode: ElkNode): void => { @@ -84,7 +86,7 @@ export async function getElkLayout( if (layer !== undefined) { hasPartitions = true; child.layoutOptions = { - ...child.layoutOptions, + ...(child.layoutOptions ?? {}), 'elk.partitioning.partition': String(layer), }; } From ffe80336ce7c161143dd29d26246314988789c4c Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:29:01 -0400 Subject: [PATCH 10/15] =?UTF-8?q?fix(layout):=20ELK=20seed=E2=86=92randomS?= =?UTF-8?q?eed,=20partition=20flag=20CFA=20fix,=20dagre=20peer=20range=20^?= =?UTF-8?q?3||^4;=20docs:=20layout=20guide=20+=20transitions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/layout-transitions.md | 98 ++++++++++++++++++++++ docs/layout.md | 166 +++++++++++++++++++++++++++++++++++++ package.json | 2 +- src/layout/elk.ts | 36 ++++---- src/layout/index.ts | 6 +- tests/layout/elk.test.ts | 12 +++ 6 files changed, 301 insertions(+), 19 deletions(-) create mode 100644 docs/layout-transitions.md create mode 100644 docs/layout.md diff --git a/docs/layout-transitions.md b/docs/layout-transitions.md new file mode 100644 index 0000000..e60ec25 --- /dev/null +++ b/docs/layout-transitions.md @@ -0,0 +1,98 @@ +# Layout transitions + +In `@statelyai/graph`, a layout is not engine state — it's **data**. Every adapter returns a plain-JSON `VisualGraph`, and the graph itself stays the single source of truth. So "switch from dagre to ELK" is just two `VisualGraph`s, and `genLayoutTransition` tweens between them. Libraries that keep layout state inside engine or class instances can't do this — there's nothing to diff or interpolate; here it's two JSON values. + +## Tween between two engines + +```ts +import { createGraph } from '@statelyai/graph'; +import { getDagreLayout } from '@statelyai/graph/layout/dagre'; +import { getElkLayout } from '@statelyai/graph/layout/elk'; +import { applyLayoutFrame, genLayoutTransition } from '@statelyai/graph/layout'; + +const graph = createGraph({ + nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }, { id: 'd' }], + edges: [ + { id: 'e1', sourceId: 'a', targetId: 'b' }, + { id: 'e2', sourceId: 'a', targetId: 'c' }, + { id: 'e3', sourceId: 'b', targetId: 'd' }, + { id: 'e4', sourceId: 'c', targetId: 'd' }, + ], +}); + +// Same graph, two engines — both pure, the input is never mutated. +const before = getDagreLayout(graph, { direction: 'down' }); +const after = await getElkLayout(graph, { direction: 'down' }); + +// Drive the tween: one frame per animation frame. +const transition = genLayoutTransition(before, after, { + steps: 45, // default 30 + ease: (t) => 1 - Math.pow(1 - t, 3), // ease-out cubic (default: smoothstep) +}); + +function tick() { + const step = transition.next(); + if (step.done) return; // step.value === after (the target VisualGraph) + applyLayoutFrame(before, step.value); + render(before); + requestAnimationFrame(tick); +} +requestAnimationFrame(tick); +``` + +Nodes are matched by id; nodes without a position in `from` (or absent from it) start at their `to` position. `alpha` cools linearly 1 → 0, like the physics layouts, so the same render loop handles both. + +## Edges: be honest + +From the `genLayoutTransition` JSDoc: *"Edge routes are not interpolated — frames carry node positions only; hide or re-route edges during the transition."* Interpolating a dagre polyline into an ELK orthogonal route point-by-point is meaningless. The usual moves: + +- fade edges out, tween nodes, fade the target routes in, or +- draw straight source→target lines during the tween and restore `edge.points` when it finishes. + +## Diff-driven transitions + +Layouts are plain graphs, so `getPatches` / `applyPatches` (from `@statelyai/graph`) work on them directly. A patch set between two layouts tells you exactly which nodes moved — e.g. to skip tweening unmoved nodes: + +```ts +import { getPatches } from '@statelyai/graph'; + +const patches = getPatches(before, after); +const moved = new Set( + patches + .filter((p) => p.op === 'updateNode' && ('x' in p.data || 'y' in p.data)) + .map((p) => (p as { id: string }).id), +); + +for (const frame of genLayoutTransition(before, after)) { + for (const id of Object.keys(frame.positions)) { + if (!moved.has(id)) delete frame.positions[id]; // applyLayoutFrame skips absent nodes + } + applyLayoutFrame(before, frame); + render(before); +} +``` + +And because patches are first-class data, undo/redo falls out for free: keep the patch sets (or use `getDiff` + `invertDiff`) and `applyPatches` to step layout history in either direction. + +## Physics handoff: the "tidy up" button + +Let users fling nodes around with a force simulation, then snap the mess into a hierarchy — settle d3-force, lay out with ELK, tween between them: + +```ts +import { getForceLayout } from '@statelyai/graph/layout/d3-force'; +import { getElkLayout } from '@statelyai/graph/layout/elk'; +import { applyLayoutFrame, genLayoutTransition } from '@statelyai/graph/layout'; + +const settled = getForceLayout(graph, { seed: 42 }); // run simulation to completion + +async function tidyUp() { + const tidy = await getElkLayout(settled, { algorithm: 'layered' }); + for (const frame of genLayoutTransition(settled, tidy)) { + applyLayoutFrame(settled, frame); + render(settled); + await nextAnimationFrame(); + } +} +``` + +The reverse works too — `genLayoutTransition(tidy, settled)` — or hand the tidy positions back to `genForceLayout`, which seeds its simulation from existing positions for an incremental re-scatter. Engines compose, because the only thing passing between them is the graph. diff --git a/docs/layout.md b/docs/layout.md new file mode 100644 index 0000000..ebe7022 --- /dev/null +++ b/docs/layout.md @@ -0,0 +1,166 @@ +# Layout + +`@statelyai/graph` ships **no layout algorithms of its own**. Layout is a set of thin, pure adapters over proven external engines: a plain-JSON `Graph` goes in, a positioned `VisualGraph` comes out, and the engine stays an optional peer dependency on its own subpath. Engine character is not hidden — async engines give you a `Promise`, iterative engines give you a `Generator`, sync engines return directly. + +| Engine | Subpath | Function | Character | Peer dep(s) | Best for | +|---|---|---|---|---|---| +| ELK | `@statelyai/graph/layout/elk` | `getElkLayout` | async | `elkjs` | hierarchical/compound graphs, ports | +| dagre | `@statelyai/graph/layout/dagre` | `getDagreLayout` | sync | `@dagrejs/dagre` | quick DAG layout | +| Graphviz | `@statelyai/graph/layout/graphviz` | `getGraphvizLayout` | async (WASM) | `@hpcc-js/wasm-graphviz` | 8 classic engines, spline edge routing | +| d3-force | `@statelyai/graph/layout/d3-force` | `genForceLayout`, `getForceLayout` | generator / sync | `d3-force` | physics, tick-by-tick animation | +| ForceAtlas2 | `@statelyai/graph/layout/forceatlas2` | `getForceAtlas2Layout` | sync | `graphology`, `graphology-layout-forceatlas2` | large-graph physics | +| d3-hierarchy | `@statelyai/graph/layout/d3-hierarchy` | `getTidyTreeLayout` | sync | `d3-hierarchy` | trees (Reingold–Tilford) | +| WebCola | `@statelyai/graph/layout/webcola` | `getColaLayout` | sync | `webcola` | constraint-based, overlap-free | +| Cytoscape | `@statelyai/graph/layout/cytoscape` | `getCytoscapeLayout` | async | `cytoscape` | the cytoscape layout ecosystem | + +Shared utilities and types live on `@statelyai/graph/layout`: `LayoutOptions`, `LayoutConstraints`, `LayoutFn`, `IterativeLayoutFn`, `LayoutFrame`, `DEFAULT_NODE_SIZE`, `getNodeSize`, `applyLayoutFrame`, `getLayoutBounds`, `genLayoutTransition`, `translateGraph`, `centerGraph`. + +## The contract + +Every adapter is a `LayoutFn`: `(graph, options?) => VisualGraph | Promise`. The input graph is never mutated. + +**Node geometry.** `node.x`/`node.y` are the **top-left** corner (engines that report centers — dagre, Graphviz, d3, cola, cytoscape — are converted for you). + +**Edge routes.** Engines that route edges write `edge.points` (waypoints ordered **tail → head**) and `edge.routing`: + +- `'polyline'` — straight segments through the points (dagre). +- `'orthogonal'` — axis-aligned segments (ELK layered routing). +- `'splines'` — bezier control points in the Graphviz convention: 3n+1 chained cubic beziers, endpoints included. + +d3-force, ForceAtlas2, d3-hierarchy, WebCola, and Cytoscape position nodes only — no `points`. + +**Edge labels.** `edge.x`/`edge.y`/`edge.width`/`edge.height` are canonically the **edge-label rect**. Give an edge a label plus `width`/`height` and label-aware engines (ELK, dagre, Graphviz) reserve space and write the placed rect back. + +**Coordinate systems.** ELK is the one engine that produces **parent-relative** child coordinates (a node with `parentId` is positioned within its parent — the xyflow convention). dagre and cytoscape support compound graphs but emit **absolute** coordinates; all flat engines are absolute. Graphviz rejects compound graphs (throws — use ELK or `flatten()` first). + +## Sizing: the `measure` callback + +Text measurement belongs to the renderer, so adapters never guess. `getNodeSize(node, options)` resolves every node's size through a fixed chain: + +1. `options.measure(node)` — your callback (e.g. canvas `measureText`), +2. the node's own `width`/`height`, +3. `DEFAULT_NODE_SIZE` (`{ width: 100, height: 50 }`). + +Zero or absent dimensions count as **unset** and fall through — layout engines overlap zero-sized nodes. + +```ts +import { getElkLayout } from '@statelyai/graph/layout/elk'; + +const laidOut = await getElkLayout(graph, { + measure: (node) => measureText(node.label), // renderer owns text metrics +}); +``` + +## Common options + +All adapters accept `LayoutOptions`; each extends it with engine-specific fields. + +- **`direction`** — `'up' | 'down' | 'left' | 'right'`, defaulting to `graph.direction ?? 'down'`. Maps to dagre/Graphviz `rankdir`, ELK direction, d3-hierarchy axes, and WebCola `flowLayout`. Caveat: cola only separates source-before-target along the axis, so `'up'`/`'left'` flow the same as `'down'`/`'right'`. Cytoscape ignores it (use `layoutOptions`). +- **`spacing`** — `{ node?, layer? }` hints. ELK: `elk.spacing.nodeNode` / `elk.layered.spacing.nodeNodeBetweenLayers`; dagre: `nodesep` / `ranksep`; Graphviz: `nodesep` / `ranksep` (converted to inches); d3-hierarchy: breadth/depth steps; WebCola: `spacing.layer` is the flow gap. Force engines use `linkDistance` instead; cytoscape ignores it. +- **`seed`** — determinism for engines with randomness; same seed, same layout. + - **Honored:** d3-force (drives `randomSource` *and* the initial scatter), ForceAtlas2 and WebCola (seeded initial scatter for unpositioned nodes — both engines are otherwise deterministic), Graphviz (maps to the `start` attribute, used by the randomized engines `neato`/`fdp`/`sfdp`). + - **Ignored:** dagre, ELK, d3-hierarchy (deterministic anyway), and cytoscape — the discrete layouts are deterministic and **cose is not seedable**. +- **`isFixed`** — pin nodes at their current `x`/`y`: + - d3-force: `fx`/`fy` (exact). ForceAtlas2: the `fixed` node attribute (native). Cytoscape: `locked: true` (layouts skip locked nodes; only nodes that already have a position). WebCola: cola's `fixed` flag — held with a large-but-finite weight during overlap projection, so pinning is within a small tolerance, not exact. Pinning also disables cola's final centering. + - Not supported by ELK, dagre, Graphviz, or d3-hierarchy. + +Positioned input also matters to the physics engines: d3-force, ForceAtlas2, and WebCola seed their simulations from existing node positions, so re-running them is an **incremental relayout** from the current arrangement. + +## Constraints + +`options.constraints` is a portable, **advisory** vocabulary (like port `direction`): engines that can express a constraint honor it, the rest ignore it. + +`constraints.layer: (node) => number | undefined` assigns nodes to ordered layers along the flow axis. Same value → same layer; smaller values come earlier; `undefined` leaves the node unconstrained. + +| Constraint | ELK | Graphviz (`dot`) | dagre | force engines | +|---|---|---|---|---| +| `layer` | partitions (`elk.partitioning.partition` + `elk.partitioning.activate`) | `{ rank=same; … }` groups | ignored | ignored | + +Note Graphviz's semantics: `rank=same` groups nodes into the same layer, but ordering *between* constrained layers still follows the edges. Only the `dot` engine has ranks. + +For anything beyond the portable vocabulary, every adapter has a raw escape hatch, always applied **last** (overrides everything the adapter computed): + +- ELK: `layoutOptions` (raw ELK options) — plus `algorithm` (`'layered'` default, `'mrtree'`, `'force'`, `'stress'`, `'radial'`, `'rectpacking'`). +- dagre: `graphOptions` (raw `setGraph` options). +- Graphviz: `graphAttributes` (raw graph attributes) — plus `engine` (`'dot'`, `'neato'`, `'fdp'`, `'sfdp'`, `'circo'`, `'twopi'`, `'osage'`, `'patchwork'`). +- ForceAtlas2: `settings` (`scalingRatio`, `gravity`, `linLogMode`, `barnesHutOptimize`, …). +- Cytoscape: `layoutOptions` (raw per-layout options — `boundingBox`, `roots`, iteration counts) plus `name`. + +## Iterative layouts + +`genForceLayout` is an `IterativeLayoutFn`: each `next()` advances one simulation tick and yields a `LayoutFrame` — `{ positions: Record, alpha }` with top-left positions by node id and `alpha` cooling 1 → 0. **You own pacing** (one tick per animation frame) **and cancellation** (just stop iterating / drop the generator). The generator's *return value* is the settled `VisualGraph`. + +```ts +import { genForceLayout } from '@statelyai/graph/layout/d3-force'; +import { applyLayoutFrame } from '@statelyai/graph/layout'; + +const sim = genForceLayout(graph, { seed: 42 }); +let cancelled = false; + +function tick() { + if (cancelled) return; // cancellation = stop calling next() + const step = sim.next(); + if (step.done) return; // step.value is the settled VisualGraph + applyLayoutFrame(graph, step.value); // mutates node x/y in place — cheap, index-safe + render(graph); + requestAnimationFrame(tick); +} +requestAnimationFrame(tick); +``` + +`applyLayoutFrame` writes positions onto the graph in place; positions are non-structural, so no `invalidateIndex()` is needed and it's cheap enough for per-frame use. Nodes absent from a frame are left untouched. `getForceLayout` runs the same generator to completion when you don't need animation. + +## Geometry utilities + +**`getLayoutBounds(graph)`** — bounding rect of all positioned nodes *and* edge route points; zero rect when there's no geometry. Ideal for an SVG viewBox: + +```ts +import { getLayoutBounds } from '@statelyai/graph/layout'; + +const b = getLayoutBounds(laidOut); +svg.setAttribute('viewBox', `${b.x} ${b.y} ${b.width} ${b.height}`); +``` + +**`translateGraph(graph, dx, dy)`** — mutable shift of node positions, edge `points`, and edge label rects. It is **hierarchy-aware**: children (`parentId` set) use parent-relative coordinates (the ELK/xyflow convention), so only top-level nodes are shifted — children ride along with their parents. Likewise an edge's geometry is shifted only when its containing coordinate system is the root (the LCA of its endpoints is no node). + +**`centerGraph(graph, rect)`** — translate in place so the layout bounds' center coincides with `rect`'s center; no-op for graphs without geometry. + +```ts +import { centerGraph } from '@statelyai/graph/layout'; + +centerGraph(laidOut, { x: 0, y: 0, width: canvas.width, height: canvas.height }); +``` + +## Web workers + +**ELK** has worker support built into `elkjs` — inject a worker-backed instance via the `elk` option (any object with `layout(graph): Promise` satisfies `ElkLike`): + +```ts +import ELK from 'elkjs/lib/elk-api'; +import { getElkLayout } from '@statelyai/graph/layout/elk'; + +const elk = new ELK({ + workerFactory: () => + new Worker(new URL('elkjs/lib/elk-worker.min.js', import.meta.url)), + // or: workerUrl: '...' +}); + +const laidOut = await getElkLayout(graph, { elk }); +``` + +**Cytoscape** uses the same injection pattern via the `cy` option — pass your own `cytoscape` factory (e.g. one with extensions registered via `cytoscape.use(...)` for cola/fcose/dagre layouts). + +**The sync engines** (dagre, WebCola, ForceAtlas2, d3-hierarchy) block the thread they run on — but graphs are plain JSON, which is exactly the point of the serializable model: `postMessage` the graph to your own worker (structured clone is free), run the whole layout call there, and post the `VisualGraph` back. No serialization layer to write. + +## Choosing an engine + +- **Compound graphs or ports?** ELK — hierarchy and ports are first-class; it's the only engine producing parent-relative coordinates. +- **A quick synchronous DAG?** dagre. Note it ignores per-edge `mode` (mixed graphs → ELK). +- **Classic looks or spline edges?** Graphviz — eight engines behind one option. +- **Animated physics?** d3-force, driven frame-by-frame. +- **Physics on big graphs?** ForceAtlas2 (Barnes–Hut via `settings.barnesHutOptimize`). +- **Strict trees?** d3-hierarchy tidy tree (non-trees fall back to a spanning tree; cyclic graphs need `rootId`). +- **No overlaps, flow constraints?** WebCola — overlap avoidance is always on. +- **Something exotic (concentric, fcose, …)?** Cytoscape — one adapter, the whole ecosystem. + +Switching later is cheap: layouts are data. See [layout-transitions.md](./layout-transitions.md). diff --git a/package.json b/package.json index a121810..40ca997 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "zod": "^4.3.6" }, "peerDependencies": { - "@dagrejs/dagre": "^4.0.0", + "@dagrejs/dagre": "^3.0.0 || ^4.0.0", "@hpcc-js/wasm-graphviz": "^1.0.0", "cytoscape": "^3.0.0", "d3-force": "^3.0.0", diff --git a/src/layout/elk.ts b/src/layout/elk.ts index f794c04..089b7a4 100644 --- a/src/layout/elk.ts +++ b/src/layout/elk.ts @@ -74,26 +74,23 @@ export async function getElkLayout( // constraints.layer → ELK partitions (same value = same layer, ordered // along the flow axis) const layerOf = options?.constraints?.layer; - // `boolean` annotation: assigned inside the visitor closure, which TS's - // narrowing doesn't see — without it the spread below narrows to `false`. - let hasPartitions: boolean = false; + let hasPartitions = false; if (layerOf) { const nodeById = new Map(sized.nodes.map((node) => [node.id, node])); - const visit = (elkNode: ElkNode): void => { - for (const child of elkNode.children ?? []) { - const node = nodeById.get(child.id); - const layer = node === undefined ? undefined : layerOf(node); - if (layer !== undefined) { - hasPartitions = true; - child.layoutOptions = { - ...(child.layoutOptions ?? {}), - 'elk.partitioning.partition': String(layer), - }; - } - visit(child); + const stack = [...(root.children ?? [])]; + while (stack.length > 0) { + const child = stack.pop()!; + const node = nodeById.get(child.id); + const layer = node === undefined ? undefined : layerOf(node); + if (layer !== undefined) { + hasPartitions = true; + child.layoutOptions = { + ...child.layoutOptions, + 'elk.partitioning.partition': String(layer), + }; } - }; - visit(root); + stack.push(...(child.children ?? [])); + } } root.layoutOptions = { @@ -107,6 +104,11 @@ export async function getElkLayout( options.spacing.layer, ), }), + // Honored by ELK's randomized algorithms (force, stress); ignored by the + // deterministic ones. + ...(options?.seed !== undefined && { + 'elk.randomSeed': String(options.seed), + }), ...root.layoutOptions, ...options?.layoutOptions, }; diff --git a/src/layout/index.ts b/src/layout/index.ts index ebb6193..b9687b5 100644 --- a/src/layout/index.ts +++ b/src/layout/index.ts @@ -16,7 +16,11 @@ export interface LayoutOptions { * Layout direction. Defaults to `graph.direction ?? 'down'`. */ direction?: 'up' | 'down' | 'left' | 'right'; - /** Spacing hints (engines map these to their native options). */ + /** + * Spacing hints (engines map these to their native options where the + * mapping is well-defined; engines without one ignore them — see each + * adapter's JSDoc). + */ spacing?: { /** Space between sibling nodes. */ node?: number; diff --git a/tests/layout/elk.test.ts b/tests/layout/elk.test.ts index 1e3c3d9..93f7536 100644 --- a/tests/layout/elk.test.ts +++ b/tests/layout/elk.test.ts @@ -111,6 +111,18 @@ describe('getElkLayout', () => { ); }); + it('maps seed to elk.randomSeed (randomized algorithms)', async () => { + const first = await getElkLayout(makeGraph(), { + algorithm: 'force', + seed: 7, + }); + const second = await getElkLayout(makeGraph(), { + algorithm: 'force', + seed: 7, + }); + expect(second).toEqual(first); + }); + it('maps constraints.layer to ELK partitions', async () => { // Fan a→b, a→c: unconstrained layered puts b and c in the same layer; // partitioning b=1, c=2 forces c into a later layer than b. From 51ef0deb52e4d5260ecfa8caf65e5c4c5d29ebdb Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:30:52 -0400 Subject: [PATCH 11/15] docs(readme): sync peers table, algorithms, layout section (8 adapters, honest routing claims), guides index --- README.md | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e36b870..1157c7b 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,19 @@ Optional peers are only needed for specific adapters: -| Package | Needed for | -| ----------------- | --------------------------------------------------- | -| `fast-xml-parser` | `@statelyai/graph/gexf`, `@statelyai/graph/graphml` | -| `dotparser` | `@statelyai/graph/dot` parsing | -| `cytoscape` | Cytoscape integration tests and consumer typing | -| `d3-force` | D3 force integration tests and consumer typing | -| `elkjs` | `@statelyai/graph/elk` | -| `zod` | `@statelyai/graph/schemas` | +| Package | Needed for | +| ------------------------------------------- | --------------------------------------------------- | +| `fast-xml-parser` | `@statelyai/graph/gexf`, `@statelyai/graph/graphml` | +| `dotparser` | `@statelyai/graph/dot` parsing | +| `zod` | `@statelyai/graph/schemas` | +| `elkjs` | `@statelyai/graph/elk`, `@statelyai/graph/layout/elk` | +| `@dagrejs/dagre` | `@statelyai/graph/layout/dagre` | +| `@hpcc-js/wasm-graphviz` | `@statelyai/graph/layout/graphviz` | +| `d3-force` | `@statelyai/graph/layout/d3-force` | +| `graphology`, `graphology-layout-forceatlas2` | `@statelyai/graph/layout/forceatlas2` | +| `d3-hierarchy` | `@statelyai/graph/layout/d3-hierarchy` | +| `webcola` | `@statelyai/graph/layout/webcola` | +| `cytoscape` | `@statelyai/graph/layout/cytoscape`, Cytoscape format typing | ## Highlights @@ -29,7 +34,8 @@ Optional peers are only needed for specific adapters: - Standalone functions with a consistent `get*`/`gen*`/`is*`/`add*` naming model - Directed, undirected, hierarchical, and visual graph support - Ports for node-editor and dataflow-style graphs -- Algorithms for traversal, paths, centrality, communities, connectivity, isomorphism, ordering, MST, and walks +- Algorithms for traversal, paths, centrality, communities, connectivity, flow/cuts, matching, cores, isomorphism, ordering, MST, and walks +- Pluggable layout over eight external engines (ELK, Graphviz, dagre, d3-force, ForceAtlas2, tidy tree, WebCola, cytoscape) — pure functions, optional peers - Diff/patch utilities for graph state changes - Multi-format conversion via package subpaths, with fidelity claims tested against fixtures - Small, fast test suite with broad format coverage @@ -188,7 +194,7 @@ const parsed = GraphSchema.parse(unknownValue); -Includes traversal (BFS, DFS, preorder/postorder), pathfinding (shortest path, simple paths, all-pairs shortest paths, A*), centrality/link analysis (degree, closeness, betweenness, PageRank, HITS, eigenvector), community detection (Louvain, label propagation, Girvan-Newman, greedy modularity, modularity scoring), flow (max-flow/min-cut), cycle detection, connected/strongly-connected components, bridges, articulation points, biconnected components, dominator trees, transitive reduction, isomorphism, topological sort, minimum spanning tree, and more. Many algorithms have lazy generator variants (`gen*`) for early exit. +Includes traversal (BFS, DFS, preorder/postorder), pathfinding (shortest path, simple paths, all-pairs shortest paths, A*, bidirectional Dijkstra), centrality/link analysis (degree, closeness, betweenness, PageRank, HITS, eigenvector, Katz), community detection (Louvain, label propagation, Girvan-Newman, greedy modularity, modularity scoring), flow & cuts (`getMaxFlow`, `getMinCut`), bipartite analysis (`isBipartite`, Hopcroft–Karp `getMaximumBipartiteMatching`), k-cores (`getCoreNumbers`, `getKCore`), cycle detection, connected/strongly-connected components, bridges, articulation points, biconnected components, dominator trees, transitive reduction, isomorphism, topological sort, minimum spanning tree, and seeded graph generators (`createCompleteGraph`, `createGridGraph`, `createRandomGraph`). Many algorithms have lazy generator variants (`gen*`) for early exit. See [docs/algorithms.md](./docs/algorithms.md) for the full reference. Hot algorithm loops (centrality, components) run on an internal compressed-sparse-row snapshot — cached and invalidated transparently like the rest of the index — so they stay fast on large graphs without changing the plain-JSON model. Algorithm results are differential-tested against graphology on seeded random graphs. @@ -240,17 +246,24 @@ isIsomorphic(graph, otherGraph); // structural equivalence ## Layout -Plug-and-play layout over external engines — pure functions in, positioned `VisualGraph` out (node positions, routed edge `points`, computed edge-label rects). No layout algorithms of our own; each adapter is a subpath with an optional peer dependency. + + +Plug-and-play layout over external engines — pure functions in, positioned `VisualGraph` out. No layout algorithms of our own; each adapter is a subpath with an optional peer dependency. The hierarchical engines (ELK, dagre, Graphviz) also produce routed edge `points` and computed edge-label rects; the physics/tree/cytoscape engines position nodes only. ```ts import { getElkLayout } from '@statelyai/graph/layout/elk'; // elkjs import { getDagreLayout } from '@statelyai/graph/layout/dagre'; // @dagrejs/dagre -import { getGraphvizLayout } from '@statelyai/graph/layout/graphviz'; // @hpcc-js/wasm-graphviz +import { getGraphvizLayout } from '@statelyai/graph/layout/graphviz'; // @hpcc-js/wasm-graphviz (8 engines) import { genForceLayout } from '@statelyai/graph/layout/d3-force'; // d3-force -import { applyLayoutFrame, getLayoutBounds } from '@statelyai/graph/layout'; +import { getForceAtlas2Layout } from '@statelyai/graph/layout/forceatlas2'; // graphology FA2 +import { getTidyTreeLayout } from '@statelyai/graph/layout/d3-hierarchy'; // d3-hierarchy +import { getColaLayout } from '@statelyai/graph/layout/webcola'; // webcola (constraints) +import { getCytoscapeLayout } from '@statelyai/graph/layout/cytoscape'; // cytoscape ecosystem +import { applyLayoutFrame, getLayoutBounds, centerGraph } from '@statelyai/graph/layout'; const laidOut = await getElkLayout(graph, { measure: (node) => measureText(node.label), // text measurement stays yours + constraints: { layer: (node) => node.data?.tier }, // portable layer constraint }); // Physics layouts are generators — one tick per frame, cancel by stopping @@ -260,7 +273,7 @@ for (const frame of genForceLayout(graph, { seed: 42 })) { } ``` -Edge `x`/`y`/`width`/`height` are canonically the edge-label rect; routes live in `edge.points` (`routing` says how to interpret them). Layouts are plain JSON — diff them with `getPatches` to animate transitions between engines. +Edge `x`/`y`/`width`/`height` are canonically the edge-label rect; routes live in `edge.points` (`routing` says how to interpret them). Layouts are plain JSON — tween between engines with `genLayoutTransition`, or diff them with `getPatches`. See [docs/layout.md](./docs/layout.md) and [docs/layout-transitions.md](./docs/layout-transitions.md). ## Diff & Walks @@ -371,6 +384,17 @@ Format-specific docs live alongside the source: - [xyflow](./src/formats/xyflow/README.md) - [Converter helpers](./src/formats/converter/README.md) +## Guides + + + +- [Layout guide](./docs/layout.md) — the adapter contract, all eight engines, constraints, sizing, web workers +- [Layout transitions](./docs/layout-transitions.md) — tween between engines; layouts are just data +- [Algorithms reference](./docs/algorithms.md) — every algorithm with complexity and semantics notes +- [Benchmarks](./docs/benchmarks.md) — measured against graphology, ngraph, graphlib, and cytoscape +- [Migrating from graphlib](./docs/migrating-from-graphlib.md) +- [React Flow + ELK pipeline](./docs/react-flow-elk-pipeline.md) — measured nodes, worker layout, live re-layout + ## Examples From f73edb695dce35a479444808893f62c57786d897 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:31:09 -0400 Subject: [PATCH 12/15] docs: algorithms reference (70 functions, complexity + semantics) --- docs/algorithms.md | 147 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 docs/algorithms.md diff --git a/docs/algorithms.md b/docs/algorithms.md new file mode 100644 index 0000000..a88a037 --- /dev/null +++ b/docs/algorithms.md @@ -0,0 +1,147 @@ +# Algorithms reference + +Every algorithm is a standalone prefixed function over a plain-JSON `Graph` — no classes, no wrappers. Expensive multi-result functions come in `gen*` (lazy generator, early-exit friendly) / `get*` (eager array, `return [...gen*()]`) pairs; hot paths run on a cached CSR (compressed-sparse-row) snapshot, and every traversal honors each edge's *effective* mode (`getEdgeMode`: per-edge `mode` override, else `graph.mode`), so mixed directed/undirected graphs behave correctly throughout. + +See [README.md](../README.md#algorithms) for a tour, [./layout.md](./layout.md) for the visual side, and [./benchmarks.md](./benchmarks.md) for numbers. + +Conventions: `n` = nodes, `m` = edges, `k` = iterations. Default edge weight is `edge.weight ?? 1`; weighted algorithms accept a `getWeight` accessor. Where a start node is optional (`options.from`), it defaults to `graph.initialNodeId`, then to the unique zero-in-degree node, else throws. + +## Traversal & ordering + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `bfs(graph, startId)` | Lazy breadth-first node visit | O(n + m) | CSR-backed generator. Mode-aware: non-directed edges traversable both ways. Unknown start yields nothing. | +| `dfs(graph, startId)` | Lazy depth-first node visit | O(n + m) | Iterative (no recursion limit), CSR-backed. | +| `getPreorder(graph, opts?)` / `getPostorder(graph, opts?)` | One DFS pre/post ordering from `from` | O(n + m) | Deterministic: neighbors in index order. | +| `genPreorders(graph, opts?)` / `genPostorders(graph, opts?)` | All possible DFS pre/post orderings | exponential (output-sensitive) | Lazy; branches on every neighbor choice. `getPreorders`/`getPostorders` are the eager forms. | + +## Connectivity & components + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `hasPath(graph, sourceId, targetId)` | Reachability | O(n + m) | BFS, mode-aware. `hasPath(g, a, a)` is `true`. | +| `isConnected(graph)` | Single weak component? | O(n + m) | Empty graph is connected. | +| `isTree(graph)` | Connected + acyclic + exactly `n − 1` edges | O(n + m) | Directed diamonds and parallel edges are not trees. Empty/single-node graphs are trees. | +| `getConnectedComponents(graph)` | Weakly-connected components | O(n + m) | Every edge connects regardless of mode/direction. CSR-backed. | +| `getStronglyConnectedComponents(graph)` | SCCs (Tarjan) | O(n + m) | Non-directed edges count as mutual reachability. Recursive — deep graphs may hit stack limits. | +| `getBridges(graph)` | Edges whose removal disconnects | O(n + m) | Treats the graph as undirected. Result sorted by id. | +| `getArticulationPoints(graph)` | Cut vertices | O(n + m) | Undirected semantics; sorted by id. | +| `getBiconnectedComponents(graph)` | Biconnected components (node arrays) | O(n + m) | Articulation points appear in multiple components. | + +## Cycles & DAG + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `isAcyclic(graph)` | No cycles? | O(n + m) typical | Mixed graphs use polynomial fast paths (directed-only cycle, union-find on non-directed edges, singleton SCCs); only ambiguous multi-node SCCs fall back to exact simple-cycle enumeration (exponential worst case, scoped to that SCC). | +| `genCycles(graph)` / `getCycles(graph)` | All simple cycles as `GraphPath`s | exponential (output-sensitive) | Dispatches on the *effective* mode kind: directed (Johnson-style DFS), undirected (edge-id dedup — two parallel edges form a genuine 2-cycle; can't re-traverse the arrival edge), or mixed (exact search, each edge used at most once; correct but potentially expensive on dense mixed graphs). | +| `getTopologicalSort(graph)` | Topological order or `null` | O(n + m) | Returns `null` on any cycle *and* whenever any edge's effective mode isn't `'directed'` (undirected = mutual precedence = 2-cycle). | +| `getTransitiveReduction(graph)` | New graph with transitively-redundant edges removed | O(n·m) time, O(n²) reach memory | DAG-only: throws on a cycle or any non-directed edge. Exact-duplicate parallel edges collapse to the first in `graph.edges` order. Input not mutated. | +| `getDominatorTree(graph, opts?)` | `{ nodeId: idomId \| null }` rooted at `from` | near-linear (Cooper–Harvey–Kennedy iteration) | Root maps to `null`; unreachable nodes omitted. Mode-aware traversal. For statecharts: "which states must every path from the initial state pass through?" | + +## Shortest paths + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `getShortestPath(graph, { from, to, ... })` | One shortest path or `undefined` | sublinear in practice | Single-pair queries use **bidirectional Dijkstra** (frontiers meet long before a unidirectional search finishes); ties broken arbitrarily. Pass `algorithm: 'bellman-ford'` for negative weights (full search). | +| `genShortestPaths(graph, opts?)` / `getShortestPaths(...)` | *All* tied shortest paths from `from` (to `to`, or to every reachable node) | Dijkstra O((n + m) log n) + lazy reconstruction | Tie predecessors are recorded, so equal-cost alternatives are all yielded. With `to`, the search **early-exits** once everything at distance ≤ dist(target) settles. Paths are reconstructed on demand — abandoning the generator never pays for paths it didn't yield. Zero-weight cycles are handled (no revisits during reconstruction). | +| `getAStarPath(graph, { from, to, heuristic, ... })` | One heuristic-guided shortest path | O((n + m) log n), heuristic-dependent | Admissible heuristic ⇒ optimal path. | +| `getAllPairsShortestPaths(graph, opts?)` | Shortest paths between all pairs | Dijkstra-per-source (default) O(n(n + m) log n); `'floyd-warshall'` O(n³); `'bellman-ford'` O(n²m) | Floyd-Warshall throws on a negative cycle (self-distance < 0). Eager — output can be huge. | +| `genSimplePaths(graph, opts?)` / `getSimplePaths(...)` / `getSimplePath(...)` | All (or first) simple paths from `from` (optionally to `to`) | exponential (output-sensitive) | DFS with backtracking; without `to`, every non-empty simple path is yielded. | +| `joinPaths(headPath, tailPath)` | Concatenated `GraphPath` | O(steps) | Throws unless head ends where tail starts. | + +**Negative-weight contract.** Dijkstra, A*, and the bidirectional/early-exit searches may legitimately finish without ever scanning a negative edge — so they assert "no negative weights" **up front**: O(1) via the CSR's cached `firstNegativeEdge` flag for the default weight, or one O(m) sweep when a custom `getWeight` is supplied. They throw with a pointer to `{ algorithm: 'bellman-ford' }` (O(n·m), handles negative edges; negative *cycles* still throw). + +## Spanning trees + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `getMinimumSpanningTree(graph, opts?)` | New `Graph` containing the MST/forest edges | Prim (default) O(m log m); `algorithm: 'kruskal'` O(m log m) | Mode-aware: non-directed edges are candidates in both directions; directed edges only source→target (Prim). All nodes are kept; weight from `opts.getWeight ?? edge.weight ?? 1`. | + +## Centrality + +All return `Record` (or `HITSResult`). Iterative methods take `{ alpha?, maxIterations? (100), tolerance? (1e-6) }`. + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `getDegreeCentrality` / `getInDegreeCentrality` / `getOutDegreeCentrality` | Degree / n − 1 | O(n + m) | | +| `getClosenessCentrality(graph)` | Closeness over unweighted hops | O(n(n + m)) | Wasserman–Faust scaled by reachable fraction, so disconnected graphs are comparable. Directed/undirected per edge semantics. | +| `getBetweennessCentrality(graph)` | Brandes betweenness, normalized | O(n·m) | **Unweighted** shortest paths. Normalization keys off `graph.mode` (undirected scores halved), not per-edge modes. CSR typed-array implementation. | +| `getPageRank(graph, opts?)` | PageRank (power iteration) | O(k(n + m)) | `alpha` damping (0.85). Dangling mass redistributed uniformly; result sums to 1. | +| `getHITS(graph, opts?)` | `{ hubs, authorities }` | O(k(n + m)) | L2-normalized each iteration. | +| `getEigenvectorCentrality(graph, opts?)` | Eigenvector centrality | O(k·m) | `A + I` shift (networkx/graphology scheme) so bipartite graphs converge. Score flows along edge direction (fed by in-neighbors); optional `getWeight`. **Throws on non-convergence.** | +| `getKatzCentrality(graph, opts?)` | Katz: `x' = αAᵀx + β` | O(k·m) | Converges only for `alpha < 1/λ_max`; **throws on non-convergence** (default `alpha` 0.1, `beta` 1). L2-normalized. | + +## Communities + +All community algorithms treat the graph as **undirected** regardless of mode. Output communities are sorted (ids lexicographic, communities by first id) — deterministic. + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `getLouvainCommunities(graph, opts?)` | Two-phase Louvain partition (`string[][]` of node ids) | ≈O(m) per pass, ≤ `maxPasses` (10) | Deterministic: `graph.nodes` order, no shuffling. Parallel-edge weights summed; self-loops count as internal weight. `resolution` γ > 1 favors smaller communities. | +| `getLabelPropagationCommunities(graph, opts?)` | LPA partition (`GraphNode[][]`) | O(k·m) | Without `seed`: synchronous, lexicographic tie-breaking (deterministic). With `seed`: classic asynchronous variant — shuffled order + random ties, mulberry32-seeded, **deterministic per seed**. | +| `genGirvanNewmanCommunities(graph, opts?)` | Lazy successive splits via edge-betweenness removal | O(n·m) per removal round | Yields a partition each time the component count grows; abandon early to skip deeper levels. | +| `getGirvanNewmanCommunities(graph, opts?)` | The split at `level` (default 1) | as above | `level <= 0` returns the connected components. | +| `getGreedyModularityCommunities(graph)` | Greedy modularity merging | very expensive (re-scores every pair per merge) | Small graphs only. | +| `getModularity(graph, communities)` | Modularity Q of a partition | O(m + Σ\|c\|²) | Undirected convention (degree counts both endpoints). | + +## Flow & cuts + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `getMaxFlow(graph, { from, to, getCapacity? })` | `{ value, flows, cutEdges }` | Edmonds–Karp O(n·m²) | Capacity defaults to `edge.weight ?? 1`; negative capacity throws. Directed edges carry flow source→target only; non-directed edges become two independent opposite arcs each with full capacity. `flows` is net flow per edge id (positive = source→target). Self-loops carry nothing. | +| `getMinCut(graph, { source, sink, getCapacity? })` | `{ value, cutEdges, partition }` | same solver | Max-flow-min-cut: `partition.source` = residual-reachable side (in `graph.nodes` order); `Σ cap(cutEdges) === value`. | + +## Bipartite + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `isBipartite(graph)` | 2-colorability | O(n + m) | Edges treated as undirected; **self-loops make a graph non-bipartite**. | +| `getMaximumBipartiteMatching(graph)` | Maximum matching (`BipartiteMatch[]`) | Hopcroft–Karp O(m·√n) | Bipartition derived by 2-coloring. Throws if not bipartite, naming the conflicting edge. Matches report the realizing edge with its stored orientation; for parallel edges, the first one used wins. | + +## Cores + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `getCoreNumbers(graph)` | Core number per node | O(m) (Batagelj–Zaveršnik bucket peeling) | **Undirected degree convention** — every edge contributes to both endpoints regardless of mode/direction; self-loops ignored. | +| `getKCore(graph, k)` | Node ids in the k-core | O(m) | `k <= 0` returns every node id; order follows `graph.nodes`. | + +## Isomorphism & equivalence + +| Function | Computes | Complexity | Notes | +|---|---|---|---| +| `isIsomorphic(graphA, graphB, opts?)` | Structural isomorphism | exponential worst case (degree-signature-pruned backtracking) | Degree signatures count per *effective* edge mode (in/out for directed, one undirected incidence otherwise), so per-edge overrides participate. Optional `nodeMatch`/`edgeMatch` refine with payloads. | +| `areEntitiesEqual(a, b, keys?)` | Key-wise node/edge equality | O(keys) | Objects compared by JSON stringification. | +| `isLayoutEqual(a, b)` / `isNonLayoutEqual(a, b)` | Equality on `LAYOUT_KEYS` / everything else | O(keys) | Layout keys: `x`, `y`, `width`, `height`, `points`, … — useful for "did layout actually change?" checks. | + +## Random walks (model-based testing) + +Walk generators yield `GraphStep`s lazily and honor effective edge modes (non-directed edges traversable both ways). All accept `seed` (mulberry32 — deterministic per seed; `Math.random` otherwise), `from`, and an edge `filter(edge, ctx)`. + +| Function | Behavior | Notes | +|---|---|---| +| `genRandomWalk(graph, opts?)` | Uniform random edge each step | Infinite until a sink (no traversable edges) is reached. | +| `genWeightedRandomWalk(graph, opts?)` | Probability ∝ `getWeight` (`edge.weight ?? 1`) | Negative weights clamp to 0; all-zero stops the walk. | +| `genQuickRandomWalk(graph, opts?)` | Targets unvisited edges; BFS-hops to the nearest one when stuck | Ends when no unvisited edge is reachable — fast edge coverage. | +| `genPredefinedWalk(graph, edgeIds, opts?)` | Replays an explicit edge-id sequence | Throws on a missing or non-adjacent edge. | +| `takeSteps(gen, n)` / `takeUntilNode(gen, id)` / `takeUntilEdge(gen, id)` | Stop-condition wrappers | Compose around any step generator. | +| `takeUntilNodeCoverage(gen, graph, c, opts?)` / `takeUntilEdgeCoverage(gen, graph, c)` | Stop at coverage fraction `c` (0–1) | Start node counts as visited for node coverage. | +| `getCoverage(graph, steps, opts?)` | `CoverageStats` for a completed walk | Node/edge coverage ratios + visited ids. | + +## Graph generators + +| Function | Creates | Notes | +|---|---|---| +| `createCompleteGraph(n, opts?)` | K_n, undirected | Nodes `n0..`, edges `e0..`; `idPrefix` overrides. | +| `createGridGraph(rows, cols, opts?)` | Grid with right/down neighbors, undirected | Nodes `n{r}_{c}`. | +| `createRandomGraph(n, p, opts?)` | Erdős–Rényi G(n, p), undirected | Deterministic per `seed` (mulberry32). | + +## Queries (headline) + +`src/queries.ts` holds O(1)/O(deg) indexed lookups rather than algorithms — neighborhood (`getNeighbors`, `getSuccessors`, `getPredecessors`, `getEdgesOf`, `getInEdges`, `getOutEdges`, `getEdgesBetween`), degree (`getDegree`, `getInDegree`, `getOutDegree`), hierarchy (`getChildren`, `getParent`, `getAncestors`, `getDescendants`, `getRoots`, `getSiblings`, `getDepth`, `getLCA`, `isCompound`, `isLeaf`), endpoints (`getSources`, `getSinks`), BFS hop-distance maps (`getRelativeDistanceMap`, `getRelativeDistance`), and ports (`getPort`, `getPorts`, `getEdgesByPort`). All collection queries return `[]` (never `undefined`) when empty. `getGraphIssues(graph)` validates referential integrity (dangling endpoints, missing parents, …) without throwing. + +## Performance notes + +- **CSR snapshot.** Hot loops (BFS/DFS, components, shortest paths, centrality, cores, bipartite) run on a compressed-sparse-row snapshot of the graph's *traversable arcs* (`src/algorithms/csr.ts`): flat `Int32Array`s addressed by node position, so traversal pays no string hashing or Map lookups. Directed edges contribute one arc; non-directed edges contribute both. It also caches a `firstNegativeEdge` flag for O(1) negative-weight assertions. +- **Auto-invalidation.** The CSR is cached per `GraphIndex` and revalidated against the index `version` and `graph.mode` — O(1) per access. Replacing `nodes`/`edges` arrays, length changes, and all `add*`/`delete*`/`update*` API mutations are detected automatically. +- **`invalidateIndex(graph)`** is only needed after *direct in-place field mutation* (e.g. `edge.sourceId = 'x'`, `node.parentId = 'y'`), which is not O(1)-detectable. The same staleness contract covers both the index and the CSR. +- Algorithm results are differential-tested against graphology on seeded random graphs; see [./benchmarks.md](./benchmarks.md) for throughput comparisons. From 51b06ed9da48e5cfc917f1f6d36d8077fd9fef60 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:48:25 -0400 Subject: [PATCH 13/15] perf(queries): O(1) getDegree via cached non-directed self-loop counts (148ms -> 9.7ms sweep at 100k/300k, parity with ngraph/graphology) --- bench/degree-sweep.ts | 74 +++++++++++++++++++++++++++++++++++++++++++ src/queries.ts | 69 +++++++++++++++++++++++++++++++--------- 2 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 bench/degree-sweep.ts diff --git a/bench/degree-sweep.ts b/bench/degree-sweep.ts new file mode 100644 index 0000000..39e2e64 --- /dev/null +++ b/bench/degree-sweep.ts @@ -0,0 +1,74 @@ +// Quick before/after check for the degree-sweep benchmark cell. +// Run: pnpm tsx bench/degree-sweep.ts +import { createGraph } from '../src'; +import { getDegree } from '../src/queries'; +import GraphologyGraph from 'graphology'; +import ngraphCreate from 'ngraph.graph'; + +const N = 100_000; +const M = 300_000; + +function mulberry32(seed: number): () => number { + let s = seed | 0; + return () => { + s = (s + 0x6d2b79f5) | 0; + let t = Math.imul(s ^ (s >>> 15), 1 | s); + t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; +} + +const rng = mulberry32(42); +const edges = Array.from({ length: M }, (_, i) => ({ + id: `e${i}`, + sourceId: `n${Math.floor(rng() * N)}`, + targetId: `n${Math.floor(rng() * N)}`, +})); + +const ours = createGraph({ + nodes: Array.from({ length: N }, (_, i) => ({ id: `n${i}` })), + edges, +}); + +const gly = new GraphologyGraph({ multi: true, type: 'directed' }); +for (let i = 0; i < N; i++) gly.addNode(`n${i}`); +for (const e of edges) gly.addEdgeWithKey(e.id, e.sourceId, e.targetId); + +const ng = ngraphCreate(); +for (let i = 0; i < N; i++) ng.addNode(`n${i}`); +for (const e of edges) ng.addLink(e.sourceId, e.targetId); + +function median(samples: number[]): number { + const sorted = [...samples].sort((a, b) => a - b); + return sorted[Math.floor(sorted.length / 2)]; +} + +function bench(label: string, fn: () => number): void { + const samples: number[] = []; + let total = 0; + for (let run = 0; run < 7; run++) { + const start = performance.now(); + total = fn(); + samples.push(performance.now() - start); + } + console.log(`${label}: ${median(samples).toFixed(2)} ms (sum=${total})`); +} + +bench('ours ', () => { + let total = 0; + for (const node of ours.nodes) total += getDegree(ours, node.id); + return total; +}); +bench('graphology', () => { + let total = 0; + gly.forEachNode((node) => void (total += gly.degree(node))); + return total; +}); +bench('ngraph ', () => { + let total = 0; + ng.forEachNode((node) => { + total += ng.getLinks(node.id)?.size ?? 0; + return false; + }); + return total; +}); diff --git a/src/queries.ts b/src/queries.ts index 0aa97c7..5b02d70 100644 --- a/src/queries.ts +++ b/src/queries.ts @@ -1,7 +1,50 @@ import type { Graph, GraphNode, GraphEdge, GraphPort } from './types'; -import { getIndex } from './indexing'; +import { getIndex, type GraphIndex } from './indexing'; import { getEdgeMode } from './mode'; +// Non-directed self-loop counts per node, cached per index version + graph +// mode (mode affects edges without a per-edge override) — the same +// revalidation scheme as the CSR snapshot. This is what makes getDegree O(1): +// degree = |out| + |in| − (non-directed self-loops), exactly, because a +// non-self-loop edge appears in exactly one of a node's two lists and a +// self-loop in both. +interface SelfLoopCacheEntry { + version: number; + mode: Graph['mode']; + counts: Map; +} + +const nonDirectedSelfLoopCache = new WeakMap(); + +function getNonDirectedSelfLoopCounts( + graph: Graph, + idx: GraphIndex, +): Map { + const cached = nonDirectedSelfLoopCache.get(idx); + if ( + cached && + cached.version === idx.version && + cached.mode === graph.mode + ) { + return cached.counts; + } + const counts = new Map(); + for (const edge of graph.edges) { + if ( + edge.sourceId === edge.targetId && + getEdgeMode(graph, edge) !== 'directed' + ) { + counts.set(edge.sourceId, (counts.get(edge.sourceId) ?? 0) + 1); + } + } + nonDirectedSelfLoopCache.set(idx, { + version: idx.version, + mode: graph.mode, + counts, + }); + return counts; +} + // --- Edge queries --- /** @@ -260,20 +303,16 @@ export function getNeighbors(graph: Graph, nodeId: string): GraphNode[] */ export function getDegree(graph: Graph, nodeId: string): number { const idx = getIndex(graph); - const out = idx.outEdges.get(nodeId) ?? []; - const inE = idx.inEdges.get(nodeId) ?? []; - let degree = 0; - const countedNonDirected = new Set(); - for (const eid of [...out, ...inE]) { - const e = graph.edges[idx.edgeById.get(eid)!]; - if (getEdgeMode(graph, e) === 'directed') { - degree++; // a directed self-loop appears in both lists → counts twice - } else if (!countedNonDirected.has(eid)) { - countedNonDirected.add(eid); - degree++; - } - } - return degree; + // O(1) per call (amortized): an incident non-self-loop edge contributes + // exactly one entry across the two lists regardless of mode, a directed + // self-loop both entries (counts twice, intended), and a non-directed + // self-loop both entries but should count once — subtract the cached count. + const out = idx.outEdges.get(nodeId); + const inE = idx.inEdges.get(nodeId); + const selfLoops = getNonDirectedSelfLoopCounts(graph, idx); + return ( + (out?.length ?? 0) + (inE?.length ?? 0) - (selfLoops.get(nodeId) ?? 0) + ); } /** From 0e5982a0662d72a7cff89e1e73d8d4023f98aa2d Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 20:51:58 -0400 Subject: [PATCH 14/15] feat(xyflow): emit labels where renderers read them (edge.label top-level, node data.label); read both back --- .changeset/calm-degree-sweep.md | 5 ++++ .changeset/true-label-spots.md | 5 ++++ docs/react-flow-elk-pipeline.md | 7 +++--- src/formats/xyflow/index.ts | 20 +++++++++++---- tests/formats/xyflow.test.ts | 43 +++++++++++++++++++++++++++++++-- 5 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 .changeset/calm-degree-sweep.md create mode 100644 .changeset/true-label-spots.md diff --git a/.changeset/calm-degree-sweep.md b/.changeset/calm-degree-sweep.md new file mode 100644 index 0000000..176f739 --- /dev/null +++ b/.changeset/calm-degree-sweep.md @@ -0,0 +1,5 @@ +--- +'@statelyai/graph': patch +--- + +`getDegree` is now O(1) per call: `|out| + |in|` corrected by a cached per-node count of non-directed self-loops (revalidated by index version + graph mode, like the CSR snapshot). A full degree sweep over a 100k-node/300k-edge graph drops from ~148 ms to ~10 ms — at parity with ngraph and graphology, which was the one benchmark cell this library lost across the board. diff --git a/.changeset/true-label-spots.md b/.changeset/true-label-spots.md new file mode 100644 index 0000000..5e6449e --- /dev/null +++ b/.changeset/true-label-spots.md @@ -0,0 +1,5 @@ +--- +'@statelyai/graph': minor +--- + +xyflow: labels now land where the renderers actually read them. `toXYFlow` emits edge labels as the top-level `edge.label` (the prop React Flow / Svelte Flow render — previously the label went to `edge.data.label`, which built-in edges ignore) and node labels as `data.label` (what React Flow's default node renders). `fromXYFlow` reads both spots back for external React Flow input, and full-fidelity round-tripping via the `__statelyai` metadata is unchanged. If you relied on `edge.data.label` in `toXYFlow` output, read `edge.label` instead. diff --git a/docs/react-flow-elk-pipeline.md b/docs/react-flow-elk-pipeline.md index e6d72ee..684e54b 100644 --- a/docs/react-flow-elk-pipeline.md +++ b/docs/react-flow-elk-pipeline.md @@ -75,9 +75,10 @@ express natively (label, color, ports, weight, …) rides along under a reserved Two render-side notes: -- React Flow renders the *top-level* `edge.label`, but `toXYFlow` stores the - label at `edge.data.label`. Lift it if you want built-in edge labels: - `flow.edges.map((e) => ({ ...e, label: (e.data as any)?.label }))`. +- Labels land where the renderers read them: edge labels on the *top-level* + `edge.label` (what React Flow's built-in edges render) and node labels on + `data.label` (what the default node renders). `fromXYFlow` reads both spots + back, so external React Flow objects import cleanly too. - `node.shape` becomes React Flow's `type`. Only set `shape` to values you've registered in `nodeTypes`, or React Flow falls back to the default node. diff --git a/src/formats/xyflow/index.ts b/src/formats/xyflow/index.ts index da2cca3..74e2f52 100644 --- a/src/formats/xyflow/index.ts +++ b/src/formats/xyflow/index.ts @@ -8,10 +8,14 @@ export type XYFlowNode< TNodeData extends Record = Record, > = NodeBase; -/** xyflow Edge — re-exported from `@xyflow/system`. */ +/** + * xyflow Edge — `EdgeBase` from `@xyflow/system` plus the top-level `label` + * that React Flow / Svelte Flow actually render (it's a renderer prop, so + * `EdgeBase` itself doesn't declare it). + */ export type XYFlowEdge< TEdgeData extends Record = Record, -> = EdgeBase; +> = EdgeBase & { label?: string }; export interface XYFlow< TNodeData extends Record = Record, @@ -152,6 +156,8 @@ export function toXYFlow(graph: VisualGraph): XYFlow { }), }; if (n.parentId) node.parentId = n.parentId; + // React Flow's built-in nodes render `data.label` + if (n.label) node.data.label = n.label; if (n.shape) node.type = n.shape; if (n.width !== undefined) node.width = n.width; if (n.height !== undefined) node.height = n.height; @@ -180,7 +186,9 @@ export function toXYFlow(graph: VisualGraph): XYFlow { height: e.height, }, }); - if (e.label) edge.data.label = e.label; + // Top-level `label` is what React Flow / Svelte Flow render for edges + // (their built-in edge components ignore `data.label`) + if (e.label) edge.label = e.label; return edge; }), }; @@ -241,7 +249,8 @@ export function fromXYFlow(flow: XYFlow): VisualGraph { label: metadata && 'label' in metadata ? (metadata.label as string | null) - : '', + : ((n.data as Record | undefined)?.label?.toString() ?? + ''), data: readUserData(n.data), x: n.position.x, y: n.position.y, @@ -267,7 +276,8 @@ export function fromXYFlow(flow: XYFlow): VisualGraph { label: metadata && 'label' in metadata ? (metadata.label as string | null) - : ((e.data as Record | undefined)?.label?.toString() ?? + : (e.label ?? + (e.data as Record | undefined)?.label?.toString() ?? ''), ...(e.sourceHandle && { sourcePort: e.sourceHandle }), ...(e.targetHandle && { targetPort: e.targetHandle }), diff --git a/tests/formats/xyflow.test.ts b/tests/formats/xyflow.test.ts index a5ce9fe..49f5709 100644 --- a/tests/formats/xyflow.test.ts +++ b/tests/formats/xyflow.test.ts @@ -81,8 +81,47 @@ describe('xyflow', () => { expect(flow.edges[0].source).toBe('a'); expect(flow.edges[0].target).toBe('b'); - // EdgeBase has no label field; label is stored in data - expect((flow.edges[0].data as any)?.label).toBe('link'); + // Top-level label — what React Flow / Svelte Flow render for edges + expect(flow.edges[0].label).toBe('link'); + }); + + it('lifts labels to the spots the renderers read (edge.label, node data.label)', () => { + const flow = toXYFlow({ + ...sampleGraph, + nodes: [ + { ...sampleGraph.nodes[0], id: 'a', label: 'Node A' }, + { + ...sampleGraph.nodes[1], + id: 'b', + label: '', + data: { label: 'user label' }, + }, + ], + edges: [ + { + ...sampleGraph.edges[0], + id: 'e1', + sourceId: 'a', + targetId: 'b', + label: 'go', + }, + ], + }); + expect(flow.nodes[0].data.label).toBe('Node A'); + // Untouched user data.label passes through when the node has no label + expect(flow.nodes[1].data.label).toBe('user label'); + expect(flow.edges[0].label).toBe('go'); + + // External React Flow input (no metadata): both spots are read back + const parsed = fromXYFlow({ + nodes: [ + { id: 'x', position: { x: 0, y: 0 }, data: { label: 'X' } }, + { id: 'y', position: { x: 10, y: 0 }, data: {} }, + ], + edges: [{ id: 'e', source: 'x', target: 'y', label: 'edge label' }], + }); + expect(parsed.nodes[0].label).toBe('X'); + expect(parsed.edges[0].label).toBe('edge label'); }); it('fromXYFlow() parses nodes and edges', () => { From 079491d24efca7485da6068286fc8dae3d75ee94 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Thu, 11 Jun 2026 21:05:51 -0400 Subject: [PATCH 15/15] =?UTF-8?q?docs(benchmarks):=20refresh=20from=202026?= =?UTF-8?q?-06-12=20run=20=E2=80=94=20degree=20sweep=20at=20parity=20after?= =?UTF-8?q?=20O(1)=20getDegree?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bench/compare/results/2026-06-12.json | 3119 ++++++++++++++++++++ bench/compare/results/2026-06-12.md | 127 + docs/benchmarks.md | 174 +- pnpm-lock.yaml | 3831 +++++++++++++------------ 4 files changed, 5390 insertions(+), 1861 deletions(-) create mode 100644 bench/compare/results/2026-06-12.json create mode 100644 bench/compare/results/2026-06-12.md diff --git a/bench/compare/results/2026-06-12.json b/bench/compare/results/2026-06-12.json new file mode 100644 index 0000000..149c54c --- /dev/null +++ b/bench/compare/results/2026-06-12.json @@ -0,0 +1,3119 @@ +{ + "cells": [ + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 1000, + "workload": "build", + "medianMs": 1.2707090000000107, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 1000, + "workload": "bfs", + "medianMs": 0.04041699999999082, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 1000, + "workload": "sssp", + "medianMs": 0.035459000000003016, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 1000, + "workload": "pagerank", + "medianMs": 0.7173339999999939, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 1000, + "workload": "components", + "medianMs": 0.06316699999996445, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 1000, + "workload": "betweenness", + "medianMs": 44.237458999999944, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.07074999999986176, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 1000, + "workload": "build", + "medianMs": 5.650250000000142, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "random", + "size": 1000, + "workload": "bfs", + "medianMs": 0.2294170000000122, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 1000, + "workload": "sssp", + "medianMs": 0.11141699999984667, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 1000, + "workload": "pagerank", + "medianMs": 1.5618749999998727, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 1000, + "workload": "components", + "medianMs": 0.46908300000018244, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 1000, + "workload": "betweenness", + "medianMs": 97.12187500000005, + "samples": 13 + }, + { + "lib": "graphology", + "shape": "random", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.03312499999992724, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 1000, + "workload": "build", + "medianMs": 2.216667000000143, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 1000, + "workload": "bfs", + "medianMs": 0.30966699999999037, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 1000, + "workload": "sssp", + "medianMs": 0.3600409999999101, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 1000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "random", + "size": 1000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "random", + "size": 1000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "random", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.03304099999968457, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 1000, + "workload": "build", + "medianMs": 16.44866699999966, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 1000, + "workload": "bfs", + "medianMs": 0.26470900000003894, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 1000, + "workload": "sssp", + "medianMs": 2.8132909999999356, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 1000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 1000, + "workload": "components", + "medianMs": 1.0522920000003069, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 1000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.9633749999998145, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 1000, + "workload": "build", + "medianMs": 40.227542000000085, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 1000, + "workload": "bfs", + "medianMs": 17.182749999999942, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 1000, + "workload": "sssp", + "medianMs": 25.802833000000646, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 1000, + "workload": "pagerank", + "medianMs": 20.118375000000015, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 1000, + "workload": "components", + "medianMs": 38.219084000000294, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 1000, + "workload": "betweenness", + "medianMs": 863.9110000000001, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 3.462290999999823, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 1000, + "workload": "build", + "medianMs": 1.0015830000011192, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 1000, + "workload": "bfs", + "medianMs": 0.0009579999987181509, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 1000, + "workload": "sssp", + "medianMs": 0.008917000001019915, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 1000, + "workload": "pagerank", + "medianMs": 0.8343330000006972, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 1000, + "workload": "components", + "medianMs": 0.022458999999798834, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 1000, + "workload": "betweenness", + "medianMs": 2.7259589999994205, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.06424999999944703, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 1000, + "workload": "build", + "medianMs": 3.2983339999991586, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 1000, + "workload": "bfs", + "medianMs": 0.00020899999981338624, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 1000, + "workload": "sssp", + "medianMs": 0.0011670000003505265, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 1000, + "workload": "pagerank", + "medianMs": 1.037000000000262, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 1000, + "workload": "components", + "medianMs": 0.5048750000005384, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 1000, + "workload": "betweenness", + "medianMs": 4.21966699999939, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.04883299999892188, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 1000, + "workload": "build", + "medianMs": 1.6316249999999854, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 1000, + "workload": "bfs", + "medianMs": 0.008832999999867752, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 1000, + "workload": "sssp", + "medianMs": 0.009582999999111053, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 1000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 1000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 1000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.10020900000017718, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 1000, + "workload": "build", + "medianMs": 12.561875000001237, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 1000, + "workload": "bfs", + "medianMs": 0.0001250000004802132, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 1000, + "workload": "sssp", + "medianMs": 1.465583000001061, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 1000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 1000, + "workload": "components", + "medianMs": 0.47891600000002654, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 1000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 1.1040830000001733, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 1000, + "workload": "build", + "medianMs": 27.708541999998488, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 1000, + "workload": "bfs", + "medianMs": 1.0294580000008864, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 1000, + "workload": "sssp", + "medianMs": 4.158916999998837, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 1000, + "workload": "pagerank", + "medianMs": 28.251749999999447, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 1000, + "workload": "components", + "medianMs": 37.81787499999882, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 1000, + "workload": "betweenness", + "medianMs": 156.15637500000048, + "samples": 10 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 3.0650839999998425, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 1000, + "workload": "build", + "medianMs": 0.8757499999992433, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 1000, + "workload": "bfs", + "medianMs": 0.025708000001031905, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 1000, + "workload": "sssp", + "medianMs": 0.209208000000217, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 1000, + "workload": "pagerank", + "medianMs": 0.541125000001557, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 1000, + "workload": "components", + "medianMs": 0.011000000000422006, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 1000, + "workload": "betweenness", + "medianMs": 3.720708000000741, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.056375000000116415, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 1000, + "workload": "build", + "medianMs": 1.9546669999999722, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 1000, + "workload": "bfs", + "medianMs": 0.16749999999956344, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 1000, + "workload": "sssp", + "medianMs": 0.9567499999993743, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 1000, + "workload": "pagerank", + "medianMs": 0.7950830000008864, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 1000, + "workload": "components", + "medianMs": 0.23862499999995634, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 1000, + "workload": "betweenness", + "medianMs": 18.978124999999636, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.052416999998968095, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 1000, + "workload": "build", + "medianMs": 1.31829099999959, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 1000, + "workload": "bfs", + "medianMs": 0.17891700000109267, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 1000, + "workload": "sssp", + "medianMs": 0.3347910000011325, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 1000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 1000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 1000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.030750000001717126, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 1000, + "workload": "build", + "medianMs": 8.974915999999212, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 1000, + "workload": "bfs", + "medianMs": 0.0800840000010794, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 1000, + "workload": "sssp", + "medianMs": 2.4527500000003783, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 1000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 1000, + "workload": "components", + "medianMs": 0.2901250000031723, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 1000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.24962500000037835, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 1000, + "workload": "build", + "medianMs": 23.38091600000189, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 1000, + "workload": "bfs", + "medianMs": 9.794000000001688, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 1000, + "workload": "sssp", + "medianMs": 15.043208999999479, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 1000, + "workload": "pagerank", + "medianMs": 30.957041999998182, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 1000, + "workload": "components", + "medianMs": 25.019165999998222, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 1000, + "workload": "betweenness", + "medianMs": 299.97899999999936, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 2.098999999998341, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 1000, + "workload": "build", + "medianMs": 0.8185409999969124, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 1000, + "workload": "bfs", + "medianMs": 0.02358299999832525, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 1000, + "workload": "sssp", + "medianMs": 0.1415420000012091, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 1000, + "workload": "pagerank", + "medianMs": 0.5439580000020214, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 1000, + "workload": "components", + "medianMs": 0.016666999999870313, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 1000, + "workload": "betweenness", + "medianMs": 16.12474999999904, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.04799999999886495, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 1000, + "workload": "build", + "medianMs": 2.8440000000009604, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 1000, + "workload": "bfs", + "medianMs": 0.16274999999950523, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 1000, + "workload": "sssp", + "medianMs": 0.6248749999977008, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 1000, + "workload": "pagerank", + "medianMs": 0.9293330000000424, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 1000, + "workload": "components", + "medianMs": 0.4361250000001746, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 1000, + "workload": "betweenness", + "medianMs": 36.313624999998865, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.04370800000106101, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 1000, + "workload": "build", + "medianMs": 1.7694999999985157, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 1000, + "workload": "bfs", + "medianMs": 0.2504579999986163, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 1000, + "workload": "sssp", + "medianMs": 0.39112500000192085, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 1000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 1000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 1000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.0865830000002461, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 1000, + "workload": "build", + "medianMs": 11.584000000002561, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 1000, + "workload": "bfs", + "medianMs": 0.08558300000004238, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 1000, + "workload": "sssp", + "medianMs": 2.525167000003421, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 1000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 1000, + "workload": "components", + "medianMs": 0.30883300000277814, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 1000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 0.82524999999805, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 1000, + "workload": "build", + "medianMs": 21.611958000001323, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 1000, + "workload": "bfs", + "medianMs": 12.333875000000262, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 1000, + "workload": "sssp", + "medianMs": 20.613083000000188, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 1000, + "workload": "pagerank", + "medianMs": 35.065582999999606, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 1000, + "workload": "components", + "medianMs": 37.32016699999804, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 1000, + "workload": "betweenness", + "medianMs": 442.55458400000134, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 1000, + "workload": "degreeSweep", + "medianMs": 3.3017500000023574, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 10000, + "workload": "build", + "medianMs": 9.158542000001034, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 10000, + "workload": "bfs", + "medianMs": 0.41308399999979883, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 10000, + "workload": "sssp", + "medianMs": 0.16516600000250037, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 10000, + "workload": "pagerank", + "medianMs": 4.885833000000275, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 10000, + "workload": "components", + "medianMs": 0.35154099999999744, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.46779199999946286, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 10000, + "workload": "build", + "medianMs": 41.80079200000182, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "random", + "size": 10000, + "workload": "bfs", + "medianMs": 5.640292000000045, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 10000, + "workload": "sssp", + "medianMs": 0.3023749999993015, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 10000, + "workload": "pagerank", + "medianMs": 10.708416999998008, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 10000, + "workload": "components", + "medianMs": 9.963583000000654, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.41729100000156905, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 10000, + "workload": "build", + "medianMs": 16.00366700000086, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 10000, + "workload": "bfs", + "medianMs": 3.7628750000003492, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 10000, + "workload": "sssp", + "medianMs": 3.734582999997656, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 10000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "random", + "size": 10000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "random", + "size": 10000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "random", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.3581659999981639, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 10000, + "workload": "build", + "medianMs": 122.17204100000163, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 10000, + "workload": "bfs", + "medianMs": 1.9799999999995634, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 10000, + "workload": "sssp", + "medianMs": 23.676292000000103, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 10000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 10000, + "workload": "components", + "medianMs": null, + "skipped": "error", + "error": "Maximum call stack size exceeded" + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 10000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 19.695040999999037, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 10000, + "workload": "build", + "medianMs": 328.05612499999916, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 10000, + "workload": "bfs", + "medianMs": 228.2977920000012, + "samples": 7 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 10000, + "workload": "sssp", + "medianMs": 332.9368749999994, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 10000, + "workload": "pagerank", + "medianMs": 7681.613875000003, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 10000, + "workload": "components", + "medianMs": 646.7514579999988, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 63.12816700000258, + "samples": 15 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 10000, + "workload": "build", + "medianMs": 13.405209000004106, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 10000, + "workload": "bfs", + "medianMs": 0.007417000000714324, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 10000, + "workload": "sssp", + "medianMs": 0.0715829999971902, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 10000, + "workload": "pagerank", + "medianMs": 5.9106250000040745, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 10000, + "workload": "components", + "medianMs": 0.2353750000038417, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.5354999999981374, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 10000, + "workload": "build", + "medianMs": 52.95608300001186, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 10000, + "workload": "bfs", + "medianMs": 0.0001250000059371814, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 10000, + "workload": "sssp", + "medianMs": 0.0009580000041751191, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 10000, + "workload": "pagerank", + "medianMs": 10.110042000000249, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 10000, + "workload": "components", + "medianMs": 12.298625000010361, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.5014159999991534, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 10000, + "workload": "build", + "medianMs": 21.87304099999892, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 10000, + "workload": "bfs", + "medianMs": 0.04554199999256525, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 10000, + "workload": "sssp", + "medianMs": 0.012124999993829988, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 10000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 10000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 10000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.6372910000063712, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 10000, + "workload": "build", + "medianMs": 150.54950000000827, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 10000, + "workload": "bfs", + "medianMs": 0.00008399999933317304, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 10000, + "workload": "sssp", + "medianMs": 6.540666999993846, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 10000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 10000, + "workload": "components", + "medianMs": 11.702166999995825, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 10000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 53.59475000000384, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 10000, + "workload": "build", + "medianMs": 307.5065409999952, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 10000, + "workload": "bfs", + "medianMs": 28.25558299999102, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 10000, + "workload": "sssp", + "medianMs": 49.234874999994645, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 10000, + "workload": "pagerank", + "medianMs": 11694.479584, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 10000, + "workload": "components", + "medianMs": 523.158208000008, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 57.36129100000835, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 10000, + "workload": "build", + "medianMs": 4.805292000004556, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 10000, + "workload": "bfs", + "medianMs": 0.2117500000022119, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 10000, + "workload": "sssp", + "medianMs": 0.7126659999921685, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 10000, + "workload": "pagerank", + "medianMs": 5.543540999991819, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 10000, + "workload": "components", + "medianMs": 0.10195800001383759, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.4737499999901047, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 10000, + "workload": "build", + "medianMs": 23.722959000006085, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 10000, + "workload": "bfs", + "medianMs": 2.0574170000036247, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 10000, + "workload": "sssp", + "medianMs": 15.618207999999868, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 10000, + "workload": "pagerank", + "medianMs": 5.284125000005588, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 10000, + "workload": "components", + "medianMs": 3.1083330000110436, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.4237089999951422, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 10000, + "workload": "build", + "medianMs": 8.895000000004075, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 10000, + "workload": "bfs", + "medianMs": 1.7672919999895385, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 10000, + "workload": "sssp", + "medianMs": 3.1963329999998678, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 10000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 10000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 10000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.32995800000207964, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 10000, + "workload": "build", + "medianMs": 57.879792000007, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 10000, + "workload": "bfs", + "medianMs": 1.4753749999945285, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 10000, + "workload": "sssp", + "medianMs": 18.543208000002778, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 10000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 10000, + "workload": "components", + "medianMs": null, + "skipped": "error", + "error": "Maximum call stack size exceeded" + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 10000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 11.155458000008366, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 10000, + "workload": "build", + "medianMs": 234.89070800000627, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 10000, + "workload": "bfs", + "medianMs": 125.2925830000022, + "samples": 12 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 10000, + "workload": "sssp", + "medianMs": 206.231958999997, + "samples": 8 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 10000, + "workload": "pagerank", + "medianMs": 6530.992792000005, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 10000, + "workload": "components", + "medianMs": 340.3179999999993, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 29.23970800000825, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 10000, + "workload": "build", + "medianMs": 5.390207999997074, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 10000, + "workload": "bfs", + "medianMs": 0.3275409999769181, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 10000, + "workload": "sssp", + "medianMs": 1.6407499999913853, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 10000, + "workload": "pagerank", + "medianMs": 6.9589170000108425, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 10000, + "workload": "components", + "medianMs": 0.33541699999477714, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.5383750000037253, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 10000, + "workload": "build", + "medianMs": 45.61179200001061, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 10000, + "workload": "bfs", + "medianMs": 2.8015420000010636, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 10000, + "workload": "sssp", + "medianMs": 15.058042000018759, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 10000, + "workload": "pagerank", + "medianMs": 8.041709000011906, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 10000, + "workload": "components", + "medianMs": 7.470499999995809, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.4244590000016615, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 10000, + "workload": "build", + "medianMs": 10.967708000011044, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 10000, + "workload": "bfs", + "medianMs": 2.476334000006318, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 10000, + "workload": "sssp", + "medianMs": 4.85341700000572, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 10000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 10000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 10000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 0.3640409999934491, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 10000, + "workload": "build", + "medianMs": 87.57274999999208, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 10000, + "workload": "bfs", + "medianMs": 1.3779579999973066, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 10000, + "workload": "sssp", + "medianMs": 22.595375000004424, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 10000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 10000, + "workload": "components", + "medianMs": null, + "skipped": "error", + "error": "Maximum call stack size exceeded" + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 10000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 16.695584000000963, + "samples": 25 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 10000, + "workload": "build", + "medianMs": 319.07808400000795, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 10000, + "workload": "bfs", + "medianMs": 163.21762499999022, + "samples": 9 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 10000, + "workload": "sssp", + "medianMs": 290.62100000001374, + "samples": 6 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 10000, + "workload": "pagerank", + "medianMs": 7774.589500000002, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 10000, + "workload": "components", + "medianMs": 497.6229999999923, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 10000, + "workload": "degreeSweep", + "medianMs": 42.692041000002064, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 100000, + "workload": "build", + "medianMs": 63.421082999993814, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 100000, + "workload": "bfs", + "medianMs": 5.155875000025844, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 100000, + "workload": "sssp", + "medianMs": 0.9318339999881573, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 100000, + "workload": "pagerank", + "medianMs": 64.23304200000712, + "samples": 22 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 100000, + "workload": "components", + "medianMs": 5.048000000009779, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "random", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 8.923624999995809, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 100000, + "workload": "build", + "medianMs": 934.6533750000235, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "random", + "size": 100000, + "workload": "bfs", + "medianMs": 251.20712500001537, + "samples": 7 + }, + { + "lib": "graphology", + "shape": "random", + "size": 100000, + "workload": "sssp", + "medianMs": 4.62604200001806, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "random", + "size": 100000, + "workload": "pagerank", + "medianMs": 249.0983750000014, + "samples": 6 + }, + { + "lib": "graphology", + "shape": "random", + "size": 100000, + "workload": "components", + "medianMs": 275.49025000000256, + "samples": 6 + }, + { + "lib": "graphology", + "shape": "random", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 6.549582999985432, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 100000, + "workload": "build", + "medianMs": 361.5792499999807, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 100000, + "workload": "bfs", + "medianMs": 118.61204199999338, + "samples": 13 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 100000, + "workload": "sssp", + "medianMs": 272.43479199998546, + "samples": 6 + }, + { + "lib": "ngraph", + "shape": "random", + "size": 100000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "random", + "size": 100000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "random", + "size": 100000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "random", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 8.351292000006652, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 100000, + "workload": "build", + "medianMs": 1943.4581670000043, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 100000, + "workload": "bfs", + "medianMs": 75.68262500001583, + "samples": 20 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 100000, + "workload": "sssp", + "medianMs": 501.37041699999827, + "samples": 5 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 100000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 100000, + "workload": "components", + "medianMs": null, + "skipped": "too-slow" + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 100000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "random", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 430.626333000022, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 100000, + "workload": "build", + "medianMs": 4628.660499999998, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 100000, + "workload": "bfs", + "medianMs": 7196.832624999981, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 100000, + "workload": "sssp", + "medianMs": 6531.00466700003, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 100000, + "workload": "pagerank", + "medianMs": null, + "skipped": "error", + "error": "Invalid array length" + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 100000, + "workload": "components", + "medianMs": 14646.664415999956, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "random", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 866.3942919999827, + "samples": 5 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 100000, + "workload": "build", + "medianMs": 48.29970799997682, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 100000, + "workload": "bfs", + "medianMs": 0.04533300001639873, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 100000, + "workload": "sssp", + "medianMs": 0.625292000011541, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 100000, + "workload": "pagerank", + "medianMs": 86.42658299999312, + "samples": 16 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 100000, + "workload": "components", + "medianMs": 3.499041999981273, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "scaleFree", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 10.794083999993745, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 100000, + "workload": "build", + "medianMs": 731.7704999999842, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 100000, + "workload": "bfs", + "medianMs": 0.00012500002048909664, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 100000, + "workload": "sssp", + "medianMs": 0.0009579999605193734, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 100000, + "workload": "pagerank", + "medianMs": 164.37062499998137, + "samples": 9 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 100000, + "workload": "components", + "medianMs": 297.0496250000433, + "samples": 6 + }, + { + "lib": "graphology", + "shape": "scaleFree", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 11.44979099999182, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 100000, + "workload": "build", + "medianMs": 287.88025000004563, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 100000, + "workload": "bfs", + "medianMs": 0.05679099995177239, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 100000, + "workload": "sssp", + "medianMs": 0.03245800000149757, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 100000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 100000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 100000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "scaleFree", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 4.68583299999591, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 100000, + "workload": "build", + "medianMs": 1347.5440830000443, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 100000, + "workload": "bfs", + "medianMs": 0.00008300004992634058, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 100000, + "workload": "sssp", + "medianMs": 69.10812499996973, + "samples": 21 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 100000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 100000, + "workload": "components", + "medianMs": null, + "skipped": "error", + "error": "Maximum call stack size exceeded" + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 100000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "scaleFree", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 524.9107910000021, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 100000, + "workload": "build", + "medianMs": 3469.1504160000477, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 100000, + "workload": "bfs", + "medianMs": 305.740541999985, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 100000, + "workload": "sssp", + "medianMs": 649.5675829999964, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 100000, + "workload": "pagerank", + "medianMs": null, + "skipped": "too-slow" + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 100000, + "workload": "components", + "medianMs": 18133.623167000012, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "scaleFree", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 780.3923749999958, + "samples": 5 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 100000, + "workload": "build", + "medianMs": 38.787833000009414, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 100000, + "workload": "bfs", + "medianMs": 2.2150840000249445, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 100000, + "workload": "sssp", + "medianMs": 20.22204199997941, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 100000, + "workload": "pagerank", + "medianMs": 57.96787499997299, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 100000, + "workload": "components", + "medianMs": 2.103000000002794, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "grid", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 9.262541999982204, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 100000, + "workload": "build", + "medianMs": 348.56662499997765, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 100000, + "workload": "bfs", + "medianMs": 67.20908299996518, + "samples": 21 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 100000, + "workload": "sssp", + "medianMs": 422.1575829999638, + "samples": 5 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 100000, + "workload": "pagerank", + "medianMs": 115.38629100000253, + "samples": 13 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 100000, + "workload": "components", + "medianMs": 79.49566600000253, + "samples": 19 + }, + { + "lib": "graphology", + "shape": "grid", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 9.496749999991152, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 100000, + "workload": "build", + "medianMs": 113.70133400004124, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 100000, + "workload": "bfs", + "medianMs": 30.108333999989554, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 100000, + "workload": "sssp", + "medianMs": 56.977374999958556, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 100000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 100000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 100000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "grid", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 4.056916999979876, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 100000, + "workload": "build", + "medianMs": 840.266500000027, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 100000, + "workload": "bfs", + "medianMs": 61.411125000042375, + "samples": 24 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 100000, + "workload": "sssp", + "medianMs": 335.0945419999771, + "samples": 5 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 100000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 100000, + "workload": "components", + "medianMs": null, + "skipped": "too-slow" + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 100000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "grid", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 206.40925000002608, + "samples": 7 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 100000, + "workload": "build", + "medianMs": 2953.7919999999576, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 100000, + "workload": "bfs", + "medianMs": 1747.272667000012, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 100000, + "workload": "sssp", + "medianMs": 4162.65491599997, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 100000, + "workload": "pagerank", + "medianMs": null, + "skipped": "error", + "error": "Invalid array length" + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 100000, + "workload": "components", + "medianMs": 4378.295792000019, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "grid", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 388.8101659999811, + "samples": 5 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 100000, + "workload": "build", + "medianMs": 56.632624999969266, + "samples": 1 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 100000, + "workload": "bfs", + "medianMs": 3.6164170000702143, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 100000, + "workload": "sssp", + "medianMs": 23.46254099998623, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 100000, + "workload": "pagerank", + "medianMs": 71.6737500000745, + "samples": 19 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 100000, + "workload": "components", + "medianMs": 4.4754160000011325, + "samples": 25 + }, + { + "lib": "@statelyai/graph", + "shape": "layeredDag", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 8.609249999979511, + "samples": 25 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 100000, + "workload": "build", + "medianMs": 527.3985000000102, + "samples": 1 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 100000, + "workload": "bfs", + "medianMs": 63.46704099990893, + "samples": 23 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 100000, + "workload": "sssp", + "medianMs": 369.2390000000596, + "samples": 5 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 100000, + "workload": "pagerank", + "medianMs": 140.67058299994096, + "samples": 11 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 100000, + "workload": "components", + "medianMs": 149.22408299997915, + "samples": 10 + }, + { + "lib": "graphology", + "shape": "layeredDag", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 10.54999999993015, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 100000, + "workload": "build", + "medianMs": 200.7970000000205, + "samples": 1 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 100000, + "workload": "bfs", + "medianMs": 41.05129199998919, + "samples": 25 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 100000, + "workload": "sssp", + "medianMs": 85.28733299998567, + "samples": 18 + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 100000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 100000, + "workload": "components", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 100000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "ngraph", + "shape": "layeredDag", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 7.178000000072643, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 100000, + "workload": "build", + "medianMs": 1232.9260419999482, + "samples": 1 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 100000, + "workload": "bfs", + "medianMs": 57.1902499999851, + "samples": 25 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 100000, + "workload": "sssp", + "medianMs": 383.06441700004507, + "samples": 5 + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 100000, + "workload": "pagerank", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 100000, + "workload": "components", + "medianMs": null, + "skipped": "too-slow" + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 100000, + "workload": "betweenness", + "medianMs": null + }, + { + "lib": "@dagrejs/graphlib", + "shape": "layeredDag", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 311.28570799995214, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 100000, + "workload": "build", + "medianMs": 4908.21883300005, + "samples": 1 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 100000, + "workload": "bfs", + "medianMs": 2341.935291999951, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 100000, + "workload": "sssp", + "medianMs": 5161.978333999985, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 100000, + "workload": "pagerank", + "medianMs": null, + "skipped": "error", + "error": "Invalid array length" + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 100000, + "workload": "components", + "medianMs": 8266.992958000046, + "samples": 5 + }, + { + "lib": "cytoscape (headless)", + "shape": "layeredDag", + "size": 100000, + "workload": "degreeSweep", + "medianMs": 500.6223329999484, + "samples": 5 + } + ] +} \ No newline at end of file diff --git a/bench/compare/results/2026-06-12.md b/bench/compare/results/2026-06-12.md new file mode 100644 index 0000000..e93ff11 --- /dev/null +++ b/bench/compare/results/2026-06-12.md @@ -0,0 +1,127 @@ +# Cross-library benchmark + +- Date: 2026-06-12T01:02:37.434Z +- Machine: Apple M1 Max · 10 cores · node v25.9.0 (darwin/arm64) +- Method: identical seeded edge lists per cell; idiomatic public API per library; median of ≥5 runs (1.5 s budget) after warmup. Bold = fastest; (n.n×) = slower than fastest; — = no equivalent API; >10s = skipped after exceeding 10 s. +- graphlib's `sssp` is full single-source Dijkstra (its only shortest-path API). +- Betweenness capped at n=1,000 (Brandes is O(V·E) for every library). +- Sub-millisecond cells (e.g. scaleFree traversals, which reach few nodes from n0) are dominated by call overhead — treat their ratios as noise. + +## build + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **1.3** | 5.7 (4.4×) | 2.2 (1.7×) | 16.4 (12.9×) | 40.2 (31.7×) | +| scaleFree 1,000 | **1.0** | 3.3 (3.3×) | 1.6 (1.6×) | 12.6 (12.5×) | 27.7 (27.7×) | +| grid 1,000 | **0.88** | 2.0 (2.2×) | 1.3 (1.5×) | 9.0 (10.2×) | 23.4 (26.7×) | +| layeredDag 1,000 | **0.82** | 2.8 (3.5×) | 1.8 (2.2×) | 11.6 (14.2×) | 21.6 (26.4×) | +| random 10,000 | **9.2** | 41.8 (4.6×) | 16.0 (1.7×) | 122 (13.3×) | 328 (35.8×) | +| scaleFree 10,000 | **13.4** | 53.0 (4.0×) | 21.9 (1.6×) | 151 (11.2×) | 308 (22.9×) | +| grid 10,000 | **4.8** | 23.7 (4.9×) | 8.9 (1.9×) | 57.9 (12.0×) | 235 (48.9×) | +| layeredDag 10,000 | **5.4** | 45.6 (8.5×) | 11.0 (2.0×) | 87.6 (16.2×) | 319 (59.2×) | +| random 100,000 | **63.4** | 935 (14.7×) | 362 (5.7×) | 1943 (30.6×) | 4629 (73.0×) | +| scaleFree 100,000 | **48.3** | 732 (15.2×) | 288 (6.0×) | 1348 (27.9×) | 3469 (71.8×) | +| grid 100,000 | **38.8** | 349 (9.0×) | 114 (2.9×) | 840 (21.7×) | 2954 (76.2×) | +| layeredDag 100,000 | **56.6** | 527 (9.3×) | 201 (3.5×) | 1233 (21.8×) | 4908 (86.7×) | + +## bfs + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **0.04** | 0.23 (5.7×) | 0.31 (7.7×) | 0.26 (6.5×) | 17.2 (425.1×) | +| scaleFree 1,000 | 0.00 (7.7×) | 0.00 (1.7×) | 0.01 (70.7×) | **0.00** | 1.0 (8235.7×) | +| grid 1,000 | **0.03** | 0.17 (6.5×) | 0.18 (7.0×) | 0.08 (3.1×) | 9.8 (381.0×) | +| layeredDag 1,000 | **0.02** | 0.16 (6.9×) | 0.25 (10.6×) | 0.09 (3.6×) | 12.3 (523.0×) | +| random 10,000 | **0.41** | 5.6 (13.7×) | 3.8 (9.1×) | 2.0 (4.8×) | 228 (552.7×) | +| scaleFree 10,000 | 0.01 (88.3×) | 0.00 (1.5×) | 0.05 (542.2×) | **0.00** | 28.3 (336376.0×) | +| grid 10,000 | **0.21** | 2.1 (9.7×) | 1.8 (8.3×) | 1.5 (7.0×) | 125 (591.7×) | +| layeredDag 10,000 | **0.33** | 2.8 (8.6×) | 2.5 (7.6×) | 1.4 (4.2×) | 163 (498.3×) | +| random 100,000 | **5.2** | 251 (48.7×) | 119 (23.0×) | 75.7 (14.7×) | 7197 (1395.9×) | +| scaleFree 100,000 | 0.05 (546.2×) | 0.00 (1.5×) | 0.06 (684.2×) | **0.00** | 306 (3683618.8×) | +| grid 100,000 | **2.2** | 67.2 (30.3×) | 30.1 (13.6×) | 61.4 (27.7×) | 1747 (788.8×) | +| layeredDag 100,000 | **3.6** | 63.5 (17.5×) | 41.1 (11.4×) | 57.2 (15.8×) | 2342 (647.6×) | + +## sssp + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **0.04** | 0.11 (3.1×) | 0.36 (10.2×) | 2.8 (79.3×) | 25.8 (727.7×) | +| scaleFree 1,000 | 0.01 (7.6×) | **0.00** | 0.01 (8.2×) | 1.5 (1255.9×) | 4.2 (3563.8×) | +| grid 1,000 | **0.21** | 0.96 (4.6×) | 0.33 (1.6×) | 2.5 (11.7×) | 15.0 (71.9×) | +| layeredDag 1,000 | **0.14** | 0.62 (4.4×) | 0.39 (2.8×) | 2.5 (17.8×) | 20.6 (145.6×) | +| random 10,000 | **0.17** | 0.30 (1.8×) | 3.7 (22.6×) | 23.7 (143.3×) | 333 (2015.8×) | +| scaleFree 10,000 | 0.07 (74.7×) | **0.00** | 0.01 (12.7×) | 6.5 (6827.4×) | 49.2 (51393.4×) | +| grid 10,000 | **0.71** | 15.6 (21.9×) | 3.2 (4.5×) | 18.5 (26.0×) | 206 (289.4×) | +| layeredDag 10,000 | **1.6** | 15.1 (9.2×) | 4.9 (3.0×) | 22.6 (13.8×) | 291 (177.1×) | +| random 100,000 | **0.93** | 4.6 (5.0×) | 272 (292.4×) | 501 (538.0×) | 6531 (7008.8×) | +| scaleFree 100,000 | 0.63 (652.7×) | **0.00** | 0.03 (33.9×) | 69.1 (72137.9×) | 650 (678045.5×) | +| grid 100,000 | **20.2** | 422 (20.9×) | 57.0 (2.8×) | 335 (16.6×) | 4163 (205.8×) | +| layeredDag 100,000 | **23.5** | 369 (15.7×) | 85.3 (3.6×) | 383 (16.3×) | 5162 (220.0×) | + +## pagerank + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **0.72** | 1.6 (2.2×) | — | — | 20.1 (28.0×) | +| scaleFree 1,000 | **0.83** | 1.0 (1.2×) | — | — | 28.3 (33.9×) | +| grid 1,000 | **0.54** | 0.80 (1.5×) | — | — | 31.0 (57.2×) | +| layeredDag 1,000 | **0.54** | 0.93 (1.7×) | — | — | 35.1 (64.5×) | +| random 10,000 | **4.9** | 10.7 (2.2×) | — | — | 7682 (1572.2×) | +| scaleFree 10,000 | **5.9** | 10.1 (1.7×) | — | — | 11694 (1978.6×) | +| grid 10,000 | 5.5 (1.0×) | **5.3** | — | — | 6531 (1236.0×) | +| layeredDag 10,000 | **7.0** | 8.0 (1.2×) | — | — | 7775 (1117.2×) | +| random 100,000 | **64.2** | 249 (3.9×) | — | — | crash | +| scaleFree 100,000 | **86.4** | 164 (1.9×) | — | — | >10s | +| grid 100,000 | **58.0** | 115 (2.0×) | — | — | crash | +| layeredDag 100,000 | **71.7** | 141 (2.0×) | — | — | crash | + +## components + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **0.06** | 0.47 (7.4×) | — | 1.1 (16.7×) | 38.2 (605.0×) | +| scaleFree 1,000 | **0.02** | 0.50 (22.5×) | — | 0.48 (21.3×) | 37.8 (1683.9×) | +| grid 1,000 | **0.01** | 0.24 (21.7×) | — | 0.29 (26.4×) | 25.0 (2274.5×) | +| layeredDag 1,000 | **0.02** | 0.44 (26.2×) | — | 0.31 (18.5×) | 37.3 (2239.2×) | +| random 10,000 | **0.35** | 10.0 (28.3×) | — | crash | 647 (1839.8×) | +| scaleFree 10,000 | **0.24** | 12.3 (52.3×) | — | 11.7 (49.7×) | 523 (2222.7×) | +| grid 10,000 | **0.10** | 3.1 (30.5×) | — | crash | 340 (3337.8×) | +| layeredDag 10,000 | **0.34** | 7.5 (22.3×) | — | crash | 498 (1483.6×) | +| random 100,000 | **5.0** | 275 (54.6×) | — | >10s | 14647 (2901.5×) | +| scaleFree 100,000 | **3.5** | 297 (84.9×) | — | crash | 18134 (5182.5×) | +| grid 100,000 | **2.1** | 79.5 (37.8×) | — | >10s | 4378 (2081.9×) | +| layeredDag 100,000 | **4.5** | 149 (33.3×) | — | >10s | 8267 (1847.2×) | + +## betweenness + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | **44.2** | 97.1 (2.2×) | — | — | 864 (19.5×) | +| scaleFree 1,000 | **2.7** | 4.2 (1.5×) | — | — | 156 (57.3×) | +| grid 1,000 | **3.7** | 19.0 (5.1×) | — | — | 300 (80.6×) | +| layeredDag 1,000 | **16.1** | 36.3 (2.3×) | — | — | 443 (27.4×) | +| random 10,000 | — | — | — | — | — | +| scaleFree 10,000 | — | — | — | — | — | +| grid 10,000 | — | — | — | — | — | +| layeredDag 10,000 | — | — | — | — | — | +| random 100,000 | — | — | — | — | — | +| scaleFree 100,000 | — | — | — | — | — | +| grid 100,000 | — | — | — | — | — | +| layeredDag 100,000 | — | — | — | — | — | + +## degreeSweep + +| graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | +|---|---|---|---|---|---| +| random 1,000 | 0.07 (2.1×) | 0.03 (1.0×) | **0.03** | 0.96 (29.2×) | 3.5 (104.8×) | +| scaleFree 1,000 | 0.06 (1.3×) | **0.05** | 0.10 (2.1×) | 1.1 (22.6×) | 3.1 (62.8×) | +| grid 1,000 | 0.06 (1.8×) | 0.05 (1.7×) | **0.03** | 0.25 (8.1×) | 2.1 (68.3×) | +| layeredDag 1,000 | 0.05 (1.1×) | **0.04** | 0.09 (2.0×) | 0.83 (18.9×) | 3.3 (75.5×) | +| random 10,000 | 0.47 (1.3×) | 0.42 (1.2×) | **0.36** | 19.7 (55.0×) | 63.1 (176.3×) | +| scaleFree 10,000 | 0.54 (1.1×) | **0.50** | 0.64 (1.3×) | 53.6 (106.9×) | 57.4 (114.4×) | +| grid 10,000 | 0.47 (1.4×) | 0.42 (1.3×) | **0.33** | 11.2 (33.8×) | 29.2 (88.6×) | +| layeredDag 10,000 | 0.54 (1.5×) | 0.42 (1.2×) | **0.36** | 16.7 (45.9×) | 42.7 (117.3×) | +| random 100,000 | 8.9 (1.4×) | **6.5** | 8.4 (1.3×) | 431 (65.7×) | 866 (132.3×) | +| scaleFree 100,000 | 10.8 (2.3×) | 11.4 (2.4×) | **4.7** | 525 (112.0×) | 780 (166.5×) | +| grid 100,000 | 9.3 (2.3×) | 9.5 (2.3×) | **4.1** | 206 (50.9×) | 389 (95.8×) | +| layeredDag 100,000 | 8.6 (1.2×) | 10.5 (1.5×) | **7.2** | 311 (43.4×) | 501 (69.7×) | diff --git a/docs/benchmarks.md b/docs/benchmarks.md index 8e45eb5..0b677cc 100644 --- a/docs/benchmarks.md +++ b/docs/benchmarks.md @@ -2,7 +2,7 @@ Cross-library comparison of `@statelyai/graph` against [graphology](https://graphology.github.io/), [ngraph](https://github.com/anvaka/ngraph.graph), [@dagrejs/graphlib](https://github.com/dagrejs/graphlib), and [cytoscape](https://js.cytoscape.org/) (headless) on seven workloads: graph construction, BFS reachability, single-pair shortest path, PageRank, connected components, betweenness centrality, and a full degree sweep. -- **Measured:** 2026-06-11 on an Apple M1 Max (10 cores), Node v25.9.0 (darwin/arm64). Library versions: graphology 0.26, ngraph.graph 20.1 / ngraph.path 1.6, @dagrejs/graphlib 4.0, cytoscape 3.34. +- **Measured:** 2026-06-12 on an Apple M1 Max (10 cores), Node v25.9.0 (darwin/arm64). Library versions: graphology 0.26, ngraph.graph 20.1 / ngraph.path 1.6, @dagrejs/graphlib 4.0, cytoscape 3.34. - **Numbers are medians** (milliseconds) of ≥5 runs after warmup, within a 1.5 s sampling budget per cell. - Machine specifics matter. Reproduce on your own hardware with: @@ -21,18 +21,18 @@ Construct the graph from an identical node/edge list. | graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | |---|---|---|---|---|---| -| random 1,000 | **1.7** | 5.3 (3.2×) | 2.3 (1.4×) | 15.3 (9.2×) | 36.7 (22.2×) | -| scaleFree 1,000 | **1.1** | 3.5 (3.3×) | 1.8 (1.7×) | 12.7 (12.0×) | 27.4 (25.8×) | -| grid 1,000 | **0.84** | 2.0 (2.3×) | 1.3 (1.5×) | 4.3 (5.1×) | 17.2 (20.5×) | -| layeredDag 1,000 | **0.95** | 3.1 (3.3×) | 1.5 (1.6×) | 12.2 (12.8×) | 23.4 (24.7×) | -| random 10,000 | **7.0** | 55.9 (8.0×) | 18.9 (2.7×) | 110 (15.7×) | 407 (58.2×) | -| scaleFree 10,000 | **8.1** | 39.3 (4.8×) | 35.3 (4.3×) | 103 (12.7×) | 411 (50.6×) | -| grid 10,000 | **5.1** | 25.8 (5.1×) | 9.0 (1.8×) | 53.3 (10.5×) | 256 (50.6×) | -| layeredDag 10,000 | **5.6** | 31.6 (5.6×) | 12.8 (2.3×) | 68.4 (12.2×) | 330 (58.9×) | -| random 100,000 | **56.0** | 660 (11.8×) | 291 (5.2×) | 1500 (26.8×) | 4477 (80.0×) | -| scaleFree 100,000 | **96.3** | 651 (6.8×) | 254 (2.6×) | 1525 (15.8×) | 3718 (38.6×) | -| grid 100,000 | **63.0** | 497 (7.9×) | 209 (3.3×) | 848 (13.5×) | 2442 (38.8×) | -| layeredDag 100,000 | **54.2** | 511 (9.4×) | 194 (3.6×) | 1014 (18.7×) | 3419 (63.1×) | +| random 1,000 | **1.3** | 5.7 (4.4×) | 2.2 (1.7×) | 16.4 (12.9×) | 40.2 (31.7×) | +| scaleFree 1,000 | **1.0** | 3.3 (3.3×) | 1.6 (1.6×) | 12.6 (12.5×) | 27.7 (27.7×) | +| grid 1,000 | **0.88** | 2.0 (2.2×) | 1.3 (1.5×) | 9.0 (10.2×) | 23.4 (26.7×) | +| layeredDag 1,000 | **0.82** | 2.8 (3.5×) | 1.8 (2.2×) | 11.6 (14.2×) | 21.6 (26.4×) | +| random 10,000 | **9.2** | 41.8 (4.6×) | 16.0 (1.7×) | 122 (13.3×) | 328 (35.8×) | +| scaleFree 10,000 | **13.4** | 53.0 (4.0×) | 21.9 (1.6×) | 151 (11.2×) | 308 (22.9×) | +| grid 10,000 | **4.8** | 23.7 (4.9×) | 8.9 (1.9×) | 57.9 (12.0×) | 235 (48.9×) | +| layeredDag 10,000 | **5.4** | 45.6 (8.5×) | 11.0 (2.0×) | 87.6 (16.2×) | 319 (59.2×) | +| random 100,000 | **63.4** | 935 (14.7×) | 362 (5.7×) | 1943 (30.6×) | 4629 (73.0×) | +| scaleFree 100,000 | **48.3** | 732 (15.2×) | 288 (6.0×) | 1348 (27.9×) | 3469 (71.8×) | +| grid 100,000 | **38.8** | 349 (9.0×) | 114 (2.9×) | 840 (21.7×) | 2954 (76.2×) | +| layeredDag 100,000 | **56.6** | 527 (9.3×) | 201 (3.5×) | 1233 (21.8×) | 4908 (86.7×) | ## BFS @@ -40,18 +40,18 @@ Full directed reachability sweep from node 0. Libraries without a built-in trave | graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | |---|---|---|---|---|---| -| random 1,000 | **0.04** | 0.23 (6.4×) | 0.32 (8.9×) | 0.24 (6.7×) | 16.4 (457.5×) | -| scaleFree 1,000 | 0.00 (9.7×) | 0.00 (1.7×) | 0.01 (75.7×) | **0.00** | 1.1 (9097.0×) | -| grid 1,000 | **0.03** | 0.17 (6.5×) | 0.16 (6.2×) | 0.08 (3.1×) | 10.8 (415.7×) | -| layeredDag 1,000 | **0.02** | 0.16 (6.8×) | 0.22 (9.1×) | 0.08 (3.1×) | 12.1 (501.7×) | -| random 10,000 | **0.40** | 9.7 (23.9×) | 4.3 (10.6×) | 3.8 (9.5×) | 228 (565.6×) | -| scaleFree 10,000 | 0.01 (71.4×) | 0.00 (2.0×) | 0.05 (539.2×) | **0.00** | 19.6 (232978.2×) | -| grid 10,000 | **0.21** | 2.8 (12.9×) | 3.0 (13.9×) | 1.7 (7.8×) | 123 (579.1×) | -| layeredDag 10,000 | **0.32** | 3.5 (10.8×) | 2.6 (8.1×) | 1.4 (4.2×) | 171 (530.2×) | -| random 100,000 | **4.6** | 126 (27.6×) | 92.7 (20.3×) | 60.5 (13.3×) | 6555 (1438.5×) | -| scaleFree 100,000 | 0.04 (265.8×) | **0.00** | 0.05 (325.6×) | 0.00 (1.3×) | 309 (1863689.7×) | -| grid 100,000 | **2.3** | 86.2 (38.3×) | 41.4 (18.4×) | 58.4 (25.9×) | 1722 (764.7×) | -| layeredDag 100,000 | **3.4** | 81.9 (23.8×) | 33.1 (9.6×) | 46.4 (13.5×) | 2396 (696.8×) | +| random 1,000 | **0.04** | 0.23 (5.7×) | 0.31 (7.7×) | 0.26 (6.5×) | 17.2 (425.1×) | +| scaleFree 1,000 | 0.00 (7.7×) | 0.00 (1.7×) | 0.01 (70.7×) | **0.00** | 1.0 (8235.7×) | +| grid 1,000 | **0.03** | 0.17 (6.5×) | 0.18 (7.0×) | 0.08 (3.1×) | 9.8 (381.0×) | +| layeredDag 1,000 | **0.02** | 0.16 (6.9×) | 0.25 (10.6×) | 0.09 (3.6×) | 12.3 (523.0×) | +| random 10,000 | **0.41** | 5.6 (13.7×) | 3.8 (9.1×) | 2.0 (4.8×) | 228 (552.7×) | +| scaleFree 10,000 | 0.01 (88.3×) | 0.00 (1.5×) | 0.05 (542.2×) | **0.00** | 28.3 (336376.0×) | +| grid 10,000 | **0.21** | 2.1 (9.7×) | 1.8 (8.3×) | 1.5 (7.0×) | 125 (591.7×) | +| layeredDag 10,000 | **0.33** | 2.8 (8.6×) | 2.5 (7.6×) | 1.4 (4.2×) | 163 (498.3×) | +| random 100,000 | **5.2** | 251 (48.7×) | 119 (23.0×) | 75.7 (14.7×) | 7197 (1395.9×) | +| scaleFree 100,000 | 0.05 (546.2×) | 0.00 (1.5×) | 0.06 (684.2×) | **0.00** | 306 (3683618.8×) | +| grid 100,000 | **2.2** | 67.2 (30.3×) | 30.1 (13.6×) | 61.4 (27.7×) | 1747 (788.8×) | +| layeredDag 100,000 | **3.6** | 63.5 (17.5×) | 41.1 (11.4×) | 57.2 (15.8×) | 2342 (647.6×) | The scaleFree rows are sub-millisecond for everyone (few nodes are reachable from node 0); their ratios are noise. @@ -61,18 +61,18 @@ Weighted shortest path from node 0 to node n−1. `@statelyai/graph` uses `getSh | graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | |---|---|---|---|---|---| -| random 1,000 | **0.11** | 0.11 (1.0×) | 0.35 (3.3×) | 2.8 (25.9×) | 22.9 (212.2×) | -| scaleFree 1,000 | 0.01 (5.0×) | **0.00** | 0.01 (8.8×) | 1.5 (1296.7×) | 4.1 (3511.2×) | -| grid 1,000 | **0.22** | 0.96 (4.4×) | 0.30 (1.4×) | 0.95 (4.3×) | 14.8 (67.3×) | -| layeredDag 1,000 | **0.16** | 0.65 (4.1×) | 0.35 (2.2×) | 2.3 (14.8×) | 18.5 (117.0×) | -| random 10,000 | **0.14** | 0.33 (2.3×) | 5.9 (40.7×) | 28.0 (194.6×) | 360 (2496.0×) | -| scaleFree 10,000 | 0.04 (25.8×) | **0.00** | 0.01 (7.1×) | 6.0 (3488.9×) | 42.8 (25033.5×) | -| grid 10,000 | **1.7** | 16.2 (9.4×) | 3.4 (2.0×) | 18.9 (11.1×) | 193 (112.4×) | -| layeredDag 10,000 | **2.0** | 13.0 (6.4×) | 4.3 (2.1×) | 18.8 (9.2×) | 269 (131.9×) | -| random 100,000 | **0.60** | 1.3 (2.2×) | 125 (207.9×) | 431 (715.9×) | 5941 (9861.4×) | -| scaleFree 100,000 | 0.34 (199.2×) | **0.00** | 0.02 (14.2×) | 67.0 (39215.9×) | 637 (372866.4×) | -| grid 100,000 | **27.4** | 383 (14.0×) | 66.0 (2.4×) | 338 (12.3×) | 3710 (135.4×) | -| layeredDag 100,000 | **35.2** | 408 (11.6×) | 68.6 (2.0×) | 386 (11.0×) | 5268 (149.9×) | +| random 1,000 | **0.04** | 0.11 (3.1×) | 0.36 (10.2×) | 2.8 (79.3×) | 25.8 (727.7×) | +| scaleFree 1,000 | 0.01 (7.6×) | **0.00** | 0.01 (8.2×) | 1.5 (1255.9×) | 4.2 (3563.8×) | +| grid 1,000 | **0.21** | 0.96 (4.6×) | 0.33 (1.6×) | 2.5 (11.7×) | 15.0 (71.9×) | +| layeredDag 1,000 | **0.14** | 0.62 (4.4×) | 0.39 (2.8×) | 2.5 (17.8×) | 20.6 (145.6×) | +| random 10,000 | **0.17** | 0.30 (1.8×) | 3.7 (22.6×) | 23.7 (143.3×) | 333 (2015.8×) | +| scaleFree 10,000 | 0.07 (74.7×) | **0.00** | 0.01 (12.7×) | 6.5 (6827.4×) | 49.2 (51393.4×) | +| grid 10,000 | **0.71** | 15.6 (21.9×) | 3.2 (4.5×) | 18.5 (26.0×) | 206 (289.4×) | +| layeredDag 10,000 | **1.6** | 15.1 (9.2×) | 4.9 (3.0×) | 22.6 (13.8×) | 291 (177.1×) | +| random 100,000 | **0.93** | 4.6 (5.0×) | 272 (292.4×) | 501 (538.0×) | 6531 (7008.8×) | +| scaleFree 100,000 | 0.63 (652.7×) | **0.00** | 0.03 (33.9×) | 69.1 (72137.9×) | 650 (678045.5×) | +| grid 100,000 | **20.2** | 422 (20.9×) | 57.0 (2.8×) | 335 (16.6×) | 4163 (205.8×) | +| layeredDag 100,000 | **23.5** | 369 (15.7×) | 85.3 (3.6×) | 383 (16.3×) | 5162 (220.0×) | graphology wins the scaleFree rows; on those graphs node n−1 is typically unreachable from node 0 and the search terminates almost immediately, so the cells are sub-millisecond for both bidirectional implementations. @@ -80,18 +80,18 @@ graphology wins the scaleFree rows; on those graphs node n−1 is typically unre | graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | |---|---|---|---|---|---| -| random 1,000 | **0.62** | 1.1 (1.8×) | — | — | 20.2 (32.4×) | -| scaleFree 1,000 | **0.79** | 1.00 (1.3×) | — | — | 28.1 (35.7×) | -| grid 1,000 | 0.84 (1.6×) | **0.52** | — | — | 30.6 (59.2×) | -| layeredDag 1,000 | **0.54** | 0.93 (1.7×) | — | — | 36.6 (68.4×) | -| random 10,000 | **5.3** | 11.5 (2.2×) | — | — | 7703 (1454.0×) | -| scaleFree 10,000 | **5.1** | 6.4 (1.3×) | — | — | 11869 (2331.2×) | -| grid 10,000 | **5.7** | 6.5 (1.1×) | — | — | 6258 (1105.2×) | -| layeredDag 10,000 | **6.9** | 7.2 (1.0×) | — | — | 7486 (1085.3×) | -| random 100,000 | **54.6** | 190 (3.5×) | — | — | crash | -| scaleFree 100,000 | **95.9** | 157 (1.6×) | — | — | >10s | -| grid 100,000 | 127 (1.1×) | **120** | — | — | crash | -| layeredDag 100,000 | **92.4** | 197 (2.1×) | — | — | crash | +| random 1,000 | **0.72** | 1.6 (2.2×) | — | — | 20.1 (28.0×) | +| scaleFree 1,000 | **0.83** | 1.0 (1.2×) | — | — | 28.3 (33.9×) | +| grid 1,000 | **0.54** | 0.80 (1.5×) | — | — | 31.0 (57.2×) | +| layeredDag 1,000 | **0.54** | 0.93 (1.7×) | — | — | 35.1 (64.5×) | +| random 10,000 | **4.9** | 10.7 (2.2×) | — | — | 7682 (1572.2×) | +| scaleFree 10,000 | **5.9** | 10.1 (1.7×) | — | — | 11694 (1978.6×) | +| grid 10,000 | 5.5 (1.0×) | **5.3** | — | — | 6531 (1236.0×) | +| layeredDag 10,000 | **7.0** | 8.0 (1.2×) | — | — | 7775 (1117.2×) | +| random 100,000 | **64.2** | 249 (3.9×) | — | — | crash | +| scaleFree 100,000 | **86.4** | 164 (1.9×) | — | — | >10s | +| grid 100,000 | **58.0** | 115 (2.0×) | — | — | crash | +| layeredDag 100,000 | **71.7** | 141 (2.0×) | — | — | crash | ngraph and graphlib have no PageRank. cytoscape's PageRank threw `Invalid array length` on three of the four 100k graphs. @@ -99,20 +99,20 @@ ngraph and graphlib have no PageRank. cytoscape's PageRank threw `Invalid array | graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | |---|---|---|---|---|---| -| random 1,000 | **0.02** | 0.42 (17.9×) | — | 1.1 (45.1×) | 37.1 (1577.3×) | -| scaleFree 1,000 | **0.02** | 0.48 (22.7×) | — | 0.69 (33.1×) | 36.0 (1722.1×) | -| grid 1,000 | **0.01** | 0.26 (23.1×) | — | 0.25 (22.9×) | 24.8 (2225.7×) | -| layeredDag 1,000 | **0.02** | 0.46 (30.1×) | — | 0.28 (18.7×) | 38.8 (2562.9×) | -| random 10,000 | **0.35** | 9.6 (27.1×) | — | crash | 526 (1490.3×) | -| scaleFree 10,000 | **0.22** | 12.1 (54.4×) | — | 7.6 (34.2×) | 510 (2293.0×) | -| grid 10,000 | **0.10** | 3.6 (35.0×) | — | crash | 302 (2980.0×) | -| layeredDag 10,000 | **0.30** | 5.9 (19.7×) | — | crash | 464 (1541.3×) | -| random 100,000 | **4.4** | 225 (51.0×) | — | >10s | 13448 (3047.4×) | -| scaleFree 100,000 | **3.3** | 248 (75.0×) | — | crash | 16249 (4906.7×) | -| grid 100,000 | **1.9** | 90.1 (48.3×) | — | >10s | 3921 (2100.9×) | -| layeredDag 100,000 | **3.9** | 196 (50.0×) | — | >10s | 8171 (2086.8×) | - -graphlib's `alg.components` uses recursive DFS and overflowed the call stack (`Maximum call stack size exceeded`) at 10,000 nodes on the random, grid, and layeredDag graphs, and at 100,000 on scaleFree. Where it survived, it was 19–34× slower; the remaining 100k cells were skipped after exceeding 10 s. +| random 1,000 | **0.06** | 0.47 (7.4×) | — | 1.1 (16.7×) | 38.2 (605.0×) | +| scaleFree 1,000 | **0.02** | 0.50 (22.5×) | — | 0.48 (21.3×) | 37.8 (1683.9×) | +| grid 1,000 | **0.01** | 0.24 (21.7×) | — | 0.29 (26.4×) | 25.0 (2274.5×) | +| layeredDag 1,000 | **0.02** | 0.44 (26.2×) | — | 0.31 (18.5×) | 37.3 (2239.2×) | +| random 10,000 | **0.35** | 10.0 (28.3×) | — | crash | 647 (1839.8×) | +| scaleFree 10,000 | **0.24** | 12.3 (52.3×) | — | 11.7 (49.7×) | 523 (2222.7×) | +| grid 10,000 | **0.10** | 3.1 (30.5×) | — | crash | 340 (3337.8×) | +| layeredDag 10,000 | **0.34** | 7.5 (22.3×) | — | crash | 498 (1483.6×) | +| random 100,000 | **5.0** | 275 (54.6×) | — | >10s | 14647 (2901.5×) | +| scaleFree 100,000 | **3.5** | 297 (84.9×) | — | crash | 18134 (5182.5×) | +| grid 100,000 | **2.1** | 79.5 (37.8×) | — | >10s | 4378 (2081.9×) | +| layeredDag 100,000 | **4.5** | 149 (33.3×) | — | >10s | 8267 (1847.2×) | + +graphlib's `alg.components` uses recursive DFS and overflowed the call stack (`Maximum call stack size exceeded`) at 10,000 nodes on the random, grid, and layeredDag graphs, and at 100,000 on scaleFree. Where it survived, it was 17–50× slower; the remaining 100k cells were skipped after exceeding 10 s. ## Betweenness centrality @@ -120,10 +120,10 @@ Run only at n=1,000 — Brandes is O(V·E) for every library, so larger sizes ar | graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | |---|---|---|---|---|---| -| random 1,000 | **42.5** | 80.3 (1.9×) | — | — | 938 (22.1×) | -| scaleFree 1,000 | **2.7** | 4.1 (1.5×) | — | — | 153 (56.6×) | -| grid 1,000 | **3.8** | 18.6 (4.9×) | — | — | 304 (80.8×) | -| layeredDag 1,000 | **15.9** | 35.5 (2.2×) | — | — | 458 (28.8×) | +| random 1,000 | **44.2** | 97.1 (2.2×) | — | — | 864 (19.5×) | +| scaleFree 1,000 | **2.7** | 4.2 (1.5×) | — | — | 156 (57.3×) | +| grid 1,000 | **3.7** | 19.0 (5.1×) | — | — | 300 (80.6×) | +| layeredDag 1,000 | **16.1** | 36.3 (2.3×) | — | — | 443 (27.4×) | ## Degree sweep @@ -131,33 +131,33 @@ Sum the degree of every node via each library's degree API. | graph | @statelyai/graph | graphology | ngraph | @dagrejs/graphlib | cytoscape (headless) | |---|---|---|---|---|---| -| random 1,000 | 0.29 (9.3×) | 0.03 (1.1×) | **0.03** | 0.87 (27.9×) | 3.2 (103.1×) | -| scaleFree 1,000 | 0.20 (4.0×) | **0.05** | 0.10 (1.9×) | 1.1 (21.0×) | 3.2 (61.5×) | -| grid 1,000 | 0.17 (5.3×) | 0.05 (1.5×) | **0.03** | 0.24 (7.5×) | 2.0 (60.8×) | -| layeredDag 1,000 | 0.20 (4.8×) | **0.04** | 0.08 (2.0×) | 0.76 (18.3×) | 3.6 (84.9×) | -| random 10,000 | 4.6 (14.0×) | 0.42 (1.3×) | **0.33** | 22.0 (67.2×) | 54.9 (167.9×) | -| scaleFree 10,000 | 3.2 (9.3×) | 0.40 (1.2×) | **0.34** | 46.3 (135.2×) | 57.0 (166.2×) | -| grid 10,000 | 1.8 (5.1×) | 0.45 (1.3×) | **0.35** | 11.4 (33.0×) | 27.3 (78.6×) | -| layeredDag 10,000 | 2.7 (8.1×) | 0.44 (1.3×) | **0.33** | 16.3 (48.9×) | 39.7 (119.2×) | -| random 100,000 | 104 (21.9×) | 5.2 (1.1×) | **4.7** | 412 (87.1×) | 753 (159.2×) | -| scaleFree 100,000 | 94.2 (21.2×) | 6.2 (1.4×) | **4.4** | 617 (138.7×) | 831 (186.9×) | -| grid 100,000 | 107 (19.2×) | 11.9 (2.1×) | **5.6** | 200 (35.8×) | 335 (59.9×) | -| layeredDag 100,000 | 93.5 (22.9×) | 11.3 (2.8×) | **4.1** | 301 (73.7×) | 634 (155.4×) | +| random 1,000 | 0.07 (2.1×) | 0.03 (1.0×) | **0.03** | 0.96 (29.2×) | 3.5 (104.8×) | +| scaleFree 1,000 | 0.06 (1.3×) | **0.05** | 0.10 (2.1×) | 1.1 (22.6×) | 3.1 (62.8×) | +| grid 1,000 | 0.06 (1.8×) | 0.05 (1.7×) | **0.03** | 0.25 (8.1×) | 2.1 (68.3×) | +| layeredDag 1,000 | 0.05 (1.1×) | **0.04** | 0.09 (2.0×) | 0.83 (18.9×) | 3.3 (75.5×) | +| random 10,000 | 0.47 (1.3×) | 0.42 (1.2×) | **0.36** | 19.7 (55.0×) | 63.1 (176.3×) | +| scaleFree 10,000 | 0.54 (1.1×) | **0.50** | 0.64 (1.3×) | 53.6 (106.9×) | 57.4 (114.4×) | +| grid 10,000 | 0.47 (1.4×) | 0.42 (1.3×) | **0.33** | 11.2 (33.8×) | 29.2 (88.6×) | +| layeredDag 10,000 | 0.54 (1.5×) | 0.42 (1.2×) | **0.36** | 16.7 (45.9×) | 42.7 (117.3×) | +| random 100,000 | 8.9 (1.4×) | **6.5** | 8.4 (1.3×) | 431 (65.7×) | 866 (132.3×) | +| scaleFree 100,000 | 10.8 (2.3×) | 11.4 (2.4×) | **4.7** | 525 (112.0×) | 780 (166.5×) | +| grid 100,000 | 9.3 (2.3×) | 9.5 (2.3×) | **4.1** | 206 (50.9×) | 389 (95.8×) | +| layeredDag 100,000 | 8.6 (1.2×) | 10.5 (1.5×) | **7.2** | 311 (43.4×) | 501 (69.7×) | ## Reading the numbers Where `@statelyai/graph` is fastest: -- **Build** — fastest in every cell, 1.4–80× ahead. Plain-object graphs with lazy WeakMap indexing have very little construction overhead. -- **BFS** — fastest on every non-degenerate row, 4–28× ahead of the next library at 10k–100k. -- **Connected components** — fastest in every cell, 18–75× ahead of graphology (the next-fastest with the API). -- **Single-pair shortest path** — fastest on every row where the search does real work; bidirectional Dijkstra is why `random 100,000` completes in 0.6 ms while full single-source Dijkstra (graphlib) takes 431 ms. -- **PageRank and betweenness** — fastest in most cells, but only by 1.0–3.5× over graphology, and graphology wins `grid` PageRank at 1,000 (0.52 vs 0.84 ms) and 100,000 (120 vs 127 ms). These two are effectively at parity with graphology. +- **Build** — fastest in every cell, 1.5–87× ahead. Plain-object graphs with lazy WeakMap indexing have very little construction overhead. +- **BFS** — fastest on every non-degenerate row, 4–15× ahead of the next library at 10k–100k. +- **Connected components** — fastest in every cell, 7–85× ahead of graphology (the next-fastest with the API). +- **Single-pair shortest path** — fastest on every row where the search does real work; bidirectional Dijkstra is why `random 100,000` completes in 0.93 ms while full single-source Dijkstra (graphlib) takes 501 ms. +- **PageRank and betweenness** — fastest in most cells, but only by 1.2–3.9× over graphology on PageRank (1.5–5.1× on betweenness), and graphology wins `grid` PageRank at 10,000 (5.3 vs 5.5 ms — effectively a tie). PageRank is at rough parity with graphology at small sizes, pulling ahead 2–4× at 100,000. Where it is not fastest: -- **Degree sweep** — ngraph and graphology are consistently faster, by 4–23×. `getDegree` recomputes per call against the edge index, while ngraph/graphology maintain adjacency structures that make per-node degree nearly free. If your workload is dominated by per-node degree queries in a tight loop, this matters. -- **scaleFree traversal/sssp cells** — graphology and graphlib post faster sub-millisecond times. These cells terminate after touching a handful of nodes and are mostly call overhead, but the raw numbers are what they are. +- **Degree sweep** — now at parity rather than a blowout: with `getDegree` made O(1), every cell lands within 1.1–2.3× of the fastest, where the previous run was 4–23× behind. ngraph is still the fastest library in 11 of the 12 degree cells (graphology takes `random 100,000`); `@statelyai/graph` wins no cell outright, though it now edges out graphology in three of the four 100k cells (scaleFree, grid, layeredDag). If per-node degree queries in a tight loop dominate your workload, ngraph remains the fastest choice — but the gap is now small. +- **scaleFree traversal/sssp cells** — graphlib posts the fastest BFS times and graphology the fastest sssp times on the scaleFree rows. These cells terminate after touching a handful of nodes and are mostly call overhead, but the raw numbers are what they are. Other findings worth knowing regardless of which library you pick: @@ -167,7 +167,7 @@ Other findings worth knowing regardless of which library you pick: ## Methodology -Source: [`bench/compare/run.ts`](../bench/compare/run.ts), [`bench/compare/generate.ts`](../bench/compare/generate.ts), [`bench/compare/adapters.ts`](../bench/compare/adapters.ts). Raw output: [`bench/compare/results/2026-06-11.md`](../bench/compare/results/2026-06-11.md) and [`2026-06-11.json`](../bench/compare/results/2026-06-11.json). +Source: [`bench/compare/run.ts`](../bench/compare/run.ts), [`bench/compare/generate.ts`](../bench/compare/generate.ts), [`bench/compare/adapters.ts`](../bench/compare/adapters.ts). Raw output: [`bench/compare/results/2026-06-12.md`](../bench/compare/results/2026-06-12.md) and [`2026-06-12.json`](../bench/compare/results/2026-06-12.json). - **Identical inputs.** Seeded generators emit a neutral edge list (integer endpoints, weights); every library builds from the same list. Simple directed graphs only (no parallel edges or self-loops) — the lowest common denominator across libraries. - **Four shapes × three sizes** (1,000 / 10,000 / 100,000 nodes): diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0aba3e2..90abed8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,660 +1,386 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -devDependencies: - '@changesets/changelog-github': - specifier: ^0.5.2 - version: 0.5.2 - '@changesets/cli': - specifier: ^2.29.8 - version: 2.31.0(@types/node@25.9.3) - '@dagrejs/dagre': - specifier: ^3.0.0 - version: 3.0.0 - '@dagrejs/graphlib': - specifier: ^4.0.1 - version: 4.0.1 - '@hpcc-js/wasm-graphviz': - specifier: ^1.22.0 - version: 1.22.0 - '@types/d3-array': - specifier: ^3.2.2 - version: 3.2.2 - '@types/d3-force': - specifier: ^3.0.10 - version: 3.0.10 - '@types/d3-hierarchy': - specifier: ^3.1.7 - version: 3.1.7 - '@types/node': - specifier: ^25.0.3 - version: 25.9.3 - '@vitest/coverage-v8': - specifier: ^4.0.18 - version: 4.1.8(vitest@4.1.8) - '@xyflow/system': - specifier: ^0.0.75 - version: 0.0.75 - bumpp: - specifier: ^10.3.2 - version: 10.4.1 - cytoscape: - specifier: ^3.34.0 - version: 3.34.0 - d3-array: - specifier: ^3.2.4 - version: 3.2.4 - d3-force: - specifier: ^3.0.0 - version: 3.0.0 - d3-hierarchy: - specifier: ^3.1.2 - version: 3.1.2 - dotparser: - specifier: ^1.1.1 - version: 1.1.1 - elkjs: - specifier: ^0.11.1 - version: 0.11.1 - fast-xml-parser: - specifier: ^5.3.4 - version: 5.8.0 - graphology: - specifier: ^0.26.0 - version: 0.26.0(graphology-types@0.24.8) - graphology-components: - specifier: ^1.5.4 - version: 1.5.4(graphology-types@0.24.8) - graphology-layout-forceatlas2: - specifier: ^0.10.1 - version: 0.10.1(graphology-types@0.24.8) - graphology-metrics: - specifier: ^2.4.0 - version: 2.4.0(graphology-types@0.24.8) - graphology-shortest-path: - specifier: ^2.1.0 - version: 2.1.0(graphology-types@0.24.8) - graphology-types: - specifier: ^0.24.8 - version: 0.24.8 - ngraph.graph: - specifier: ^20.1.2 - version: 20.1.2 - ngraph.path: - specifier: ^1.6.1 - version: 1.6.1 - publint: - specifier: ^0.3.15 - version: 0.3.21 - tsdown: - specifier: ^0.18.1 - version: 0.18.4(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)(publint@0.3.21)(typescript@5.9.3) - tsx: - specifier: ^4.21.0 - version: 4.22.4 - typescript: - specifier: ^5.9.3 - version: 5.9.3 - vitest: - specifier: ^4.0.16 - version: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16) - webcola: - specifier: ^3.4.0 - version: 3.4.0 - xstate: - specifier: ^5.28.0 - version: 5.32.0 - zod: - specifier: ^4.3.6 - version: 4.4.3 +importers: + + .: + devDependencies: + '@changesets/changelog-github': + specifier: ^0.5.2 + version: 0.5.2 + '@changesets/cli': + specifier: ^2.29.8 + version: 2.31.0(@types/node@25.9.3) + '@dagrejs/dagre': + specifier: ^3.0.0 + version: 3.0.0 + '@dagrejs/graphlib': + specifier: ^4.0.1 + version: 4.0.1 + '@hpcc-js/wasm-graphviz': + specifier: ^1.22.0 + version: 1.22.0 + '@types/d3-array': + specifier: ^3.2.2 + version: 3.2.2 + '@types/d3-force': + specifier: ^3.0.10 + version: 3.0.10 + '@types/d3-hierarchy': + specifier: ^3.1.7 + version: 3.1.7 + '@types/node': + specifier: ^25.0.3 + version: 25.9.3 + '@vitest/coverage-v8': + specifier: ^4.0.18 + version: 4.1.8(vitest@4.1.8) + '@xyflow/system': + specifier: ^0.0.75 + version: 0.0.75 + bumpp: + specifier: ^10.3.2 + version: 10.4.1(magicast@0.5.3) + cytoscape: + specifier: ^3.34.0 + version: 3.34.0 + d3-array: + specifier: ^3.2.4 + version: 3.2.4 + d3-force: + specifier: ^3.0.0 + version: 3.0.0 + d3-hierarchy: + specifier: ^3.1.2 + version: 3.1.2 + dotparser: + specifier: ^1.1.1 + version: 1.1.1 + elkjs: + specifier: ^0.11.1 + version: 0.11.1 + fast-xml-parser: + specifier: ^5.3.4 + version: 5.8.0 + graphology: + specifier: ^0.26.0 + version: 0.26.0(graphology-types@0.24.8) + graphology-components: + specifier: ^1.5.4 + version: 1.5.4(graphology-types@0.24.8) + graphology-layout-forceatlas2: + specifier: ^0.10.1 + version: 0.10.1(graphology-types@0.24.8) + graphology-metrics: + specifier: ^2.4.0 + version: 2.4.0(graphology-types@0.24.8) + graphology-shortest-path: + specifier: ^2.1.0 + version: 2.1.0(graphology-types@0.24.8) + graphology-types: + specifier: ^0.24.8 + version: 0.24.8 + ngraph.graph: + specifier: ^20.1.2 + version: 20.1.2 + ngraph.path: + specifier: ^1.6.1 + version: 1.6.1 + publint: + specifier: ^0.3.15 + version: 0.3.21 + tsdown: + specifier: ^0.18.1 + version: 0.18.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(publint@0.3.21)(typescript@5.9.3) + tsx: + specifier: ^4.21.0 + version: 4.22.4 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vitest: + specifier: ^4.0.16 + version: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)) + webcola: + specifier: ^3.4.0 + version: 3.4.0 + xstate: + specifier: ^5.28.0 + version: 5.32.0 + zod: + specifier: ^4.3.6 + version: 4.4.3 packages: - /@babel/generator@7.29.7: + '@babel/generator@7.29.7': resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==, tarball: https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz} engines: {node: '>=6.9.0'} - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - dev: true - /@babel/helper-string-parser@7.29.7: + '@babel/helper-string-parser@7.29.7': resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==, tarball: https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz} engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-validator-identifier@7.29.7: + '@babel/helper-validator-identifier@7.29.7': resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==, tarball: https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz} engines: {node: '>=6.9.0'} - dev: true - /@babel/parser@7.29.7: + '@babel/parser@7.29.7': resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==, tarball: https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz} engines: {node: '>=6.0.0'} hasBin: true - dependencies: - '@babel/types': 7.29.7 - dev: true - /@babel/runtime@7.29.7: + '@babel/runtime@7.29.7': resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==, tarball: https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz} engines: {node: '>=6.9.0'} - dev: true - /@babel/types@7.29.7: + '@babel/types@7.29.7': resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==, tarball: https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz} engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - dev: true - /@bcoe/v8-coverage@1.0.2: + '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==, tarball: https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz} engines: {node: '>=18'} - dev: true - /@changesets/apply-release-plan@7.1.1: + '@changesets/apply-release-plan@7.1.1': resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==, tarball: https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.1.1.tgz} - dependencies: - '@changesets/config': 3.1.4 - '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.4 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.8.8 - resolve-from: 5.0.0 - semver: 7.8.4 - dev: true - /@changesets/assemble-release-plan@6.0.10: + '@changesets/assemble-release-plan@6.0.10': resolution: {integrity: sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==, tarball: https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.10.tgz} - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.4 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - semver: 7.8.4 - dev: true - /@changesets/changelog-git@0.2.1: + '@changesets/changelog-git@0.2.1': resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==, tarball: https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz} - dependencies: - '@changesets/types': 6.1.0 - dev: true - /@changesets/changelog-github@0.5.2: + '@changesets/changelog-github@0.5.2': resolution: {integrity: sha512-HeGeDl8HaIGj9fQHo/tv5XKQ2SNEi9+9yl1Bss1jttPqeiASRXhfi0A2wv8yFKCp07kR1gpOI5ge6+CWNm1jPw==, tarball: https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.5.2.tgz} - dependencies: - '@changesets/get-github-info': 0.7.0 - '@changesets/types': 6.1.0 - dotenv: 8.6.0 - transitivePeerDependencies: - - encoding - dev: true - /@changesets/cli@2.31.0(@types/node@25.9.3): + '@changesets/cli@2.31.0': resolution: {integrity: sha512-AhI4enNTgHu2IZr6K4WZyf0EPch4XVMn1yOMFmCD9gsfBGqMYaHXls5HyDv6/CL5axVQABz68eG30eCtbr2wFg==, tarball: https://registry.npmjs.org/@changesets/cli/-/cli-2.31.0.tgz} hasBin: true - dependencies: - '@changesets/apply-release-plan': 7.1.1 - '@changesets/assemble-release-plan': 6.0.10 - '@changesets/changelog-git': 0.2.1 - '@changesets/config': 3.1.4 - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.4 - '@changesets/get-release-plan': 4.0.16 - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.7 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@25.9.3) - '@manypkg/get-packages': 1.1.3 - ansi-colors: 4.1.3 - enquirer: 2.4.1 - fs-extra: 7.0.1 - mri: 1.2.0 - package-manager-detector: 0.2.11 - picocolors: 1.1.1 - resolve-from: 5.0.0 - semver: 7.8.4 - spawndamnit: 3.0.1 - term-size: 2.2.1 - transitivePeerDependencies: - - '@types/node' - dev: true - /@changesets/config@3.1.4: + '@changesets/config@3.1.4': resolution: {integrity: sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==, tarball: https://registry.npmjs.org/@changesets/config/-/config-3.1.4.tgz} - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.4 - '@changesets/logger': 0.1.1 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - micromatch: 4.0.8 - dev: true - /@changesets/errors@0.2.0: + '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==, tarball: https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz} - dependencies: - extendable-error: 0.1.7 - dev: true - /@changesets/get-dependents-graph@2.1.4: + '@changesets/get-dependents-graph@2.1.4': resolution: {integrity: sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==, tarball: https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.4.tgz} - dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - picocolors: 1.1.1 - semver: 7.8.4 - dev: true - /@changesets/get-github-info@0.7.0: + '@changesets/get-github-info@0.7.0': resolution: {integrity: sha512-+i67Bmhfj9V4KfDeS1+Tz3iF32btKZB2AAx+cYMqDSRFP7r3/ZdGbjCo+c6qkyViN9ygDuBjzageuPGJtKGe5A==, tarball: https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.7.0.tgz} - dependencies: - dataloader: 1.4.0 - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - dev: true - /@changesets/get-release-plan@4.0.16: + '@changesets/get-release-plan@4.0.16': resolution: {integrity: sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==, tarball: https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.16.tgz} - dependencies: - '@changesets/assemble-release-plan': 6.0.10 - '@changesets/config': 3.1.4 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.7 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - dev: true - /@changesets/get-version-range-type@0.4.0: + '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==, tarball: https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz} - dev: true - /@changesets/git@3.0.4: + '@changesets/git@3.0.4': resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==, tarball: https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz} - dependencies: - '@changesets/errors': 0.2.0 - '@manypkg/get-packages': 1.1.3 - is-subdir: 1.2.0 - micromatch: 4.0.8 - spawndamnit: 3.0.1 - dev: true - /@changesets/logger@0.1.1: + '@changesets/logger@0.1.1': resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==, tarball: https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz} - dependencies: - picocolors: 1.1.1 - dev: true - /@changesets/parse@0.4.3: + '@changesets/parse@0.4.3': resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==, tarball: https://registry.npmjs.org/@changesets/parse/-/parse-0.4.3.tgz} - dependencies: - '@changesets/types': 6.1.0 - js-yaml: 4.2.0 - dev: true - /@changesets/pre@2.0.2: + '@changesets/pre@2.0.2': resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==, tarball: https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz} - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - dev: true - /@changesets/read@0.6.7: + '@changesets/read@0.6.7': resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==, tarball: https://registry.npmjs.org/@changesets/read/-/read-0.6.7.tgz} - dependencies: - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.3 - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - p-filter: 2.1.0 - picocolors: 1.1.1 - dev: true - /@changesets/should-skip-package@0.1.2: + '@changesets/should-skip-package@0.1.2': resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==, tarball: https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz} - dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - dev: true - /@changesets/types@4.1.0: + '@changesets/types@4.1.0': resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==, tarball: https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz} - dev: true - /@changesets/types@6.1.0: + '@changesets/types@6.1.0': resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==, tarball: https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz} - dev: true - /@changesets/write@0.4.0: + '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==, tarball: https://registry.npmjs.org/@changesets/write/-/write-0.4.0.tgz} - dependencies: - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - human-id: 4.2.0 - prettier: 2.8.8 - dev: true - /@dagrejs/dagre@3.0.0: + '@dagrejs/dagre@3.0.0': resolution: {integrity: sha512-ZzhnTy1rfuoew9Ez3EIw4L2znPGnYYhfn8vc9c4oB8iw6QAsszbiU0vRhlxWPFnmmNSFAkrYeF1PhM5m4lAN0Q==, tarball: https://registry.npmjs.org/@dagrejs/dagre/-/dagre-3.0.0.tgz} - dependencies: - '@dagrejs/graphlib': 4.0.1 - dev: true - /@dagrejs/graphlib@4.0.1: + '@dagrejs/graphlib@4.0.1': resolution: {integrity: sha512-IvcV6FduIIAmLwnH+yun+QtV36SC7mERqa86aClNqmMN09WhmPPYU8ckHrZBozErf+UvHPWOTJYaGYiIcs0DgA==, tarball: https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-4.0.1.tgz} - dev: true - /@emnapi/core@1.10.0: + '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==, tarball: https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz} - requiresBuild: true - dependencies: - '@emnapi/wasi-threads': 1.2.1 - tslib: 2.8.1 - dev: true - optional: true - - /@emnapi/core@1.11.0: - resolution: {integrity: sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==, tarball: https://registry.npmjs.org/@emnapi/core/-/core-1.11.0.tgz} - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.8.1 - dev: true - optional: true - /@emnapi/runtime@1.10.0: + '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==, tarball: https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz} - requiresBuild: true - dependencies: - tslib: 2.8.1 - dev: true - optional: true - - /@emnapi/runtime@1.11.0: - resolution: {integrity: sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==, tarball: https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.0.tgz} - dependencies: - tslib: 2.8.1 - dev: true - optional: true - /@emnapi/wasi-threads@1.2.1: + '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==, tarball: https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz} - requiresBuild: true - dependencies: - tslib: 2.8.1 - dev: true - optional: true - - /@emnapi/wasi-threads@1.2.2: - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==, tarball: https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz} - dependencies: - tslib: 2.8.1 - dev: true - optional: true - /@esbuild/aix-ppc64@0.28.1: - resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz} + '@esbuild/aix-ppc64@0.28.0': + resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-arm64@0.28.1: - resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz} + '@esbuild/android-arm64@0.28.0': + resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-arm@0.28.1: - resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz} + '@esbuild/android-arm@0.28.0': + resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm] os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-x64@0.28.1: - resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz} + '@esbuild/android-x64@0.28.0': + resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/darwin-arm64@0.28.1: - resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz} + '@esbuild/darwin-arm64@0.28.0': + resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@esbuild/darwin-x64@0.28.1: - resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz} + '@esbuild/darwin-x64@0.28.0': + resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@esbuild/freebsd-arm64@0.28.1: - resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz} + '@esbuild/freebsd-arm64@0.28.0': + resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/freebsd-x64@0.28.1: - resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz} + '@esbuild/freebsd-x64@0.28.0': + resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-arm64@0.28.1: - resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz} + '@esbuild/linux-arm64@0.28.0': + resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-arm@0.28.1: - resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz} + '@esbuild/linux-arm@0.28.0': + resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-ia32@0.28.1: - resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz} + '@esbuild/linux-ia32@0.28.0': + resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz} engines: {node: '>=18'} cpu: [ia32] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-loong64@0.28.1: - resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz} + '@esbuild/linux-loong64@0.28.0': + resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz} engines: {node: '>=18'} cpu: [loong64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-mips64el@0.28.1: - resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz} + '@esbuild/linux-mips64el@0.28.0': + resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-ppc64@0.28.1: - resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz} + '@esbuild/linux-ppc64@0.28.0': + resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-riscv64@0.28.1: - resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz} + '@esbuild/linux-riscv64@0.28.0': + resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-s390x@0.28.1: - resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz} + '@esbuild/linux-s390x@0.28.0': + resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz} engines: {node: '>=18'} cpu: [s390x] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-x64@0.28.1: - resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz} + '@esbuild/linux-x64@0.28.0': + resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/netbsd-arm64@0.28.1: - resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==, tarball: https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz} + '@esbuild/netbsd-arm64@0.28.0': + resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==, tarball: https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/netbsd-x64@0.28.1: - resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz} + '@esbuild/netbsd-x64@0.28.0': + resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/openbsd-arm64@0.28.1: - resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==, tarball: https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz} + '@esbuild/openbsd-arm64@0.28.0': + resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==, tarball: https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/openbsd-x64@0.28.1: - resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz} + '@esbuild/openbsd-x64@0.28.0': + resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/openharmony-arm64@0.28.1: - resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==, tarball: https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz} + '@esbuild/openharmony-arm64@0.28.0': + resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==, tarball: https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - requiresBuild: true - dev: true - optional: true - /@esbuild/sunos-x64@0.28.1: - resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz} + '@esbuild/sunos-x64@0.28.0': + resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [sunos] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-arm64@0.28.1: - resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz} + '@esbuild/win32-arm64@0.28.0': + resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-ia32@0.28.1: - resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz} + '@esbuild/win32-ia32@0.28.0': + resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz} engines: {node: '>=18'} cpu: [ia32] os: [win32] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-x64@0.28.1: - resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz} + '@esbuild/win32-x64@0.28.0': + resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@hpcc-js/wasm-graphviz@1.22.0: + '@hpcc-js/wasm-graphviz@1.22.0': resolution: {integrity: sha512-/l6m+ev4TzYwiSm2pklMALiKejuheJwFkOHKrTAvFei+US+MVv6Vgk06xMc4Mjn57WiqzheMVGnmNu1iqkcBdA==, tarball: https://registry.npmjs.org/@hpcc-js/wasm-graphviz/-/wasm-graphviz-1.22.0.tgz} - dev: true - /@inquirer/external-editor@1.0.3(@types/node@25.9.3): + '@inquirer/external-editor@1.0.3': resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==, tarball: https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz} engines: {node: '>=18'} peerDependencies: @@ -662,621 +388,392 @@ packages: peerDependenciesMeta: '@types/node': optional: true - dependencies: - '@types/node': 25.9.3 - chardet: 2.1.1 - iconv-lite: 0.7.2 - dev: true - /@jridgewell/gen-mapping@0.3.13: + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==, tarball: https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz} - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - dev: true - /@jridgewell/resolve-uri@3.1.2: + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, tarball: https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz} engines: {node: '>=6.0.0'} - dev: true - /@jridgewell/sourcemap-codec@1.5.5: + '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, tarball: https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz} - dev: true - /@jridgewell/trace-mapping@0.3.31: + '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==, tarball: https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz} - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - dev: true - /@manypkg/find-root@1.1.0: + '@manypkg/find-root@1.1.0': resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==, tarball: https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz} - dependencies: - '@babel/runtime': 7.29.7 - '@types/node': 12.20.55 - find-up: 4.1.0 - fs-extra: 8.1.0 - dev: true - /@manypkg/get-packages@1.1.3: + '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==, tarball: https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz} - dependencies: - '@babel/runtime': 7.29.7 - '@changesets/types': 4.1.0 - '@manypkg/find-root': 1.1.0 - fs-extra: 8.1.0 - globby: 11.1.0 - read-yaml-file: 1.1.0 - dev: true - - /@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): - resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==, tarball: https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz} - requiresBuild: true - peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 - dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.2 - dev: true - optional: true - /@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0): + '@napi-rs/wasm-runtime@1.1.5': resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==, tarball: https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz} - requiresBuild: true peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 - dependencies: - '@emnapi/core': 1.11.0 - '@emnapi/runtime': 1.11.0 - '@tybys/wasm-util': 0.10.2 - dev: true - optional: true - /@nodable/entities@2.1.1: + '@nodable/entities@2.1.1': resolution: {integrity: sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg==, tarball: https://registry.npmjs.org/@nodable/entities/-/entities-2.1.1.tgz} - dev: true - /@nodelib/fs.scandir@2.1.5: + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, tarball: https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - /@nodelib/fs.stat@2.0.5: + '@nodelib/fs.stat@2.0.5': resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, tarball: https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz} engines: {node: '>= 8'} - dev: true - /@nodelib/fs.walk@1.2.8: + '@nodelib/fs.walk@1.2.8': resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, tarball: https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 - dev: true - /@oxc-project/types@0.103.0: + '@oxc-project/types@0.103.0': resolution: {integrity: sha512-bkiYX5kaXWwUessFRSoXFkGIQTmc6dLGdxuRTrC+h8PSnIdZyuXHHlLAeTmOue5Br/a0/a7dHH0Gca6eXn9MKg==, tarball: https://registry.npmjs.org/@oxc-project/types/-/types-0.103.0.tgz} - dev: true - /@oxc-project/types@0.127.0: + '@oxc-project/types@0.127.0': resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==, tarball: https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz} - dev: true - /@oxc-project/types@0.133.0: + '@oxc-project/types@0.133.0': resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==, tarball: https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz} - dev: true - /@publint/pack@0.1.4: + '@publint/pack@0.1.4': resolution: {integrity: sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ==, tarball: https://registry.npmjs.org/@publint/pack/-/pack-0.1.4.tgz} engines: {node: '>=18'} - dev: true - /@quansync/fs@1.0.0: + '@quansync/fs@1.0.0': resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==, tarball: https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz} - dependencies: - quansync: 1.0.0 - dev: true - /@rolldown/binding-android-arm64@1.0.0-beta.57: + '@rolldown/binding-android-arm64@1.0.0-beta.57': resolution: {integrity: sha512-GoOVDy8bjw9z1K30Oo803nSzXJS/vWhFijFsW3kzvZCO8IZwFnNa6pGctmbbJstKl3Fv6UBwyjJQN6msejW0IQ==, tarball: https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-android-arm64@1.0.0-rc.17: + '@rolldown/binding-android-arm64@1.0.0-rc.17': resolution: {integrity: sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==, tarball: https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-android-arm64@1.0.3: + '@rolldown/binding-android-arm64@1.0.3': resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==, tarball: https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-darwin-arm64@1.0.0-beta.57: + '@rolldown/binding-darwin-arm64@1.0.0-beta.57': resolution: {integrity: sha512-9c4FOhRGpl+PX7zBK5p17c5efpF9aSpTPgyigv57hXf5NjQUaJOOiejPLAtFiKNBIfm5Uu6yFkvLKzOafNvlTw==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-darwin-arm64@1.0.0-rc.17: + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': resolution: {integrity: sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-darwin-arm64@1.0.3: + '@rolldown/binding-darwin-arm64@1.0.3': resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-darwin-x64@1.0.0-beta.57: + '@rolldown/binding-darwin-x64@1.0.0-beta.57': resolution: {integrity: sha512-6RsB8Qy4LnGqNGJJC/8uWeLWGOvbRL/KG5aJ8XXpSEupg/KQtlBEiFaYU/Ma5Usj1s+bt3ItkqZYAI50kSplBA==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-darwin-x64@1.0.0-rc.17: + '@rolldown/binding-darwin-x64@1.0.0-rc.17': resolution: {integrity: sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-darwin-x64@1.0.3: + '@rolldown/binding-darwin-x64@1.0.3': resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==, tarball: https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-freebsd-x64@1.0.0-beta.57: + '@rolldown/binding-freebsd-x64@1.0.0-beta.57': resolution: {integrity: sha512-uA9kG7+MYkHTbqwv67Tx+5GV5YcKd33HCJIi0311iYBd25yuwyIqvJfBdt1VVB8tdOlyTb9cPAgfCki8nhwTQg==, tarball: https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-freebsd-x64@1.0.0-rc.17: + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': resolution: {integrity: sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==, tarball: https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-freebsd-x64@1.0.3: + '@rolldown/binding-freebsd-x64@1.0.3': resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==, tarball: https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.57: + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.57': resolution: {integrity: sha512-3KkS0cHsllT2T+Te+VZMKHNw6FPQihYsQh+8J4jkzwgvAQpbsbXmrqhkw3YU/QGRrD8qgcOvBr6z5y6Jid+rmw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17: + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': resolution: {integrity: sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-linux-arm-gnueabihf@1.0.3: + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-linux-arm64-gnu@1.0.0-beta.57: + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.57': resolution: {integrity: sha512-A3/wu1RgsHhqP3rVH2+sM81bpk+Qd2XaHTl8LtX5/1LNR7QVBFBCpAoiXwjTdGnI5cMdBVi7Z1pi52euW760Fw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17: + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-arm64-gnu@1.0.3: + '@rolldown/binding-linux-arm64-gnu@1.0.3': resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-arm64-musl@1.0.0-beta.57: + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.57': resolution: {integrity: sha512-d0kIVezTQtazpyWjiJIn5to8JlwfKITDqwsFv0Xc6s31N16CD2PC/Pl2OtKgS7n8WLOJbfqgIp5ixYzTAxCqMg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [musl] - /@rolldown/binding-linux-arm64-musl@1.0.0-rc.17: + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [musl] - /@rolldown/binding-linux-arm64-musl@1.0.3: + '@rolldown/binding-linux-arm64-musl@1.0.3': resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [musl] - /@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17: + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-ppc64-gnu@1.0.3: + '@rolldown/binding-linux-ppc64-gnu@1.0.3': resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17: + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-s390x-gnu@1.0.3: + '@rolldown/binding-linux-s390x-gnu@1.0.3': resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-x64-gnu@1.0.0-beta.57: + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.57': resolution: {integrity: sha512-E199LPijo98yrLjPCmETx8EF43sZf9t3guSrLee/ej1rCCc3zDVTR4xFfN9BRAapGVl7/8hYqbbiQPTkv73kUg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-x64-gnu@1.0.0-rc.17: + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-x64-gnu@1.0.3: + '@rolldown/binding-linux-x64-gnu@1.0.3': resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /@rolldown/binding-linux-x64-musl@1.0.0-beta.57: + '@rolldown/binding-linux-x64-musl@1.0.0-beta.57': resolution: {integrity: sha512-++EQDpk/UJ33kY/BNsh7A7/P1sr/jbMuQ8cE554ZIy+tCUWCivo9zfyjDUoiMdnxqX6HLJEqqGnbGQOvzm2OMQ==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [musl] - /@rolldown/binding-linux-x64-musl@1.0.0-rc.17: + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [musl] - /@rolldown/binding-linux-x64-musl@1.0.3: + '@rolldown/binding-linux-x64-musl@1.0.3': resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==, tarball: https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [musl] - /@rolldown/binding-openharmony-arm64@1.0.0-beta.57: + '@rolldown/binding-openharmony-arm64@1.0.0-beta.57': resolution: {integrity: sha512-voDEBcNqxbUv/GeXKFtxXVWA+H45P/8Dec4Ii/SbyJyGvCqV1j+nNHfnFUIiRQ2Q40DwPe/djvgYBs9PpETiMA==, tarball: https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-openharmony-arm64@1.0.0-rc.17: + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==, tarball: https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-openharmony-arm64@1.0.3: + '@rolldown/binding-openharmony-arm64@1.0.3': resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==, tarball: https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-wasm32-wasi@1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0): + '@rolldown/binding-wasm32-wasi@1.0.0-beta.57': resolution: {integrity: sha512-bRhcF7NLlCnpkzLVlVhrDEd0KH22VbTPkPTbMjlYvqhSmarxNIq5vtlQS8qmV7LkPKHrNLWyJW/V/sOyFba26Q==, tarball: https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.57.tgz} engines: {node: '>=14.0.0'} cpu: [wasm32] - requiresBuild: true - dependencies: - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' - dev: true - optional: true - /@rolldown/binding-wasm32-wasi@1.0.0-rc.17: + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': resolution: {integrity: sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==, tarball: https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - requiresBuild: true - dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) - dev: true - optional: true - /@rolldown/binding-wasm32-wasi@1.0.3: + '@rolldown/binding-wasm32-wasi@1.0.3': resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==, tarball: https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - requiresBuild: true - dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) - dev: true - optional: true - /@rolldown/binding-win32-arm64-msvc@1.0.0-beta.57: + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.57': resolution: {integrity: sha512-rnDVGRks2FQ2hgJ2g15pHtfxqkGFGjJQUDWzYznEkE8Ra2+Vag9OffxdbJMZqBWXHVM0iS4dv8qSiEn7bO+n1Q==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17: + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': resolution: {integrity: sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-win32-arm64-msvc@1.0.3: + '@rolldown/binding-win32-arm64-msvc@1.0.3': resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-win32-x64-msvc@1.0.0-beta.57: + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.57': resolution: {integrity: sha512-OqIUyNid1M4xTj6VRXp/Lht/qIP8fo25QyAZlCP+p6D2ATCEhyW4ZIFLnC9zAGN/HMbXoCzvwfa8Jjg/8J4YEg==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-win32-x64-msvc@1.0.0-rc.17: + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': resolution: {integrity: sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@rolldown/binding-win32-x64-msvc@1.0.3: + '@rolldown/binding-win32-x64-msvc@1.0.3': resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==, tarball: https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@rolldown/pluginutils@1.0.0-beta.57: + '@rolldown/pluginutils@1.0.0-beta.57': resolution: {integrity: sha512-aQNelgx14tGA+n2tNSa9x6/jeoCL9fkDeCei7nOKnHx0fEFRRMu5ReiITo+zZD5TzWDGGRjbSYCs93IfRIyTuQ==, tarball: https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.57.tgz} - dev: true - /@rolldown/pluginutils@1.0.0-rc.17: + '@rolldown/pluginutils@1.0.0-rc.17': resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==, tarball: https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz} - dev: true - /@rolldown/pluginutils@1.0.1: + '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==, tarball: https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz} - dev: true - /@standard-schema/spec@1.1.0: + '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==, tarball: https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz} - dev: true - /@tybys/wasm-util@0.10.2: + '@tybys/wasm-util@0.10.2': resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==, tarball: https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz} - requiresBuild: true - dependencies: - tslib: 2.8.1 - dev: true - optional: true - /@types/chai@5.2.3: + '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==, tarball: https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz} - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 - dev: true - /@types/d3-array@3.2.2: + '@types/d3-array@3.2.2': resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==, tarball: https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz} - dev: true - /@types/d3-color@3.1.3: + '@types/d3-color@3.1.3': resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==, tarball: https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz} - dev: true - /@types/d3-drag@3.0.7: + '@types/d3-drag@3.0.7': resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==, tarball: https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz} - dependencies: - '@types/d3-selection': 3.0.11 - dev: true - /@types/d3-force@3.0.10: + '@types/d3-force@3.0.10': resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==, tarball: https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz} - dev: true - /@types/d3-hierarchy@3.1.7: + '@types/d3-hierarchy@3.1.7': resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==, tarball: https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz} - dev: true - /@types/d3-interpolate@3.0.4: + '@types/d3-interpolate@3.0.4': resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==, tarball: https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz} - dependencies: - '@types/d3-color': 3.1.3 - dev: true - /@types/d3-selection@3.0.11: + '@types/d3-selection@3.0.11': resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==, tarball: https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz} - dev: true - /@types/d3-transition@3.0.9: + '@types/d3-transition@3.0.9': resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==, tarball: https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz} - dependencies: - '@types/d3-selection': 3.0.11 - dev: true - /@types/d3-zoom@3.0.8: + '@types/d3-zoom@3.0.8': resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==, tarball: https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz} - dependencies: - '@types/d3-interpolate': 3.0.4 - '@types/d3-selection': 3.0.11 - dev: true - /@types/deep-eql@4.0.2: + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==, tarball: https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz} - dev: true - /@types/estree@1.0.9: + '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==, tarball: https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz} - dev: true - /@types/node@12.20.55: + '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==, tarball: https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz} - dev: true - /@types/node@25.9.3: + '@types/node@25.9.3': resolution: {integrity: sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==, tarball: https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz} - dependencies: - undici-types: 7.24.6 - dev: true - /@vitest/coverage-v8@4.1.8(vitest@4.1.8): + '@vitest/coverage-v8@4.1.8': resolution: {integrity: sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==, tarball: https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.8.tgz} peerDependencies: '@vitest/browser': 4.1.8 @@ -1284,32 +781,11 @@ packages: peerDependenciesMeta: '@vitest/browser': optional: true - dependencies: - '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.8 - ast-v8-to-istanbul: 1.0.4 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.2.0 - magicast: 0.5.3 - obug: 2.1.2 - std-env: 4.1.0 - tinyrainbow: 3.1.0 - vitest: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16) - dev: true - /@vitest/expect@4.1.8: + '@vitest/expect@4.1.8': resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==, tarball: https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz} - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.8 - '@vitest/utils': 4.1.8 - chai: 6.2.2 - tinyrainbow: 3.1.0 - dev: true - /@vitest/mocker@4.1.8(vite@8.0.16): + '@vitest/mocker@4.1.8': resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==, tarball: https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.8.tgz} peerDependencies: msw: ^2.4.9 @@ -1319,391 +795,225 @@ packages: optional: true vite: optional: true - dependencies: - '@vitest/spy': 4.1.8 - estree-walker: 3.0.3 - magic-string: 0.30.21 - vite: 8.0.16(@types/node@25.9.3)(tsx@4.22.4) - dev: true - /@vitest/pretty-format@4.1.8: + '@vitest/pretty-format@4.1.8': resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==, tarball: https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.8.tgz} - dependencies: - tinyrainbow: 3.1.0 - dev: true - /@vitest/runner@4.1.8: + '@vitest/runner@4.1.8': resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==, tarball: https://registry.npmjs.org/@vitest/runner/-/runner-4.1.8.tgz} - dependencies: - '@vitest/utils': 4.1.8 - pathe: 2.0.3 - dev: true - /@vitest/snapshot@4.1.8: + '@vitest/snapshot@4.1.8': resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==, tarball: https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.8.tgz} - dependencies: - '@vitest/pretty-format': 4.1.8 - '@vitest/utils': 4.1.8 - magic-string: 0.30.21 - pathe: 2.0.3 - dev: true - /@vitest/spy@4.1.8: + '@vitest/spy@4.1.8': resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==, tarball: https://registry.npmjs.org/@vitest/spy/-/spy-4.1.8.tgz} - dev: true - /@vitest/utils@4.1.8: + '@vitest/utils@4.1.8': resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==, tarball: https://registry.npmjs.org/@vitest/utils/-/utils-4.1.8.tgz} - dependencies: - '@vitest/pretty-format': 4.1.8 - convert-source-map: 2.0.0 - tinyrainbow: 3.1.0 - dev: true - /@xyflow/system@0.0.75: + '@xyflow/system@0.0.75': resolution: {integrity: sha512-iXs+AGFLi8w/VlAoc/iSxk+CxfT6o64Uw/k0CKASOPqjqz6E0rb5jFZgJtXGZCpfQI6OQpu5EnumP5fGxQheaQ==, tarball: https://registry.npmjs.org/@xyflow/system/-/system-0.0.75.tgz} - dependencies: - '@types/d3-drag': 3.0.7 - '@types/d3-interpolate': 3.0.4 - '@types/d3-selection': 3.0.11 - '@types/d3-transition': 3.0.9 - '@types/d3-zoom': 3.0.8 - d3-drag: 3.0.0 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-zoom: 3.0.0 - dev: true - /@yomguithereal/helpers@1.1.1: + '@yomguithereal/helpers@1.1.1': resolution: {integrity: sha512-UYvAq/XCA7xoh1juWDYsq3W0WywOB+pz8cgVnE1b45ZfdMhBvHDrgmSFG3jXeZSr2tMTYLGHFHON+ekG05Jebg==, tarball: https://registry.npmjs.org/@yomguithereal/helpers/-/helpers-1.1.1.tgz} - dev: true - /ansi-colors@4.1.3: + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==, tarball: https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz} engines: {node: '>=6'} - dev: true - /ansi-regex@5.0.1: + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, tarball: https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz} engines: {node: '>=8'} - dev: true - /ansis@4.3.1: + ansis@4.3.1: resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==, tarball: https://registry.npmjs.org/ansis/-/ansis-4.3.1.tgz} engines: {node: '>=14'} - dev: true - /anynum@1.0.0: + anynum@1.0.0: resolution: {integrity: sha512-xjR9/zBVnUOP6ztMIIgShjsxui80nQUQH+5xJnvrYLs+90bF25/KJqaAi8mk+B4RDtX1Nspi6fmp4YTEts8SfA==, tarball: https://registry.npmjs.org/anynum/-/anynum-1.0.0.tgz} - dev: true - /argparse@1.0.10: + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, tarball: https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz} - dependencies: - sprintf-js: 1.0.3 - dev: true - /argparse@2.0.1: + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, tarball: https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz} - dev: true - /args-tokenizer@0.3.0: + args-tokenizer@0.3.0: resolution: {integrity: sha512-xXAd7G2Mll5W8uo37GETpQ2VrE84M181Z7ugHFGQnJZ50M2mbOv0osSZ9VsSgPfJQ+LVG0prSi0th+ELMsno7Q==, tarball: https://registry.npmjs.org/args-tokenizer/-/args-tokenizer-0.3.0.tgz} - dev: true - /array-union@2.1.0: + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, tarball: https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz} engines: {node: '>=8'} - dev: true - /assertion-error@2.0.1: + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==, tarball: https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz} engines: {node: '>=12'} - dev: true - /ast-kit@2.2.0: + ast-kit@2.2.0: resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==, tarball: https://registry.npmjs.org/ast-kit/-/ast-kit-2.2.0.tgz} engines: {node: '>=20.19.0'} - dependencies: - '@babel/parser': 7.29.7 - pathe: 2.0.3 - dev: true - /ast-v8-to-istanbul@1.0.4: + ast-v8-to-istanbul@1.0.4: resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==, tarball: https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.4.tgz} - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - estree-walker: 3.0.3 - js-tokens: 10.0.0 - dev: true - /better-path-resolve@1.0.0: + better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==, tarball: https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz} engines: {node: '>=4'} - dependencies: - is-windows: 1.0.2 - dev: true - /birpc@4.0.0: + birpc@4.0.0: resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==, tarball: https://registry.npmjs.org/birpc/-/birpc-4.0.0.tgz} - dev: true - /braces@3.0.3: + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, tarball: https://registry.npmjs.org/braces/-/braces-3.0.3.tgz} engines: {node: '>=8'} - dependencies: - fill-range: 7.1.1 - dev: true - /bumpp@10.4.1: + bumpp@10.4.1: resolution: {integrity: sha512-X/bwWs5Gbb/D7rN4aHLB7zdjiA6nGdjckM1sTHhI9oovIbEw2L5pw5S4xzk8ZTeOZ8EnwU/Ze4SoZ6/Vr3pM2Q==, tarball: https://registry.npmjs.org/bumpp/-/bumpp-10.4.1.tgz} engines: {node: '>=18'} hasBin: true - dependencies: - ansis: 4.3.1 - args-tokenizer: 0.3.0 - c12: 3.3.4 - cac: 6.7.14 - escalade: 3.2.0 - jsonc-parser: 3.3.1 - package-manager-detector: 1.6.0 - semver: 7.8.4 - tinyexec: 1.2.4 - tinyglobby: 0.2.17 - yaml: 2.9.0 - transitivePeerDependencies: - - magicast - dev: true - /c12@3.3.4: + c12@3.3.4: resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==, tarball: https://registry.npmjs.org/c12/-/c12-3.3.4.tgz} peerDependencies: magicast: '*' peerDependenciesMeta: magicast: optional: true - dependencies: - chokidar: 5.0.0 - confbox: 0.2.4 - defu: 6.1.7 - dotenv: 17.4.2 - exsolve: 1.0.8 - giget: 3.3.0 - jiti: 2.7.0 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - pkg-types: 2.3.1 - rc9: 3.0.1 - dev: true - /cac@6.7.14: + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, tarball: https://registry.npmjs.org/cac/-/cac-6.7.14.tgz} engines: {node: '>=8'} - dev: true - /chai@6.2.2: + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==, tarball: https://registry.npmjs.org/chai/-/chai-6.2.2.tgz} engines: {node: '>=18'} - dev: true - /chardet@2.1.1: + chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==, tarball: https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz} - dev: true - /chokidar@5.0.0: + chokidar@5.0.0: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==, tarball: https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz} engines: {node: '>= 20.19.0'} - dependencies: - readdirp: 5.0.0 - dev: true - /confbox@0.2.4: + confbox@0.2.4: resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==, tarball: https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz} - dev: true - /convert-source-map@2.0.0: + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, tarball: https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz} - dev: true - /cross-spawn@7.0.6: + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, tarball: https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz} engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - /cytoscape@3.34.0: + cytoscape@3.34.0: resolution: {integrity: sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==, tarball: https://registry.npmjs.org/cytoscape/-/cytoscape-3.34.0.tgz} engines: {node: '>=0.10'} - dev: true - /d3-array@3.2.4: + d3-array@3.2.4: resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==, tarball: https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz} engines: {node: '>=12'} - dependencies: - internmap: 2.0.3 - dev: true - /d3-color@3.1.0: + d3-color@3.1.0: resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==, tarball: https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz} engines: {node: '>=12'} - dev: true - /d3-dispatch@1.0.6: + d3-dispatch@1.0.6: resolution: {integrity: sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==, tarball: https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz} - dev: true - /d3-dispatch@3.0.1: + d3-dispatch@3.0.1: resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==, tarball: https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz} engines: {node: '>=12'} - dev: true - /d3-drag@1.2.5: + d3-drag@1.2.5: resolution: {integrity: sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==, tarball: https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz} - dependencies: - d3-dispatch: 1.0.6 - d3-selection: 1.4.2 - dev: true - /d3-drag@3.0.0: + d3-drag@3.0.0: resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==, tarball: https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz} engines: {node: '>=12'} - dependencies: - d3-dispatch: 3.0.1 - d3-selection: 3.0.0 - dev: true - /d3-ease@3.0.1: + d3-ease@3.0.1: resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==, tarball: https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz} engines: {node: '>=12'} - dev: true - /d3-force@3.0.0: + d3-force@3.0.0: resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==, tarball: https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz} engines: {node: '>=12'} - dependencies: - d3-dispatch: 3.0.1 - d3-quadtree: 3.0.1 - d3-timer: 3.0.1 - dev: true - /d3-hierarchy@3.1.2: + d3-hierarchy@3.1.2: resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==, tarball: https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz} engines: {node: '>=12'} - dev: true - /d3-interpolate@3.0.1: + d3-interpolate@3.0.1: resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==, tarball: https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz} engines: {node: '>=12'} - dependencies: - d3-color: 3.1.0 - dev: true - /d3-path@1.0.9: + d3-path@1.0.9: resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==, tarball: https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz} - dev: true - /d3-quadtree@3.0.1: + d3-quadtree@3.0.1: resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==, tarball: https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz} engines: {node: '>=12'} - dev: true - /d3-selection@1.4.2: + d3-selection@1.4.2: resolution: {integrity: sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg==, tarball: https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz} - dev: true - /d3-selection@3.0.0: + d3-selection@3.0.0: resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==, tarball: https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz} engines: {node: '>=12'} - dev: true - /d3-shape@1.3.7: + d3-shape@1.3.7: resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==, tarball: https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz} - dependencies: - d3-path: 1.0.9 - dev: true - /d3-timer@1.0.10: + d3-timer@1.0.10: resolution: {integrity: sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==, tarball: https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz} - dev: true - /d3-timer@3.0.1: + d3-timer@3.0.1: resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==, tarball: https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz} engines: {node: '>=12'} - dev: true - /d3-transition@3.0.1(d3-selection@3.0.0): + d3-transition@3.0.1: resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==, tarball: https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz} engines: {node: '>=12'} peerDependencies: d3-selection: 2 - 3 - dependencies: - d3-color: 3.1.0 - d3-dispatch: 3.0.1 - d3-ease: 3.0.1 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-timer: 3.0.1 - dev: true - /d3-zoom@3.0.0: + d3-zoom@3.0.0: resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==, tarball: https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz} engines: {node: '>=12'} - dependencies: - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-transition: 3.0.1(d3-selection@3.0.0) - dev: true - /dataloader@1.4.0: + dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==, tarball: https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz} - dev: true - /defu@6.1.7: + defu@6.1.7: resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==, tarball: https://registry.npmjs.org/defu/-/defu-6.1.7.tgz} - dev: true - /destr@2.0.5: + destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==, tarball: https://registry.npmjs.org/destr/-/destr-2.0.5.tgz} - dev: true - /detect-indent@6.1.0: + detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==, tarball: https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz} engines: {node: '>=8'} - dev: true - /detect-libc@2.1.2: + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==, tarball: https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz} engines: {node: '>=8'} - dev: true - /dir-glob@3.0.1: + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, tarball: https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz} engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - /dotenv@17.4.2: + dotenv@17.4.2: resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==, tarball: https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz} engines: {node: '>=12'} - dev: true - /dotenv@8.6.0: + dotenv@8.6.0: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==, tarball: https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz} engines: {node: '>=10'} - dev: true - /dotparser@1.1.1: + dotparser@1.1.1: resolution: {integrity: sha512-8ojhUts0HbLnXJgjTiJOddwVVBUk6hg4SJ5kGiuhzgK/f+y79TiWvICwx1oCWlVbBC8YI3nEaIQg9fjGYbGBXw==, tarball: https://registry.npmjs.org/dotparser/-/dotparser-1.1.1.tgz} - dev: true - /dts-resolver@2.1.3: + dts-resolver@2.1.3: resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==, tarball: https://registry.npmjs.org/dts-resolver/-/dts-resolver-2.1.3.tgz} engines: {node: '>=20.19.0'} peerDependencies: @@ -1711,134 +1021,67 @@ packages: peerDependenciesMeta: oxc-resolver: optional: true - dev: true - /elkjs@0.11.1: + elkjs@0.11.1: resolution: {integrity: sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==, tarball: https://registry.npmjs.org/elkjs/-/elkjs-0.11.1.tgz} - dev: true - /empathic@2.0.1: + empathic@2.0.1: resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==, tarball: https://registry.npmjs.org/empathic/-/empathic-2.0.1.tgz} engines: {node: '>=14'} - dev: true - /enquirer@2.4.1: + enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==, tarball: https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz} engines: {node: '>=8.6'} - dependencies: - ansi-colors: 4.1.3 - strip-ansi: 6.0.1 - dev: true - /es-module-lexer@2.1.0: + es-module-lexer@2.1.0: resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==, tarball: https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz} - dev: true - /esbuild@0.28.1: - resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==, tarball: https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz} + esbuild@0.28.0: + resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==, tarball: https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz} engines: {node: '>=18'} hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/aix-ppc64': 0.28.1 - '@esbuild/android-arm': 0.28.1 - '@esbuild/android-arm64': 0.28.1 - '@esbuild/android-x64': 0.28.1 - '@esbuild/darwin-arm64': 0.28.1 - '@esbuild/darwin-x64': 0.28.1 - '@esbuild/freebsd-arm64': 0.28.1 - '@esbuild/freebsd-x64': 0.28.1 - '@esbuild/linux-arm': 0.28.1 - '@esbuild/linux-arm64': 0.28.1 - '@esbuild/linux-ia32': 0.28.1 - '@esbuild/linux-loong64': 0.28.1 - '@esbuild/linux-mips64el': 0.28.1 - '@esbuild/linux-ppc64': 0.28.1 - '@esbuild/linux-riscv64': 0.28.1 - '@esbuild/linux-s390x': 0.28.1 - '@esbuild/linux-x64': 0.28.1 - '@esbuild/netbsd-arm64': 0.28.1 - '@esbuild/netbsd-x64': 0.28.1 - '@esbuild/openbsd-arm64': 0.28.1 - '@esbuild/openbsd-x64': 0.28.1 - '@esbuild/openharmony-arm64': 0.28.1 - '@esbuild/sunos-x64': 0.28.1 - '@esbuild/win32-arm64': 0.28.1 - '@esbuild/win32-ia32': 0.28.1 - '@esbuild/win32-x64': 0.28.1 - dev: true - - /escalade@3.2.0: + + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, tarball: https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz} engines: {node: '>=6'} - dev: true - /esprima@4.0.1: + esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, tarball: https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz} engines: {node: '>=4'} hasBin: true - dev: true - /estree-walker@3.0.3: + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, tarball: https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz} - dependencies: - '@types/estree': 1.0.9 - dev: true - /events@3.3.0: + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==, tarball: https://registry.npmjs.org/events/-/events-3.3.0.tgz} engines: {node: '>=0.8.x'} - dev: true - /expect-type@1.3.0: + expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==, tarball: https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz} engines: {node: '>=12.0.0'} - dev: true - /exsolve@1.0.8: + exsolve@1.0.8: resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==, tarball: https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz} - dev: true - /extendable-error@0.1.7: + extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==, tarball: https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz} - dev: true - /fast-glob@3.3.3: + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, tarball: https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz} engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - dev: true - /fast-xml-builder@1.2.0: + fast-xml-builder@1.2.0: resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==, tarball: https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz} - dependencies: - path-expression-matcher: 1.5.0 - xml-naming: 0.1.0 - dev: true - /fast-xml-parser@5.8.0: + fast-xml-parser@5.8.0: resolution: {integrity: sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==, tarball: https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz} hasBin: true - dependencies: - '@nodable/entities': 2.1.1 - fast-xml-builder: 1.2.0 - path-expression-matcher: 1.5.0 - strnum: 2.4.0 - xml-naming: 0.1.0 - dev: true - /fastq@1.20.1: + fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==, tarball: https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz} - dependencies: - reusify: 1.1.0 - dev: true - /fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, tarball: https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz} engines: {node: '>=12.0.0'} peerDependencies: @@ -1846,490 +1089,296 @@ packages: peerDependenciesMeta: picomatch: optional: true - dependencies: - picomatch: 4.0.4 - dev: true - /fill-range@7.1.1: + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, tarball: https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz} engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - /find-up@4.1.0: + find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, tarball: https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz} engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true - /fs-extra@7.0.1: + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==, tarball: https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz} engines: {node: '>=6 <7 || >=8'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - dev: true - /fs-extra@8.1.0: + fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==, tarball: https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz} engines: {node: '>=6 <7 || >=8'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - dev: true - /fsevents@2.3.3: + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - requiresBuild: true - dev: true - optional: true - /get-tsconfig@4.14.0: + get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==, tarball: https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz} - dependencies: - resolve-pkg-maps: 1.0.0 - dev: true - /giget@3.3.0: - resolution: {integrity: sha512-gzi2D96p+AMfDcmJHGDj3KJ9NRiwvlFAU5yfa3ROwWZmFUjX4P43x3BcyRaOMMLto1vUo7C+86+MFhYTl6Ryiw==, tarball: https://registry.npmjs.org/giget/-/giget-3.3.0.tgz} + giget@3.2.0: + resolution: {integrity: sha512-GvHTWcykIR/fP8cj8dMpuMMkvaeJfPvYnhq0oW+chSeIr+ldX21ifU2Ms6KBoyKZQZmVaUAAhQ2EZ68KJF8a7A==, tarball: https://registry.npmjs.org/giget/-/giget-3.2.0.tgz} hasBin: true - dev: true - /glob-parent@5.1.2: + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, tarball: https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz} engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - dev: true - /globby@11.1.0: + globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, tarball: https://registry.npmjs.org/globby/-/globby-11.1.0.tgz} engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - /graceful-fs@4.2.11: + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, tarball: https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz} - dev: true - /graphology-components@1.5.4(graphology-types@0.24.8): + graphology-components@1.5.4: resolution: {integrity: sha512-O37vC226wgnN0C6FUWHNe4fbTzaF51CcQjwX3naId/QTzH/PkUtXaanCShj9ws5Vju+z4u3zvSeEZE84Bo9jlA==, tarball: https://registry.npmjs.org/graphology-components/-/graphology-components-1.5.4.tgz} peerDependencies: graphology-types: '>=0.19.0' - dependencies: - graphology-indices: 0.17.0(graphology-types@0.24.8) - graphology-types: 0.24.8 - graphology-utils: 2.5.2(graphology-types@0.24.8) - dev: true - /graphology-indices@0.17.0(graphology-types@0.24.8): + graphology-indices@0.17.0: resolution: {integrity: sha512-A7RXuKQvdqSWOpn7ZVQo4S33O0vCfPBnUSf7FwE0zNCasqwZVUaCXePuWo5HBpWw68KJcwObZDHpFk6HKH6MYQ==, tarball: https://registry.npmjs.org/graphology-indices/-/graphology-indices-0.17.0.tgz} peerDependencies: graphology-types: '>=0.20.0' - dependencies: - graphology-types: 0.24.8 - graphology-utils: 2.5.2(graphology-types@0.24.8) - mnemonist: 0.39.8 - dev: true - /graphology-layout-forceatlas2@0.10.1(graphology-types@0.24.8): + graphology-layout-forceatlas2@0.10.1: resolution: {integrity: sha512-ogzBeF1FvWzjkikrIFwxhlZXvD2+wlY54lqhsrWprcdPjopM2J9HoMweUmIgwaTvY4bUYVimpSsOdvDv1gPRFQ==, tarball: https://registry.npmjs.org/graphology-layout-forceatlas2/-/graphology-layout-forceatlas2-0.10.1.tgz} peerDependencies: graphology-types: '>=0.19.0' - dependencies: - graphology-types: 0.24.8 - graphology-utils: 2.5.2(graphology-types@0.24.8) - dev: true - /graphology-metrics@2.4.0(graphology-types@0.24.8): + graphology-metrics@2.4.0: resolution: {integrity: sha512-7WOfOP+mFLCaTJx55Qg4eY+211vr1/b3D/R3biz3SXGhAaCVcWYkfabnmO4O4WBNWANEHtVnFrGgJ0kj6MM6xw==, tarball: https://registry.npmjs.org/graphology-metrics/-/graphology-metrics-2.4.0.tgz} peerDependencies: graphology-types: '>=0.20.0' - dependencies: - graphology-indices: 0.17.0(graphology-types@0.24.8) - graphology-shortest-path: 2.1.0(graphology-types@0.24.8) - graphology-types: 0.24.8 - graphology-utils: 2.5.2(graphology-types@0.24.8) - mnemonist: 0.39.8 - pandemonium: 2.4.1 - dev: true - /graphology-shortest-path@2.1.0(graphology-types@0.24.8): + graphology-shortest-path@2.1.0: resolution: {integrity: sha512-KbT9CTkP/u72vGEJzyRr24xFC7usI9Es3LMmCPHGwQ1KTsoZjxwA9lMKxfU0syvT/w+7fZUdB/Hu2wWYcJBm6Q==, tarball: https://registry.npmjs.org/graphology-shortest-path/-/graphology-shortest-path-2.1.0.tgz} peerDependencies: graphology-types: '>=0.20.0' - dependencies: - '@yomguithereal/helpers': 1.1.1 - graphology-indices: 0.17.0(graphology-types@0.24.8) - graphology-types: 0.24.8 - graphology-utils: 2.5.2(graphology-types@0.24.8) - mnemonist: 0.39.8 - dev: true - /graphology-types@0.24.8: + graphology-types@0.24.8: resolution: {integrity: sha512-hDRKYXa8TsoZHjgEaysSRyPdT6uB78Ci8WnjgbStlQysz7xR52PInxNsmnB7IBOM1BhikxkNyCVEFgmPKnpx3Q==, tarball: https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.8.tgz} - dev: true - /graphology-utils@2.5.2(graphology-types@0.24.8): + graphology-utils@2.5.2: resolution: {integrity: sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==, tarball: https://registry.npmjs.org/graphology-utils/-/graphology-utils-2.5.2.tgz} peerDependencies: graphology-types: '>=0.23.0' - dependencies: - graphology-types: 0.24.8 - dev: true - /graphology@0.26.0(graphology-types@0.24.8): + graphology@0.26.0: resolution: {integrity: sha512-8SSImzgUUYC89Z042s+0r/vMibY7GX/Emz4LDO5e7jYXhuoWfHISPFJYjpRLUSJGq6UQ6xlenvX1p/hJdfXuXg==, tarball: https://registry.npmjs.org/graphology/-/graphology-0.26.0.tgz} peerDependencies: graphology-types: '>=0.24.0' - dependencies: - events: 3.3.0 - graphology-types: 0.24.8 - dev: true - /has-flag@4.0.0: + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, tarball: https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz} engines: {node: '>=8'} - dev: true - /hookable@6.1.1: + hookable@6.1.1: resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==, tarball: https://registry.npmjs.org/hookable/-/hookable-6.1.1.tgz} - dev: true - /html-escaper@2.0.2: + html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, tarball: https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz} - dev: true - /human-id@4.2.0: + human-id@4.2.0: resolution: {integrity: sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==, tarball: https://registry.npmjs.org/human-id/-/human-id-4.2.0.tgz} hasBin: true - dev: true - /iconv-lite@0.7.2: + iconv-lite@0.7.2: resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==, tarball: https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz} engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: true - /ignore@5.3.2: + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, tarball: https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz} engines: {node: '>= 4'} - dev: true - /import-without-cache@0.2.5: + import-without-cache@0.2.5: resolution: {integrity: sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==, tarball: https://registry.npmjs.org/import-without-cache/-/import-without-cache-0.2.5.tgz} engines: {node: '>=20.19.0'} - dev: true - /internmap@2.0.3: + internmap@2.0.3: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==, tarball: https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz} engines: {node: '>=12'} - dev: true - /is-extglob@2.1.1: + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, tarball: https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz} engines: {node: '>=0.10.0'} - dev: true - /is-glob@4.0.3: + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, tarball: https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz} engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - /is-number@7.0.0: + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, tarball: https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz} engines: {node: '>=0.12.0'} - dev: true - /is-subdir@1.2.0: + is-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==, tarball: https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz} engines: {node: '>=4'} - dependencies: - better-path-resolve: 1.0.0 - dev: true - /is-windows@1.0.2: + is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==, tarball: https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz} engines: {node: '>=0.10.0'} - dev: true - /isexe@2.0.0: + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, tarball: https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz} - dev: true - /istanbul-lib-coverage@3.2.2: + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, tarball: https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz} engines: {node: '>=8'} - dev: true - /istanbul-lib-report@3.0.1: + istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, tarball: https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz} engines: {node: '>=10'} - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - dev: true - /istanbul-reports@3.2.0: + istanbul-reports@3.2.0: resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==, tarball: https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz} engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - dev: true - /jiti@2.7.0: + jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==, tarball: https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz} hasBin: true - dev: true - /js-tokens@10.0.0: + js-tokens@10.0.0: resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==, tarball: https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz} - dev: true - /js-yaml@3.14.2: + js-yaml@3.14.2: resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==, tarball: https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz} hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: true - /js-yaml@4.2.0: + js-yaml@4.2.0: resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==, tarball: https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz} hasBin: true - dependencies: - argparse: 2.0.1 - dev: true - /jsesc@3.1.0: + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==, tarball: https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz} engines: {node: '>=6'} hasBin: true - dev: true - /jsonc-parser@3.3.1: + jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==, tarball: https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz} - dev: true - /jsonfile@4.0.0: + jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==, tarball: https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz} - optionalDependencies: - graceful-fs: 4.2.11 - dev: true - /lightningcss-android-arm64@1.32.0: + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==, tarball: https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [android] - requiresBuild: true - dev: true - optional: true - /lightningcss-darwin-arm64@1.32.0: + lightningcss-darwin-arm64@1.32.0: resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==, tarball: https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /lightningcss-darwin-x64@1.32.0: + lightningcss-darwin-x64@1.32.0: resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==, tarball: https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /lightningcss-freebsd-x64@1.32.0: + lightningcss-freebsd-x64@1.32.0: resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==, tarball: https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - requiresBuild: true - dev: true - optional: true - /lightningcss-linux-arm-gnueabihf@1.32.0: + lightningcss-linux-arm-gnueabihf@1.32.0: resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==, tarball: https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - requiresBuild: true - dev: true - optional: true - /lightningcss-linux-arm64-gnu@1.32.0: + lightningcss-linux-arm64-gnu@1.32.0: resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==, tarball: https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /lightningcss-linux-arm64-musl@1.32.0: + lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==, tarball: https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [musl] - /lightningcss-linux-x64-gnu@1.32.0: + lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==, tarball: https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [glibc] - /lightningcss-linux-x64-musl@1.32.0: + lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==, tarball: https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true + libc: [musl] - /lightningcss-win32-arm64-msvc@1.32.0: + lightningcss-win32-arm64-msvc@1.32.0: resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==, tarball: https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - requiresBuild: true - dev: true - optional: true - /lightningcss-win32-x64-msvc@1.32.0: + lightningcss-win32-x64-msvc@1.32.0: resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==, tarball: https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - requiresBuild: true - dev: true - optional: true - /lightningcss@1.32.0: + lightningcss@1.32.0: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==, tarball: https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz} engines: {node: '>= 12.0.0'} - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 - dev: true - /locate-path@5.0.0: + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, tarball: https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz} engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true - /lodash.startcase@4.4.0: + lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==, tarball: https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz} - dev: true - /magic-string@0.30.21: + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, tarball: https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz} - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - dev: true - /magicast@0.5.3: + magicast@0.5.3: resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==, tarball: https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz} - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - source-map-js: 1.2.1 - dev: true - /make-dir@4.0.0: + make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, tarball: https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz} engines: {node: '>=10'} - dependencies: - semver: 7.8.4 - dev: true - /merge2@1.4.1: + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, tarball: https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz} engines: {node: '>= 8'} - dev: true - /micromatch@4.0.8: + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, tarball: https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz} engines: {node: '>=8.6'} - dependencies: - braces: 3.0.3 - picomatch: 2.3.2 - dev: true - /mnemonist@0.39.8: + mnemonist@0.39.8: resolution: {integrity: sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==, tarball: https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz} - dependencies: - obliterator: 2.0.5 - dev: true - /mri@1.2.0: + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==, tarball: https://registry.npmjs.org/mri/-/mri-1.2.0.tgz} engines: {node: '>=4'} - dev: true - /nanoid@3.3.12: + nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==, tarball: https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: true - /ngraph.events@1.4.0: + ngraph.events@1.4.0: resolution: {integrity: sha512-NeDGI4DSyjBNBRtA86222JoYietsmCXbs8CEB0dZ51Xeh4lhVl1y3wpWLumczvnha8sFQIW4E0vvVWwgmX2mGw==, tarball: https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.4.0.tgz} - dev: true - /ngraph.graph@20.1.2: + ngraph.graph@20.1.2: resolution: {integrity: sha512-W/G3GBR3Y5UxMLHTUCPP9v+pbtpzwuAEIqP5oZV+9IwgxAIEZwh+Foc60iPc1idlnK7Zxu0p3puxAyNmDvBd0Q==, tarball: https://registry.npmjs.org/ngraph.graph/-/ngraph.graph-20.1.2.tgz} - dependencies: - ngraph.events: 1.4.0 - dev: true - /ngraph.path@1.6.1: + ngraph.path@1.6.1: resolution: {integrity: sha512-NiA52wAoRo/t36/1dBAZkXPeX+rQ1mn82bc9LSfnfywGY9TxH/jXw3x3fZ1mOCblyln26lHtfHHEzssjjyX+aw==, tarball: https://registry.npmjs.org/ngraph.path/-/ngraph.path-1.6.1.tgz} - dev: true - /node-fetch@2.7.0: + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==, tarball: https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz} engines: {node: 4.x || >=6.0.0} peerDependencies: @@ -2337,204 +1386,135 @@ packages: peerDependenciesMeta: encoding: optional: true - dependencies: - whatwg-url: 5.0.0 - dev: true - /obliterator@2.0.5: + obliterator@2.0.5: resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==, tarball: https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz} - dev: true - /obug@2.1.2: + obug@2.1.2: resolution: {integrity: sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==, tarball: https://registry.npmjs.org/obug/-/obug-2.1.2.tgz} engines: {node: '>=12.20.0'} - dev: true - /ohash@2.0.11: + ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==, tarball: https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz} - dev: true - /outdent@0.5.0: + outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==, tarball: https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz} - dev: true - /p-filter@2.1.0: + p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==, tarball: https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz} engines: {node: '>=8'} - dependencies: - p-map: 2.1.0 - dev: true - /p-limit@2.3.0: + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, tarball: https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz} engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true - /p-locate@4.1.0: + p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, tarball: https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz} engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - /p-map@2.1.0: + p-map@2.1.0: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==, tarball: https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz} engines: {node: '>=6'} - dev: true - /p-try@2.2.0: + p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, tarball: https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz} engines: {node: '>=6'} - dev: true - /package-manager-detector@0.2.11: + package-manager-detector@0.2.11: resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==, tarball: https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz} - dependencies: - quansync: 0.2.11 - dev: true - /package-manager-detector@1.6.0: + package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==, tarball: https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz} - dev: true - /pandemonium@2.4.1: + pandemonium@2.4.1: resolution: {integrity: sha512-wRqjisUyiUfXowgm7MFH2rwJzKIr20rca5FsHXCMNm1W5YPP1hCtrZfgmQ62kP7OZ7Xt+cR858aB28lu5NX55g==, tarball: https://registry.npmjs.org/pandemonium/-/pandemonium-2.4.1.tgz} - dependencies: - mnemonist: 0.39.8 - dev: true - /path-exists@4.0.0: + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, tarball: https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz} engines: {node: '>=8'} - dev: true - /path-expression-matcher@1.5.0: + path-expression-matcher@1.5.0: resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==, tarball: https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz} engines: {node: '>=14.0.0'} - dev: true - /path-key@3.1.1: + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, tarball: https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz} engines: {node: '>=8'} - dev: true - /path-type@4.0.0: + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, tarball: https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz} engines: {node: '>=8'} - dev: true - /pathe@2.0.3: + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, tarball: https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz} - dev: true - /perfect-debounce@2.1.0: + perfect-debounce@2.1.0: resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==, tarball: https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz} - dev: true - /picocolors@1.1.1: + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, tarball: https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz} - dev: true - /picomatch@2.3.2: + picomatch@2.3.2: resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==, tarball: https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz} engines: {node: '>=8.6'} - dev: true - /picomatch@4.0.4: + picomatch@4.0.4: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==, tarball: https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz} engines: {node: '>=12'} - dev: true - /pify@4.0.1: + pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==, tarball: https://registry.npmjs.org/pify/-/pify-4.0.1.tgz} engines: {node: '>=6'} - dev: true - /pkg-types@2.3.1: + pkg-types@2.3.1: resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==, tarball: https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.1.tgz} - dependencies: - confbox: 0.2.4 - exsolve: 1.0.8 - pathe: 2.0.3 - dev: true - /postcss@8.5.15: + postcss@8.5.15: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==, tarball: https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz} engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.12 - picocolors: 1.1.1 - source-map-js: 1.2.1 - dev: true - /prettier@2.8.8: + prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==, tarball: https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz} engines: {node: '>=10.13.0'} hasBin: true - dev: true - /publint@0.3.21: + publint@0.3.21: resolution: {integrity: sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ==, tarball: https://registry.npmjs.org/publint/-/publint-0.3.21.tgz} engines: {node: '>=18'} hasBin: true - dependencies: - '@publint/pack': 0.1.4 - package-manager-detector: 1.6.0 - picocolors: 1.1.1 - sade: 1.8.1 - dev: true - /quansync@0.2.11: + quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==, tarball: https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz} - dev: true - /quansync@1.0.0: + quansync@1.0.0: resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==, tarball: https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz} - dev: true - /queue-microtask@1.2.3: + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, tarball: https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz} - dev: true - /rc9@3.0.1: + rc9@3.0.1: resolution: {integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==, tarball: https://registry.npmjs.org/rc9/-/rc9-3.0.1.tgz} - dependencies: - defu: 6.1.7 - destr: 2.0.5 - dev: true - /read-yaml-file@1.1.0: + read-yaml-file@1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==, tarball: https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz} engines: {node: '>=6'} - dependencies: - graceful-fs: 4.2.11 - js-yaml: 3.14.2 - pify: 4.0.1 - strip-bom: 3.0.0 - dev: true - /readdirp@5.0.0: + readdirp@5.0.0: resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==, tarball: https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz} engines: {node: '>= 20.19.0'} - dev: true - /resolve-from@5.0.0: + resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, tarball: https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz} engines: {node: '>=8'} - dev: true - /resolve-pkg-maps@1.0.0: + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==, tarball: https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz} - dev: true - /reusify@1.1.0: + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, tarball: https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true - /rolldown-plugin-dts@0.20.0(rolldown@1.0.0-beta.57)(typescript@5.9.3): + rolldown-plugin-dts@0.20.0: resolution: {integrity: sha512-cLAY1kN2ilTYMfZcFlGWbXnu6Nb+8uwUBsi+Mjbh4uIx7IN8uMOmJ7RxrrRgPsO4H7eSz3E+JwGoL1gyugiyUA==, tarball: https://registry.npmjs.org/rolldown-plugin-dts/-/rolldown-plugin-dts-0.20.0.tgz} engines: {node: '>=20.19.0'} peerDependencies: @@ -2552,239 +1532,118 @@ packages: optional: true vue-tsc: optional: true - dependencies: - '@babel/generator': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - ast-kit: 2.2.0 - birpc: 4.0.0 - dts-resolver: 2.1.3 - get-tsconfig: 4.14.0 - obug: 2.1.2 - rolldown: 1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) - typescript: 5.9.3 - transitivePeerDependencies: - - oxc-resolver - dev: true - /rolldown@1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0): + rolldown@1.0.0-beta.57: resolution: {integrity: sha512-lMMxcNN71GMsSko8RyeTaFoATHkCh4IWU7pYF73ziMYjhHZWfVesC6GQ+iaJCvZmVjvgSks9Ks1aaqEkBd8udg==, tarball: https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.57.tgz} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - dependencies: - '@oxc-project/types': 0.103.0 - '@rolldown/pluginutils': 1.0.0-beta.57 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.57 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.57 - '@rolldown/binding-darwin-x64': 1.0.0-beta.57 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.57 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.57 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.57 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.57 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.57 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.57 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.57 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.57 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.57 - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' - dev: true - /rolldown@1.0.0-rc.17: + rolldown@1.0.0-rc.17: resolution: {integrity: sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==, tarball: https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - dependencies: - '@oxc-project/types': 0.127.0 - '@rolldown/pluginutils': 1.0.0-rc.17 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.17 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.17 - '@rolldown/binding-darwin-x64': 1.0.0-rc.17 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.17 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 - dev: true - /rolldown@1.0.3: + rolldown@1.0.3: resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==, tarball: https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - dependencies: - '@oxc-project/types': 0.133.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.3 - '@rolldown/binding-darwin-arm64': 1.0.3 - '@rolldown/binding-darwin-x64': 1.0.3 - '@rolldown/binding-freebsd-x64': 1.0.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 - '@rolldown/binding-linux-arm64-gnu': 1.0.3 - '@rolldown/binding-linux-arm64-musl': 1.0.3 - '@rolldown/binding-linux-ppc64-gnu': 1.0.3 - '@rolldown/binding-linux-s390x-gnu': 1.0.3 - '@rolldown/binding-linux-x64-gnu': 1.0.3 - '@rolldown/binding-linux-x64-musl': 1.0.3 - '@rolldown/binding-openharmony-arm64': 1.0.3 - '@rolldown/binding-wasm32-wasi': 1.0.3 - '@rolldown/binding-win32-arm64-msvc': 1.0.3 - '@rolldown/binding-win32-x64-msvc': 1.0.3 - dev: true - /run-parallel@1.2.0: + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, tarball: https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz} - dependencies: - queue-microtask: 1.2.3 - dev: true - /sade@1.8.1: + sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==, tarball: https://registry.npmjs.org/sade/-/sade-1.8.1.tgz} engines: {node: '>=6'} - dependencies: - mri: 1.2.0 - dev: true - /safer-buffer@2.1.2: + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, tarball: https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz} - dev: true - /semver@7.8.4: + semver@7.8.4: resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==, tarball: https://registry.npmjs.org/semver/-/semver-7.8.4.tgz} engines: {node: '>=10'} hasBin: true - dev: true - /shebang-command@2.0.0: + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, tarball: https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz} engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: true - /shebang-regex@3.0.0: + shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, tarball: https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz} engines: {node: '>=8'} - dev: true - /siginfo@2.0.0: + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, tarball: https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz} - dev: true - /signal-exit@4.1.0: + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, tarball: https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz} engines: {node: '>=14'} - dev: true - /slash@3.0.0: + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, tarball: https://registry.npmjs.org/slash/-/slash-3.0.0.tgz} engines: {node: '>=8'} - dev: true - /source-map-js@1.2.1: + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, tarball: https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz} engines: {node: '>=0.10.0'} - dev: true - /spawndamnit@3.0.1: + spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==, tarball: https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz} - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - dev: true - /sprintf-js@1.0.3: + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, tarball: https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz} - dev: true - /stackback@0.0.2: + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, tarball: https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz} - dev: true - /std-env@4.1.0: + std-env@4.1.0: resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==, tarball: https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz} - dev: true - /strip-ansi@6.0.1: + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, tarball: https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz} engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true - /strip-bom@3.0.0: + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, tarball: https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz} engines: {node: '>=4'} - dev: true - /strnum@2.4.0: + strnum@2.4.0: resolution: {integrity: sha512-sHrVyWWdq28RbhjuJdZsA1SnGRJV6NiXbk6AXBxDOsgAcA+lmpUZCYjOdLBxkXMwis6RRe7dlZt4VlIWFVzkmg==, tarball: https://registry.npmjs.org/strnum/-/strnum-2.4.0.tgz} - dependencies: - anynum: 1.0.0 - dev: true - /supports-color@7.2.0: + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, tarball: https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz} engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - dev: true - /term-size@2.2.1: + term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==, tarball: https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz} engines: {node: '>=8'} - dev: true - /tinybench@2.9.0: + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==, tarball: https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz} - dev: true - /tinyexec@1.2.4: + tinyexec@1.2.4: resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==, tarball: https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz} engines: {node: '>=18'} - dev: true - /tinyglobby@0.2.17: + tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==, tarball: https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz} engines: {node: '>=12.0.0'} - dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - dev: true - /tinyrainbow@3.1.0: + tinyrainbow@3.1.0: resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==, tarball: https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz} engines: {node: '>=14.0.0'} - dev: true - /to-regex-range@5.0.1: + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, tarball: https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz} engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - /tr46@0.0.3: + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, tarball: https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz} - dev: true - /tree-kill@1.2.2: + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==, tarball: https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz} hasBin: true - dev: true - /tsdown@0.18.4(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)(publint@0.3.21)(typescript@5.9.3): + tsdown@0.18.4: resolution: {integrity: sha512-J/tRS6hsZTkvqmt4+xdELUCkQYDuUCXgBv0fw3ImV09WPGbEKfsPD65E+WUjSu3E7Z6tji9XZ1iWs8rbGqB/ZA==, tarball: https://registry.npmjs.org/tsdown/-/tsdown-0.18.4.tgz} engines: {node: '>=20.19.0'} hasBin: true @@ -2808,73 +1667,31 @@ packages: optional: true unplugin-unused: optional: true - dependencies: - ansis: 4.3.1 - cac: 6.7.14 - defu: 6.1.7 - empathic: 2.0.1 - hookable: 6.1.1 - import-without-cache: 0.2.5 - obug: 2.1.2 - picomatch: 4.0.4 - publint: 0.3.21 - rolldown: 1.0.0-beta.57(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) - rolldown-plugin-dts: 0.20.0(rolldown@1.0.0-beta.57)(typescript@5.9.3) - semver: 7.8.4 - tinyexec: 1.2.4 - tinyglobby: 0.2.17 - tree-kill: 1.2.2 - typescript: 5.9.3 - unconfig-core: 7.5.0 - unrun: 0.2.39 - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' - - '@ts-macro/tsc' - - '@typescript/native-preview' - - oxc-resolver - - synckit - - vue-tsc - dev: true - /tslib@2.8.1: + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, tarball: https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz} - dev: true - optional: true - /tsx@4.22.4: + tsx@4.22.4: resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==, tarball: https://registry.npmjs.org/tsx/-/tsx-4.22.4.tgz} engines: {node: '>=18.0.0'} hasBin: true - dependencies: - esbuild: 0.28.1 - optionalDependencies: - fsevents: 2.3.3 - dev: true - /typescript@5.9.3: + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==, tarball: https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz} engines: {node: '>=14.17'} hasBin: true - dev: true - /unconfig-core@7.5.0: + unconfig-core@7.5.0: resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==, tarball: https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.5.0.tgz} - dependencies: - '@quansync/fs': 1.0.0 - quansync: 1.0.0 - dev: true - /undici-types@7.24.6: + undici-types@7.24.6: resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==, tarball: https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz} - dev: true - /universalify@0.1.2: + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==, tarball: https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz} engines: {node: '>= 4.0.0'} - dev: true - /unrun@0.2.39: + unrun@0.2.39: resolution: {integrity: sha512-h9FxYVpztY/wwq+bauLOh6Y3CWu2IVeRLq5lxzneBiIU9Tn86OGp9xiQrGhnYspAmg5dzdY0Cc8+Y70kuTARCg==, tarball: https://registry.npmjs.org/unrun/-/unrun-0.2.39.tgz} engines: {node: '>=20.19.0'} hasBin: true @@ -2883,11 +1700,8 @@ packages: peerDependenciesMeta: synckit: optional: true - dependencies: - rolldown: 1.0.0-rc.17 - dev: true - /vite@8.0.16(@types/node@25.9.3)(tsx@4.22.4): + vite@8.0.16: resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==, tarball: https://registry.npmjs.org/vite/-/vite-8.0.16.tgz} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -2929,19 +1743,8 @@ packages: optional: true yaml: optional: true - dependencies: - '@types/node': 25.9.3 - lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.15 - rolldown: 1.0.3 - tinyglobby: 0.2.17 - tsx: 4.22.4 - optionalDependencies: - fsevents: 2.3.3 - dev: true - /vitest@4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16): + vitest@4.1.8: resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==, tarball: https://registry.npmjs.org/vitest/-/vitest-4.1.8.tgz} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true @@ -2981,85 +1784,1565 @@ packages: optional: true jsdom: optional: true - dependencies: - '@types/node': 25.9.3 - '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) - '@vitest/expect': 4.1.8 - '@vitest/mocker': 4.1.8(vite@8.0.16) - '@vitest/pretty-format': 4.1.8 - '@vitest/runner': 4.1.8 - '@vitest/snapshot': 4.1.8 - '@vitest/spy': 4.1.8 - '@vitest/utils': 4.1.8 - es-module-lexer: 2.1.0 - expect-type: 1.3.0 - magic-string: 0.30.21 - obug: 2.1.2 - pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.1.0 - tinybench: 2.9.0 - tinyexec: 1.2.4 - tinyglobby: 0.2.17 - tinyrainbow: 3.1.0 - vite: 8.0.16(@types/node@25.9.3)(tsx@4.22.4) - why-is-node-running: 2.3.0 - transitivePeerDependencies: - - msw - dev: true - /webcola@3.4.0: + webcola@3.4.0: resolution: {integrity: sha512-4BiLXjXw3SJHo3Xd+rF+7fyClT6n7I+AR6TkBqyQ4kTsePSAMDLRCXY1f3B/kXJeP9tYn4G1TblxTO+jAt0gaw==, tarball: https://registry.npmjs.org/webcola/-/webcola-3.4.0.tgz} - dependencies: - d3-dispatch: 1.0.6 - d3-drag: 1.2.5 - d3-shape: 1.3.7 - d3-timer: 1.0.10 - dev: true - /webidl-conversions@3.0.1: + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, tarball: https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz} - dev: true - /whatwg-url@5.0.0: + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, tarball: https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: true - /which@2.0.2: + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, tarball: https://registry.npmjs.org/which/-/which-2.0.2.tgz} engines: {node: '>= 8'} hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - /why-is-node-running@2.3.0: + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==, tarball: https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz} engines: {node: '>=8'} hasBin: true - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - dev: true - /xml-naming@0.1.0: + xml-naming@0.1.0: resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==, tarball: https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz} engines: {node: '>=16.0.0'} - dev: true - /xstate@5.32.0: + xstate@5.32.0: resolution: {integrity: sha512-zsk73aWGmxn9z34P0kbiod5JwTvdYRW3+IDxITq8sd9+VWwMyW7BUzpplnYy9mIEXa6V8IMDv7Hy4m0mhT5+2Q==, tarball: https://registry.npmjs.org/xstate/-/xstate-5.32.0.tgz} - dev: true - /yaml@2.9.0: + yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==, tarball: https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz} engines: {node: '>= 14.6'} hasBin: true - dev: true - /zod@4.4.3: + zod@4.4.3: resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==, tarball: https://registry.npmjs.org/zod/-/zod-4.4.3.tgz} - dev: true + +snapshots: + + '@babel/generator@7.29.7': + dependencies: + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/parser@7.29.7': + dependencies: + '@babel/types': 7.29.7 + + '@babel/runtime@7.29.7': {} + + '@babel/types@7.29.7': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@bcoe/v8-coverage@1.0.2': {} + + '@changesets/apply-release-plan@7.1.1': + dependencies: + '@changesets/config': 3.1.4 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.8.4 + + '@changesets/assemble-release-plan@6.0.10': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.8.4 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/changelog-github@0.5.2': + dependencies: + '@changesets/get-github-info': 0.7.0 + '@changesets/types': 6.1.0 + dotenv: 8.6.0 + transitivePeerDependencies: + - encoding + + '@changesets/cli@2.31.0(@types/node@25.9.3)': + dependencies: + '@changesets/apply-release-plan': 7.1.1 + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.4 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/get-release-plan': 4.0.16 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@25.9.3) + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.8.4 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' + + '@changesets/config@3.1.4': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.4': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.8.4 + + '@changesets/get-github-info@0.7.0': + dependencies: + dataloader: 1.4.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + '@changesets/get-release-plan@4.0.16': + dependencies: + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/config': 3.1.4 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.3': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.2.0 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.7': + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.3 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.4.0': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.2.0 + prettier: 2.8.8 + + '@dagrejs/dagre@3.0.0': + dependencies: + '@dagrejs/graphlib': 4.0.1 + + '@dagrejs/graphlib@4.0.1': {} + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.28.0': + optional: true + + '@esbuild/android-arm64@0.28.0': + optional: true + + '@esbuild/android-arm@0.28.0': + optional: true + + '@esbuild/android-x64@0.28.0': + optional: true + + '@esbuild/darwin-arm64@0.28.0': + optional: true + + '@esbuild/darwin-x64@0.28.0': + optional: true + + '@esbuild/freebsd-arm64@0.28.0': + optional: true + + '@esbuild/freebsd-x64@0.28.0': + optional: true + + '@esbuild/linux-arm64@0.28.0': + optional: true + + '@esbuild/linux-arm@0.28.0': + optional: true + + '@esbuild/linux-ia32@0.28.0': + optional: true + + '@esbuild/linux-loong64@0.28.0': + optional: true + + '@esbuild/linux-mips64el@0.28.0': + optional: true + + '@esbuild/linux-ppc64@0.28.0': + optional: true + + '@esbuild/linux-riscv64@0.28.0': + optional: true + + '@esbuild/linux-s390x@0.28.0': + optional: true + + '@esbuild/linux-x64@0.28.0': + optional: true + + '@esbuild/netbsd-arm64@0.28.0': + optional: true + + '@esbuild/netbsd-x64@0.28.0': + optional: true + + '@esbuild/openbsd-arm64@0.28.0': + optional: true + + '@esbuild/openbsd-x64@0.28.0': + optional: true + + '@esbuild/openharmony-arm64@0.28.0': + optional: true + + '@esbuild/sunos-x64@0.28.0': + optional: true + + '@esbuild/win32-arm64@0.28.0': + optional: true + + '@esbuild/win32-ia32@0.28.0': + optional: true + + '@esbuild/win32-x64@0.28.0': + optional: true + + '@hpcc-js/wasm-graphviz@1.22.0': {} + + '@inquirer/external-editor@1.0.3(@types/node@25.9.3)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 25.9.3 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.29.7 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.29.7 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + optional: true + + '@nodable/entities@2.1.1': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@oxc-project/types@0.103.0': {} + + '@oxc-project/types@0.127.0': {} + + '@oxc-project/types@0.133.0': {} + + '@publint/pack@0.1.4': {} + + '@quansync/fs@1.0.0': + dependencies: + quansync: 1.0.0 + + '@rolldown/binding-android-arm64@1.0.0-beta.57': + optional: true + + '@rolldown/binding-android-arm64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-android-arm64@1.0.3': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.57': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.3': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.57': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-darwin-x64@1.0.3': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.57': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.3': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.57': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.57': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.57': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.3': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.57': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.57': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.3': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.57': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.3': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.57(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.3': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.57': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.3': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.57': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.3': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.57': {} + + '@rolldown/pluginutils@1.0.0-rc.17': {} + + '@rolldown/pluginutils@1.0.1': {} + + '@standard-schema/spec@1.1.0': {} + + '@tybys/wasm-util@0.10.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/d3-array@3.2.2': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-force@3.0.10': {} + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.9': {} + + '@types/node@12.20.55': {} + + '@types/node@25.9.3': + dependencies: + undici-types: 7.24.6 + + '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.1.8 + ast-v8-to-istanbul: 1.0.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + magicast: 0.5.3 + obug: 2.1.2 + std-env: 4.1.0 + tinyrainbow: 3.1.0 + vitest: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)) + + '@vitest/expect@4.1.8': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + chai: 6.2.2 + tinyrainbow: 3.1.0 + + '@vitest/mocker@4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0) + + '@vitest/pretty-format@4.1.8': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.8': + dependencies: + '@vitest/utils': 4.1.8 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.8': + dependencies: + '@vitest/pretty-format': 4.1.8 + '@vitest/utils': 4.1.8 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.8': {} + + '@vitest/utils@4.1.8': + dependencies: + '@vitest/pretty-format': 4.1.8 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + + '@xyflow/system@0.0.75': + dependencies: + '@types/d3-drag': 3.0.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-zoom: 3.0.0 + + '@yomguithereal/helpers@1.1.1': {} + + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansis@4.3.1: {} + + anynum@1.0.0: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + args-tokenizer@0.3.0: {} + + array-union@2.1.0: {} + + assertion-error@2.0.1: {} + + ast-kit@2.2.0: + dependencies: + '@babel/parser': 7.29.7 + pathe: 2.0.3 + + ast-v8-to-istanbul@1.0.4: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + birpc@4.0.0: {} + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + bumpp@10.4.1(magicast@0.5.3): + dependencies: + ansis: 4.3.1 + args-tokenizer: 0.3.0 + c12: 3.3.4(magicast@0.5.3) + cac: 6.7.14 + escalade: 3.2.0 + jsonc-parser: 3.3.1 + package-manager-detector: 1.6.0 + semver: 7.8.4 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + yaml: 2.9.0 + transitivePeerDependencies: + - magicast + + c12@3.3.4(magicast@0.5.3): + dependencies: + chokidar: 5.0.0 + confbox: 0.2.4 + defu: 6.1.7 + dotenv: 17.4.2 + exsolve: 1.0.8 + giget: 3.2.0 + jiti: 2.7.0 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.1 + rc9: 3.0.1 + optionalDependencies: + magicast: 0.5.3 + + cac@6.7.14: {} + + chai@6.2.2: {} + + chardet@2.1.1: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + confbox@0.2.4: {} + + convert-source-map@2.0.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cytoscape@3.34.0: {} + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-color@3.1.0: {} + + d3-dispatch@1.0.6: {} + + d3-dispatch@3.0.1: {} + + d3-drag@1.2.5: + dependencies: + d3-dispatch: 1.0.6 + d3-selection: 1.4.2 + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-ease@3.0.1: {} + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-quadtree@3.0.1: {} + + d3-selection@1.4.2: {} + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-timer@1.0.10: {} + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + dataloader@1.4.0: {} + + defu@6.1.7: {} + + destr@2.0.5: {} + + detect-indent@6.1.0: {} + + detect-libc@2.1.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dotenv@17.4.2: {} + + dotenv@8.6.0: {} + + dotparser@1.1.1: {} + + dts-resolver@2.1.3: {} + + elkjs@0.11.1: {} + + empathic@2.0.1: {} + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + es-module-lexer@2.1.0: {} + + esbuild@0.28.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.0 + '@esbuild/android-arm': 0.28.0 + '@esbuild/android-arm64': 0.28.0 + '@esbuild/android-x64': 0.28.0 + '@esbuild/darwin-arm64': 0.28.0 + '@esbuild/darwin-x64': 0.28.0 + '@esbuild/freebsd-arm64': 0.28.0 + '@esbuild/freebsd-x64': 0.28.0 + '@esbuild/linux-arm': 0.28.0 + '@esbuild/linux-arm64': 0.28.0 + '@esbuild/linux-ia32': 0.28.0 + '@esbuild/linux-loong64': 0.28.0 + '@esbuild/linux-mips64el': 0.28.0 + '@esbuild/linux-ppc64': 0.28.0 + '@esbuild/linux-riscv64': 0.28.0 + '@esbuild/linux-s390x': 0.28.0 + '@esbuild/linux-x64': 0.28.0 + '@esbuild/netbsd-arm64': 0.28.0 + '@esbuild/netbsd-x64': 0.28.0 + '@esbuild/openbsd-arm64': 0.28.0 + '@esbuild/openbsd-x64': 0.28.0 + '@esbuild/openharmony-arm64': 0.28.0 + '@esbuild/sunos-x64': 0.28.0 + '@esbuild/win32-arm64': 0.28.0 + '@esbuild/win32-ia32': 0.28.0 + '@esbuild/win32-x64': 0.28.0 + + escalade@3.2.0: {} + + esprima@4.0.1: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + events@3.3.0: {} + + expect-type@1.3.0: {} + + exsolve@1.0.8: {} + + extendable-error@0.1.7: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-xml-builder@1.2.0: + dependencies: + path-expression-matcher: 1.5.0 + xml-naming: 0.1.0 + + fast-xml-parser@5.8.0: + dependencies: + '@nodable/entities': 2.1.1 + fast-xml-builder: 1.2.0 + path-expression-matcher: 1.5.0 + strnum: 2.4.0 + xml-naming: 0.1.0 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fsevents@2.3.3: + optional: true + + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + giget@3.2.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + graceful-fs@4.2.11: {} + + graphology-components@1.5.4(graphology-types@0.24.8): + dependencies: + graphology-indices: 0.17.0(graphology-types@0.24.8) + graphology-types: 0.24.8 + graphology-utils: 2.5.2(graphology-types@0.24.8) + + graphology-indices@0.17.0(graphology-types@0.24.8): + dependencies: + graphology-types: 0.24.8 + graphology-utils: 2.5.2(graphology-types@0.24.8) + mnemonist: 0.39.8 + + graphology-layout-forceatlas2@0.10.1(graphology-types@0.24.8): + dependencies: + graphology-types: 0.24.8 + graphology-utils: 2.5.2(graphology-types@0.24.8) + + graphology-metrics@2.4.0(graphology-types@0.24.8): + dependencies: + graphology-indices: 0.17.0(graphology-types@0.24.8) + graphology-shortest-path: 2.1.0(graphology-types@0.24.8) + graphology-types: 0.24.8 + graphology-utils: 2.5.2(graphology-types@0.24.8) + mnemonist: 0.39.8 + pandemonium: 2.4.1 + + graphology-shortest-path@2.1.0(graphology-types@0.24.8): + dependencies: + '@yomguithereal/helpers': 1.1.1 + graphology-indices: 0.17.0(graphology-types@0.24.8) + graphology-types: 0.24.8 + graphology-utils: 2.5.2(graphology-types@0.24.8) + mnemonist: 0.39.8 + + graphology-types@0.24.8: {} + + graphology-utils@2.5.2(graphology-types@0.24.8): + dependencies: + graphology-types: 0.24.8 + + graphology@0.26.0(graphology-types@0.24.8): + dependencies: + events: 3.3.0 + graphology-types: 0.24.8 + + has-flag@4.0.0: {} + + hookable@6.1.1: {} + + html-escaper@2.0.2: {} + + human-id@4.2.0: {} + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + import-without-cache@0.2.5: {} + + internmap@2.0.3: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-windows@1.0.2: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jiti@2.7.0: {} + + js-tokens@10.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.2.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + jsonc-parser@3.3.1: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.startcase@4.4.0: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.5.3: + dependencies: + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.8.4 + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mnemonist@0.39.8: + dependencies: + obliterator: 2.0.5 + + mri@1.2.0: {} + + nanoid@3.3.12: {} + + ngraph.events@1.4.0: {} + + ngraph.graph@20.1.2: + dependencies: + ngraph.events: 1.4.0 + + ngraph.path@1.6.1: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + obliterator@2.0.5: {} + + obug@2.1.2: {} + + ohash@2.0.11: {} + + outdent@0.5.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-map@2.1.0: {} + + p-try@2.2.0: {} + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + + package-manager-detector@1.6.0: {} + + pandemonium@2.4.1: + dependencies: + mnemonist: 0.39.8 + + path-exists@4.0.0: {} + + path-expression-matcher@1.5.0: {} + + path-key@3.1.1: {} + + path-type@4.0.0: {} + + pathe@2.0.3: {} + + perfect-debounce@2.1.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.4: {} + + pify@4.0.1: {} + + pkg-types@2.3.1: + dependencies: + confbox: 0.2.4 + exsolve: 1.0.8 + pathe: 2.0.3 + + postcss@8.5.15: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@2.8.8: {} + + publint@0.3.21: + dependencies: + '@publint/pack': 0.1.4 + package-manager-detector: 1.6.0 + picocolors: 1.1.1 + sade: 1.8.1 + + quansync@0.2.11: {} + + quansync@1.0.0: {} + + queue-microtask@1.2.3: {} + + rc9@3.0.1: + dependencies: + defu: 6.1.7 + destr: 2.0.5 + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 + + readdirp@5.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + reusify@1.1.0: {} + + rolldown-plugin-dts@0.20.0(rolldown@1.0.0-beta.57(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(typescript@5.9.3): + dependencies: + '@babel/generator': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + ast-kit: 2.2.0 + birpc: 4.0.0 + dts-resolver: 2.1.3 + get-tsconfig: 4.14.0 + obug: 2.1.2 + rolldown: 1.0.0-beta.57(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - oxc-resolver + + rolldown@1.0.0-beta.57(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): + dependencies: + '@oxc-project/types': 0.103.0 + '@rolldown/pluginutils': 1.0.0-beta.57 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-beta.57 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.57 + '@rolldown/binding-darwin-x64': 1.0.0-beta.57 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.57 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.57 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.57 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.57 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.57 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.57 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.57 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.57(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.57 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.57 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + + rolldown@1.0.0-rc.17: + dependencies: + '@oxc-project/types': 0.127.0 + '@rolldown/pluginutils': 1.0.0-rc.17 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-x64': 1.0.0-rc.17 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.17 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 + + rolldown@1.0.3: + dependencies: + '@oxc-project/types': 0.133.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.3 + '@rolldown/binding-darwin-arm64': 1.0.3 + '@rolldown/binding-darwin-x64': 1.0.3 + '@rolldown/binding-freebsd-x64': 1.0.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.3 + '@rolldown/binding-linux-arm64-musl': 1.0.3 + '@rolldown/binding-linux-ppc64-gnu': 1.0.3 + '@rolldown/binding-linux-s390x-gnu': 1.0.3 + '@rolldown/binding-linux-x64-gnu': 1.0.3 + '@rolldown/binding-linux-x64-musl': 1.0.3 + '@rolldown/binding-openharmony-arm64': 1.0.3 + '@rolldown/binding-wasm32-wasi': 1.0.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.3 + '@rolldown/binding-win32-x64-msvc': 1.0.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + safer-buffer@2.1.2: {} + + semver@7.8.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + slash@3.0.0: {} + + source-map-js@1.2.1: {} + + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + + stackback@0.0.2: {} + + std-env@4.1.0: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + + strnum@2.4.0: + dependencies: + anynum: 1.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + term-size@2.2.1: {} + + tinybench@2.9.0: {} + + tinyexec@1.2.4: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tinyrainbow@3.1.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@0.0.3: {} + + tree-kill@1.2.2: {} + + tsdown@0.18.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(publint@0.3.21)(typescript@5.9.3): + dependencies: + ansis: 4.3.1 + cac: 6.7.14 + defu: 6.1.7 + empathic: 2.0.1 + hookable: 6.1.1 + import-without-cache: 0.2.5 + obug: 2.1.2 + picomatch: 4.0.4 + rolldown: 1.0.0-beta.57(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + rolldown-plugin-dts: 0.20.0(rolldown@1.0.0-beta.57(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0))(typescript@5.9.3) + semver: 7.8.4 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tree-kill: 1.2.2 + unconfig-core: 7.5.0 + unrun: 0.2.39 + optionalDependencies: + publint: 0.3.21 + typescript: 5.9.3 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + - '@ts-macro/tsc' + - '@typescript/native-preview' + - oxc-resolver + - synckit + - vue-tsc + + tslib@2.8.1: + optional: true + + tsx@4.22.4: + dependencies: + esbuild: 0.28.0 + optionalDependencies: + fsevents: 2.3.3 + + typescript@5.9.3: {} + + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + quansync: 1.0.0 + + undici-types@7.24.6: {} + + universalify@0.1.2: {} + + unrun@0.2.39: + dependencies: + rolldown: 1.0.0-rc.17 + + vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.15 + rolldown: 1.0.3 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 25.9.3 + esbuild: 0.28.0 + fsevents: 2.3.3 + jiti: 2.7.0 + tsx: 4.22.4 + yaml: 2.9.0 + + vitest@4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.8 + '@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.8 + '@vitest/runner': 4.1.8 + '@vitest/snapshot': 4.1.8 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.2 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.9.3 + '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) + transitivePeerDependencies: + - msw + + webcola@3.4.0: + dependencies: + d3-dispatch: 1.0.6 + d3-drag: 1.2.5 + d3-shape: 1.3.7 + d3-timer: 1.0.10 + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + xml-naming@0.1.0: {} + + xstate@5.32.0: {} + + yaml@2.9.0: {} + + zod@4.4.3: {}