From 35d3f1718c8a6b21e6f9e57e7698bddc855cda68 Mon Sep 17 00:00:00 2001 From: MFA-X-AI Date: Mon, 6 Apr 2026 14:32:54 +0900 Subject: [PATCH 1/9] Add xircuits-graph-viewer: pure SVG renderer for .xircuits workflow files --- xircuits-graph-viewer/.gitignore | 2 + xircuits-graph-viewer/README.md | 210 ++++++ .../__tests__/fixtures/HelloXircuits.xircuits | 623 ++++++++++++++++++ .../__tests__/parser.test.ts | 116 ++++ .../__tests__/render.test.ts | 146 ++++ xircuits-graph-viewer/demo/index.html | 19 + xircuits-graph-viewer/demo/package.json | 22 + xircuits-graph-viewer/demo/src/App.tsx | 41 ++ .../demo/src/fixtures/HelloXircuits.xircuits | 623 ++++++++++++++++++ xircuits-graph-viewer/demo/src/main.tsx | 5 + xircuits-graph-viewer/demo/tsconfig.json | 8 + xircuits-graph-viewer/demo/vite.config.ts | 6 + xircuits-graph-viewer/package.json | 13 + .../packages/core/package.json | 25 + .../packages/core/src/index.ts | 56 ++ .../packages/core/src/interaction/panZoom.ts | 99 +++ .../packages/core/src/layout/metrics.ts | 95 +++ .../packages/core/src/layout/viewBox.ts | 40 ++ .../packages/core/src/parser/classify.ts | 58 ++ .../packages/core/src/parser/parse.ts | 156 +++++ .../packages/core/src/parser/validate.ts | 40 ++ .../packages/core/src/render/colors.ts | 91 +++ .../packages/core/src/render/renderDefs.ts | 218 ++++++ .../packages/core/src/render/renderEdge.ts | 23 + .../packages/core/src/render/renderGraph.ts | 61 ++ .../packages/core/src/render/renderNode.ts | 117 ++++ .../packages/core/src/render/renderPort.ts | 83 +++ .../packages/core/src/render/symbols.ts | 46 ++ .../packages/core/src/svg/bezier.ts | 14 + .../packages/core/src/svg/builder.ts | 57 ++ .../packages/core/src/types.ts | 75 +++ .../packages/core/tsconfig.json | 8 + .../packages/react/package.json | 29 + .../packages/react/src/XircuitsGraph.tsx | 125 ++++ .../react/src/XircuitsGraphStatic.tsx | 76 +++ .../packages/react/src/index.ts | 4 + .../packages/react/tsconfig.json | 9 + xircuits-graph-viewer/pnpm-workspace.yaml | 3 + xircuits-graph-viewer/tsconfig.base.json | 17 + xircuits-graph-viewer/upload-demo/index.html | 93 +++ xircuits-graph-viewer/upload-demo/main.js | 113 ++++ .../upload-demo/package.json | 15 + xircuits-graph-viewer/vitest.config.ts | 7 + xircuits-graph-viewer/xircuits-hello.png | Bin 0 -> 243301 bytes 44 files changed, 3687 insertions(+) create mode 100644 xircuits-graph-viewer/.gitignore create mode 100644 xircuits-graph-viewer/README.md create mode 100644 xircuits-graph-viewer/__tests__/fixtures/HelloXircuits.xircuits create mode 100644 xircuits-graph-viewer/__tests__/parser.test.ts create mode 100644 xircuits-graph-viewer/__tests__/render.test.ts create mode 100644 xircuits-graph-viewer/demo/index.html create mode 100644 xircuits-graph-viewer/demo/package.json create mode 100644 xircuits-graph-viewer/demo/src/App.tsx create mode 100644 xircuits-graph-viewer/demo/src/fixtures/HelloXircuits.xircuits create mode 100644 xircuits-graph-viewer/demo/src/main.tsx create mode 100644 xircuits-graph-viewer/demo/tsconfig.json create mode 100644 xircuits-graph-viewer/demo/vite.config.ts create mode 100644 xircuits-graph-viewer/package.json create mode 100644 xircuits-graph-viewer/packages/core/package.json create mode 100644 xircuits-graph-viewer/packages/core/src/index.ts create mode 100644 xircuits-graph-viewer/packages/core/src/interaction/panZoom.ts create mode 100644 xircuits-graph-viewer/packages/core/src/layout/metrics.ts create mode 100644 xircuits-graph-viewer/packages/core/src/layout/viewBox.ts create mode 100644 xircuits-graph-viewer/packages/core/src/parser/classify.ts create mode 100644 xircuits-graph-viewer/packages/core/src/parser/parse.ts create mode 100644 xircuits-graph-viewer/packages/core/src/parser/validate.ts create mode 100644 xircuits-graph-viewer/packages/core/src/render/colors.ts create mode 100644 xircuits-graph-viewer/packages/core/src/render/renderDefs.ts create mode 100644 xircuits-graph-viewer/packages/core/src/render/renderEdge.ts create mode 100644 xircuits-graph-viewer/packages/core/src/render/renderGraph.ts create mode 100644 xircuits-graph-viewer/packages/core/src/render/renderNode.ts create mode 100644 xircuits-graph-viewer/packages/core/src/render/renderPort.ts create mode 100644 xircuits-graph-viewer/packages/core/src/render/symbols.ts create mode 100644 xircuits-graph-viewer/packages/core/src/svg/bezier.ts create mode 100644 xircuits-graph-viewer/packages/core/src/svg/builder.ts create mode 100644 xircuits-graph-viewer/packages/core/src/types.ts create mode 100644 xircuits-graph-viewer/packages/core/tsconfig.json create mode 100644 xircuits-graph-viewer/packages/react/package.json create mode 100644 xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx create mode 100644 xircuits-graph-viewer/packages/react/src/XircuitsGraphStatic.tsx create mode 100644 xircuits-graph-viewer/packages/react/src/index.ts create mode 100644 xircuits-graph-viewer/packages/react/tsconfig.json create mode 100644 xircuits-graph-viewer/pnpm-workspace.yaml create mode 100644 xircuits-graph-viewer/tsconfig.base.json create mode 100644 xircuits-graph-viewer/upload-demo/index.html create mode 100644 xircuits-graph-viewer/upload-demo/main.js create mode 100644 xircuits-graph-viewer/upload-demo/package.json create mode 100644 xircuits-graph-viewer/vitest.config.ts create mode 100644 xircuits-graph-viewer/xircuits-hello.png diff --git a/xircuits-graph-viewer/.gitignore b/xircuits-graph-viewer/.gitignore new file mode 100644 index 00000000..b9470778 --- /dev/null +++ b/xircuits-graph-viewer/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/xircuits-graph-viewer/README.md b/xircuits-graph-viewer/README.md new file mode 100644 index 00000000..de80c424 --- /dev/null +++ b/xircuits-graph-viewer/README.md @@ -0,0 +1,210 @@ +# xircuits-graph-viewer + +Pure SVG renderer for `.xircuits` workflow files. Parses the JSON format and produces self-contained SVG that visually matches the Xircuits editor. + +![HelloXircuits rendered](./xircuits-hello.png) + +## Packages + +| Package | npm | Purpose | +|---------|-----|---------| +| `xircuits-graph-core` | [![npm](https://img.shields.io/npm/v/xircuits-graph-core)](https://www.npmjs.com/package/xircuits-graph-core) | Parser + SVG renderer. Zero runtime deps. | +| `xircuits-graph-react` | [![npm](https://img.shields.io/npm/v/xircuits-graph-react)](https://www.npmjs.com/package/xircuits-graph-react) | React components (interactive + SSR-safe). | + +## Quick Start + +### React + +```bash +npm install xircuits-graph-core xircuits-graph-react +``` + +**Point it at a `.xircuits` file** — that's it: + +```tsx +import { XircuitsGraph } from 'xircuits-graph-react'; + +// src accepts any URL: uploaded file path, API endpoint, static asset, etc. + +``` + +With options: + +```tsx + console.log(node.name)} +/> +``` + +**Static rendering** (SSR-safe, no client JS needed): + +```tsx +import { XircuitsGraphStatic } from 'xircuits-graph-react'; + + +``` + +You can also pass pre-loaded JSON via `data` instead of `src`: + +```tsx +import workflow from './MyWorkflow.xircuits'; + + +``` + +### Core (framework-agnostic) + +Works with Svelte, Vue, plain HTML, Node.js — anything. + +```bash +npm install xircuits-graph-core +``` + +**From a URL** (browser): + +```js +import { renderFromUrl } from 'xircuits-graph-core'; + +const svg = await renderFromUrl('/workflows/MyWorkflow.xircuits', { theme: 'dark' }); +document.getElementById('viewer').innerHTML = svg; +``` + +**From JSON data**: + +```js +import { renderXircuits } from 'xircuits-graph-core'; + +const svg = renderXircuits(workflowJson, { theme: 'dark' }); +``` + +**With pan/zoom**: + +```js +import { parse, renderToElement } from 'xircuits-graph-core'; +import { attachPanZoom } from 'xircuits-graph-core/interaction'; + +const res = await fetch('/workflows/MyWorkflow.xircuits'); +const svg = renderToElement(parse(await res.json()), { theme: 'dark' }); +document.body.appendChild(svg); +const { destroy } = attachPanZoom(svg); +``` + +### Docusaurus + +```mdx +import { XircuitsGraphStatic } from 'xircuits-graph-react'; + +# My Workflow + + +``` + +For interactive mode, wrap with `BrowserOnly`: + +```mdx +import BrowserOnly from '@docusaurus/BrowserOnly'; + + + {() => { + const { XircuitsGraph } = require('xircuits-graph-react'); + return ; + }} + +``` + +## API + +### Core + +| Function | Description | +|----------|-------------| +| `renderFromUrl(url, options?)` | Fetch a `.xircuits` URL and return SVG string. Browser only. | +| `renderXircuits(json, options?)` | One-shot: parse JSON + render to SVG string. | +| `parse(json)` | Parse `.xircuits` JSON into `XGraph`. | +| `renderToString(graph, options?)` | Render `XGraph` to SVG string. Works in Node.js and browsers. | +| `renderToElement(graph, options?)` | Render `XGraph` to DOM `SVGSVGElement`. Browser only. | +| `validate(json)` | Validate a `.xircuits` file without parsing. | +| `attachPanZoom(svg, options?)` | Add mouse/touch pan and zoom to rendered SVG. | + +### React + +| Component | Props | Description | +|-----------|-------|-------------| +| `` | `src` or `data`, `theme`, `interactive`, `height`, ... | Interactive viewer with pan/zoom. | +| `` | `src` or `data`, `theme`, `height`, ... | Static SVG output, SSR-safe. | + +### `RenderOptions` + +```ts +{ + theme?: 'dark' | 'light'; // default: 'dark' + width?: number; // SVG width + height?: number; // SVG height + padding?: number; // viewport padding (default: 40) + fitView?: boolean; // auto-fit viewBox (default: true) + className?: string; // root SVG class + nodeClassFn?: (node) => string; // custom per-node CSS classes + edgeClassFn?: (edge) => string; // custom per-edge CSS classes +} +``` + +## Development + +```bash +pnpm install + +# Build core +cd packages/core && pnpm build + +# Run tests (24 tests) +cd ../.. +node_modules/.bin/vitest run + +# Generate a PNG preview (requires Google Chrome) +google-chrome --headless=new --no-sandbox \ + --screenshot=output.png --window-size=2700,1400 \ + /tmp/rendered.html +``` + +### Project Structure + +``` +xircuits-graph-viewer/ +├── packages/ +│ ├── core/src/ # xircuits-graph-core (zero runtime deps) +│ │ ├── types.ts # XGraph, XNode, XEdge, XPort +│ │ ├── parser/ # .xircuits JSON → XGraph +│ │ ├── layout/ # Node metrics, viewBox computation +│ │ ├── render/ # SVG generation (nodes, ports, edges, defs) +│ │ ├── svg/ # Builder utilities, bezier curves +│ │ └── interaction/ # Pan/zoom (browser-only) +│ └── react/src/ # xircuits-graph-react +│ ├── XircuitsGraph.tsx # Interactive (client-side) +│ └── XircuitsGraphStatic.tsx # SSR-safe (string output) +├── demo/ # Vite + React demo app +├── __tests__/ # Parser + render tests +└── vitest.config.ts +``` + +## Publishing to npm + +```bash +# Build both packages +cd packages/core && pnpm build +cd ../react && pnpm build + +# Update workspace:* → actual version in react/package.json +# "xircuits-graph-core": "workspace:*" → "xircuits-graph-core": "^0.1.0" + +# Publish (core first, react depends on it) +cd ../core && npm publish --access public +cd ../react && npm publish --access public +``` + +## License + +MIT diff --git a/xircuits-graph-viewer/__tests__/fixtures/HelloXircuits.xircuits b/xircuits-graph-viewer/__tests__/fixtures/HelloXircuits.xircuits new file mode 100644 index 00000000..4a2aa53e --- /dev/null +++ b/xircuits-graph-viewer/__tests__/fixtures/HelloXircuits.xircuits @@ -0,0 +1,623 @@ +{ + "id": "11b9d835-f7c3-4b78-a927-bec01ae39956", + "offsetX": 138.70289808530393, + "offsetY": 112.11086262472926, + "zoom": 62.96296034657244, + "gridSize": 0, + "layers": [ + { + "id": "e8c7e3ab-cc6d-4d15-8c15-25b3b24cacd0", + "type": "diagram-links", + "isSvg": true, + "transformed": true, + "models": { + "0c51cfd5-b730-488b-a722-a7a93528866e": { + "id": "0c51cfd5-b730-488b-a722-a7a93528866e", + "type": "triangle-link", + "selected": false, + "source": "15df3e50-91c2-47a1-9c48-59f040abc728", + "sourcePort": "1bfb241e-2860-4cd8-887c-ace64dc6b9da", + "target": "16949768-609b-4f49-9637-1362acd39ebe", + "targetPort": "40888689-6dc0-4d53-bdbf-f74cd85f7e47", + "points": [ + { + "id": "0ddd19f6-a0da-440f-a802-3932fb342c9a", + "type": "point", + "x": 193.281, + "y": 118.015 + }, + { + "id": "22ff1dfd-b7f5-4ce9-b642-296b831d0fdf", + "type": "point", + "x": 353.929, + "y": 196.811 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "901eb298-883a-4803-9fca-d3ed4f926688": { + "id": "901eb298-883a-4803-9fca-d3ed4f926688", + "type": "triangle-link", + "selected": false, + "source": "16949768-609b-4f49-9637-1362acd39ebe", + "sourcePort": "13ff60b4-096f-43ac-9f8d-fd7eb6c68b00", + "target": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "targetPort": "e4118ad4-6463-45d0-acfe-278473f33171", + "points": [ + { + "id": "c3b6116d-aaf4-459e-9c1d-2eac10f71110", + "type": "point", + "x": 454.253, + "y": 196.811 + }, + { + "id": "7640dc8e-dddc-4cd2-ac4f-e800452a3f2b", + "type": "point", + "x": 708.119, + "y": 276.568 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "11ae19ab-0615-4e3f-ba1d-6dea826154b3": { + "id": "11ae19ab-0615-4e3f-ba1d-6dea826154b3", + "type": "triangle-link", + "selected": false, + "source": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "sourcePort": "8d80f536-fec5-41ca-a82a-23972097d32f", + "target": "4f6b8a78-d1a9-4510-b31e-131531a3ce23", + "targetPort": "738f2d81-79ca-414f-a6c3-43ebcdc825b4", + "points": [ + { + "id": "e8436c2a-9c79-41f5-ae34-5c6c90852abe", + "type": "point", + "x": 800.006, + "y": 276.568 + }, + { + "id": "f692f0e3-1d03-4ebf-9e2f-c5eaa5c2152b", + "type": "point", + "x": 927.448, + "y": 408.385 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "9d08656b-7508-4eae-a449-f50a3a125289": { + "id": "9d08656b-7508-4eae-a449-f50a3a125289", + "type": "parameter-link", + "selected": false, + "source": "7affbe5e-678b-4a5c-ad27-c5c4a12fc733", + "sourcePort": "bef4edd7-d310-463f-8ac3-dba1fb71e80e", + "target": "16949768-609b-4f49-9637-1362acd39ebe", + "targetPort": "d487a5cd-ffe5-4fba-800f-4651634f1ff5", + "points": [ + { + "id": "16128708-cec8-4c5c-aa18-eccc1d8aae67", + "type": "point", + "x": 201.892, + "y": 495.92 + }, + { + "id": "c6baf25d-ff3d-40c2-b43e-0430d3a05514", + "type": "point", + "x": 353.929, + "y": 228.779 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "14625014-44cf-4966-b34f-7b5d2023afe6": { + "id": "14625014-44cf-4966-b34f-7b5d2023afe6", + "type": "parameter-link", + "selected": false, + "source": "16949768-609b-4f49-9637-1362acd39ebe", + "sourcePort": "625956f7-cee1-4476-a9e7-ea34af1805d2", + "target": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "targetPort": "57336bb8-dbbf-48d2-88ac-2de9f15d6df6", + "points": [ + { + "id": "b92a9e9d-47ca-45df-b50b-2725a1077ab2", + "type": "point", + "x": 454.253, + "y": 212.795 + }, + { + "id": "1d373617-9c69-4839-aea5-ec027d58b4d3", + "type": "point", + "x": 708.119, + "y": 292.552 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f": { + "id": "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f", + "type": "parameter-link", + "selected": false, + "source": "bd066e96-970a-4477-86c7-fdc2dc88c4a1", + "sourcePort": "d9cf851b-f1de-4ab8-9244-9e8b24399ffd", + "target": "16949768-609b-4f49-9637-1362acd39ebe", + "targetPort": "14fbc718-0f8f-4c0b-bc47-4ac837d39b27", + "points": [ + { + "id": "86e6c64b-d0b2-40e3-b746-dc56b9c2e56b", + "type": "point", + "x": 200.295, + "y": 422.066 + }, + { + "id": "fd5a730e-8422-4d27-95fb-b954065393ca", + "type": "point", + "x": 353.929, + "y": 212.795 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + } + } + }, + { + "id": "b1e2c329-efb4-4370-8927-38e61e23c5d2", + "type": "diagram-nodes", + "isSvg": false, + "transformed": true, + "models": { + "15df3e50-91c2-47a1-9c48-59f040abc728": { + "id": "15df3e50-91c2-47a1-9c48-59f040abc728", + "type": "custom-node", + "selected": false, + "extras": { + "type": "Start", + "borderColor": "rgb(0,192,255)" + }, + "x": 155.159, + "y": 86.223, + "ports": [ + { + "id": "1bfb241e-2860-4cd8-887c-ace64dc6b9da", + "type": "default", + "extras": {}, + "x": 185.787, + "y": 110.521, + "name": "out-0", + "alignment": "right", + "parentNode": "15df3e50-91c2-47a1-9c48-59f040abc728", + "links": [ + "0c51cfd5-b730-488b-a722-a7a93528866e" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Start", + "color": "rgb(255,102,102)", + "portsInOrder": [], + "portsOutOrder": [ + "1bfb241e-2860-4cd8-887c-ace64dc6b9da" + ] + }, + "4f6b8a78-d1a9-4510-b31e-131531a3ce23": { + "id": "4f6b8a78-d1a9-4510-b31e-131531a3ce23", + "type": "custom-node", + "selected": false, + "extras": { + "type": "Finish", + "borderColor": "rgb(0,192,255)" + }, + "x": 918.478, + "y": 376.596, + "ports": [ + { + "id": "738f2d81-79ca-414f-a6c3-43ebcdc825b4", + "type": "default", + "extras": {}, + "x": 919.954, + "y": 400.891, + "name": "in-0", + "alignment": "left", + "parentNode": "4f6b8a78-d1a9-4510-b31e-131531a3ce23", + "links": [ + "11ae19ab-0615-4e3f-ba1d-6dea826154b3" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Finish", + "color": "rgb(255,102,102)", + "portsInOrder": [ + "738f2d81-79ca-414f-a6c3-43ebcdc825b4" + ], + "portsOutOrder": [] + }, + "7affbe5e-678b-4a5c-ad27-c5c4a12fc733": { + "id": "7affbe5e-678b-4a5c-ad27-c5c4a12fc733", + "type": "custom-node", + "selected": false, + "extras": { + "type": "string" + }, + "x": 133.861, + "y": 464.122, + "ports": [ + { + "id": "bef4edd7-d310-463f-8ac3-dba1fb71e80e", + "type": "default", + "extras": {}, + "x": 194.398, + "y": 488.426, + "name": "out-0", + "alignment": "right", + "parentNode": "7affbe5e-678b-4a5c-ad27-c5c4a12fc733", + "links": [ + "9d08656b-7508-4eae-a449-f50a3a125289" + ], + "in": false, + "label": "Xircuits!", + "varName": "Xircuits!", + "portType": "", + "dataType": "" + } + ], + "name": "Literal String", + "color": "lightpink", + "portsInOrder": [], + "portsOutOrder": [ + "bef4edd7-d310-463f-8ac3-dba1fb71e80e" + ] + }, + "bd066e96-970a-4477-86c7-fdc2dc88c4a1": { + "id": "bd066e96-970a-4477-86c7-fdc2dc88c4a1", + "type": "custom-node", + "selected": false, + "extras": { + "type": "string" + }, + "x": 134.61, + "y": 390.271, + "ports": [ + { + "id": "d9cf851b-f1de-4ab8-9244-9e8b24399ffd", + "type": "default", + "extras": {}, + "x": 192.801, + "y": 414.572, + "name": "out-0", + "alignment": "right", + "parentNode": "bd066e96-970a-4477-86c7-fdc2dc88c4a1", + "links": [ + "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f" + ], + "in": false, + "label": "Hello ", + "varName": "Hello ", + "portType": "", + "dataType": "" + } + ], + "name": "Literal String", + "color": "lightpink", + "portsInOrder": [], + "portsOutOrder": [ + "d9cf851b-f1de-4ab8-9244-9e8b24399ffd" + ] + }, + "16949768-609b-4f49-9637-1362acd39ebe": { + "id": "16949768-609b-4f49-9637-1362acd39ebe", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_utils/utils.py", + "description": null, + "lineNo": [ + { + "lineno": 16, + "end_lineno": 22 + } + ] + }, + "x": 344.958, + "y": 165.014, + "ports": [ + { + "id": "40888689-6dc0-4d53-bdbf-f74cd85f7e47", + "type": "default", + "extras": {}, + "x": 346.435, + "y": 189.317, + "name": "in-0", + "alignment": "left", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "0c51cfd5-b730-488b-a722-a7a93528866e" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "14fbc718-0f8f-4c0b-bc47-4ac837d39b27", + "type": "default", + "extras": {}, + "x": 346.435, + "y": 205.301, + "name": "parameter-string-a", + "alignment": "left", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f" + ], + "in": true, + "label": "a", + "varName": "a", + "portType": "", + "dataType": "string" + }, + { + "id": "d487a5cd-ffe5-4fba-800f-4651634f1ff5", + "type": "default", + "extras": {}, + "x": 346.435, + "y": 221.285, + "name": "parameter-string-b", + "alignment": "left", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "9d08656b-7508-4eae-a449-f50a3a125289" + ], + "in": true, + "label": "b", + "varName": "b", + "portType": "", + "dataType": "string" + }, + { + "id": "13ff60b4-096f-43ac-9f8d-fd7eb6c68b00", + "type": "default", + "extras": {}, + "x": 446.759, + "y": 189.317, + "name": "out-0", + "alignment": "right", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "901eb298-883a-4803-9fca-d3ed4f926688" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "625956f7-cee1-4476-a9e7-ea34af1805d2", + "type": "default", + "extras": {}, + "x": 446.759, + "y": 205.301, + "name": "parameter-out-string-out", + "alignment": "right", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "14625014-44cf-4966-b34f-7b5d2023afe6" + ], + "in": false, + "label": "out", + "varName": "out", + "portType": "", + "dataType": "" + } + ], + "name": "ConcatString", + "color": "rgb(153,51,204)", + "portsInOrder": [ + "40888689-6dc0-4d53-bdbf-f74cd85f7e47", + "14fbc718-0f8f-4c0b-bc47-4ac837d39b27", + "d487a5cd-ffe5-4fba-800f-4651634f1ff5" + ], + "portsOutOrder": [ + "13ff60b4-096f-43ac-9f8d-fd7eb6c68b00", + "625956f7-cee1-4476-a9e7-ea34af1805d2" + ] + }, + "c67603e4-dfda-4c58-b6ab-0952eba75254": { + "id": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_utils/utils.py", + "description": null, + "lineNo": [ + { + "lineno": 9, + "end_lineno": 13 + } + ] + }, + "x": 699.144, + "y": 244.771, + "ports": [ + { + "id": "e4118ad4-6463-45d0-acfe-278473f33171", + "type": "default", + "extras": {}, + "x": 700.625, + "y": 269.074, + "name": "in-0", + "alignment": "left", + "parentNode": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "links": [ + "901eb298-883a-4803-9fca-d3ed4f926688" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "57336bb8-dbbf-48d2-88ac-2de9f15d6df6", + "type": "default", + "extras": {}, + "x": 700.625, + "y": 285.058, + "name": "parameter-any-msg", + "alignment": "left", + "parentNode": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "links": [ + "14625014-44cf-4966-b34f-7b5d2023afe6" + ], + "in": true, + "label": "msg", + "varName": "msg", + "portType": "", + "dataType": "any" + }, + { + "id": "8d80f536-fec5-41ca-a82a-23972097d32f", + "type": "default", + "extras": {}, + "x": 792.512, + "y": 269.074, + "name": "out-0", + "alignment": "right", + "parentNode": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "links": [ + "11ae19ab-0615-4e3f-ba1d-6dea826154b3" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Print", + "color": "rgb(102,51,102)", + "portsInOrder": [ + "e4118ad4-6463-45d0-acfe-278473f33171", + "57336bb8-dbbf-48d2-88ac-2de9f15d6df6" + ], + "portsOutOrder": [ + "8d80f536-fec5-41ca-a82a-23972097d32f" + ] + }, + "35a75ed7-cd63-45d0-83a8-82b6f2a1e295": { + "id": "35a75ed7-cd63-45d0-83a8-82b6f2a1e295", + "type": "custom-node", + "selected": true, + "extras": { + "type": "comment", + "commentInput": "[1] Xircuits workflows are designed around \n the concept of linking nodes and configuring \n them with specific parameters." + }, + "x": -2.913, + "y": -76.821, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "d64c2fc8-73a6-4f7e-a406-f491c2ce2bce": { + "id": "d64c2fc8-73a6-4f7e-a406-f491c2ce2bce", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[2] The blue flowing link connecting ▶ ports\n represent the sequence of execution." + }, + "x": 339.679, + "y": 51.942, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "ef86f386-48c9-456c-9b3c-7af11c9c4575": { + "id": "ef86f386-48c9-456c-9b3c-7af11c9c4575", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[4] You can also pass parameters \n from one component node to another." + }, + "x": 381.006, + "y": 339.556, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "f2c978ce-51d3-4327-a01b-2490500dffb4": { + "id": "f2c978ce-51d3-4327-a01b-2490500dffb4", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[3] Literals are one way of supplying parameters\n to your component node.\n You can double click literals to edit their value." + }, + "x": -143.813, + "y": 231.319, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "d4c2e2ce-f0dd-4104-9355-df2c96d0aa84": { + "id": "d4c2e2ce-f0dd-4104-9355-df2c96d0aa84", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[5] Once you're done, you can compile \n and execute the workflow." + }, + "x": 824.994, + "y": 456.905, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + } + } + } + ] +} \ No newline at end of file diff --git a/xircuits-graph-viewer/__tests__/parser.test.ts b/xircuits-graph-viewer/__tests__/parser.test.ts new file mode 100644 index 00000000..01d502f0 --- /dev/null +++ b/xircuits-graph-viewer/__tests__/parser.test.ts @@ -0,0 +1,116 @@ +import { describe, it, expect } from 'vitest'; +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { parse } from '../packages/core/src/parser/parse.js'; +import { validate } from '../packages/core/src/parser/validate.js'; + +const fixtureDir = resolve(__dirname, 'fixtures'); + +function loadFixture(name: string) { + return JSON.parse(readFileSync(resolve(fixtureDir, name), 'utf-8')); +} + +describe('validate', () => { + it('validates a correct .xircuits file', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const result = validate(json); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); + + it('rejects non-object input', () => { + const result = validate('not an object'); + expect(result.valid).toBe(false); + }); + + it('rejects missing layers', () => { + const result = validate({ id: 'test' }); + expect(result.valid).toBe(false); + expect(result.errors).toContain('Missing or invalid "layers" array'); + }); +}); + +describe('parse', () => { + it('parses HelloXircuits correctly', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + + expect(graph.id).toBe('11b9d835-f7c3-4b78-a927-bec01ae39956'); + expect(graph.nodes.length).toBeGreaterThan(0); + expect(graph.edges.length).toBeGreaterThan(0); + }); + + it('classifies Start node correctly', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + + const start = graph.nodes.find(n => n.name === 'Start'); + expect(start).toBeDefined(); + expect(start!.kind).toBe('start'); + expect(start!.color).toBe('rgb(255,102,102)'); + }); + + it('classifies Finish node correctly', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + + const finish = graph.nodes.find(n => n.name === 'Finish'); + expect(finish).toBeDefined(); + expect(finish!.kind).toBe('finish'); + }); + + it('classifies Literal nodes correctly', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + + const literals = graph.nodes.filter(n => n.kind === 'literal'); + expect(literals.length).toBe(2); // Two "Literal String" nodes + }); + + it('classifies Comment nodes correctly', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + + const comments = graph.nodes.filter(n => n.kind === 'comment'); + expect(comments.length).toBe(5); + expect(comments[0].extras.commentInput).toBeDefined(); + }); + + it('classifies component nodes correctly', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + + const concat = graph.nodes.find(n => n.name === 'ConcatString'); + expect(concat).toBeDefined(); + expect(concat!.kind).toBe('component'); + }); + + it('parses ports correctly', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + + const concat = graph.nodes.find(n => n.name === 'ConcatString')!; + expect(concat.portsIn.length).toBe(3); // flow + a + b + expect(concat.portsOut.length).toBe(2); // flow + out + + const flowIn = concat.portsIn.find(p => p.kind === 'flow'); + expect(flowIn).toBeDefined(); + expect(flowIn!.label).toBe('▶'); + + const paramA = concat.portsIn.find(p => p.label === 'a'); + expect(paramA).toBeDefined(); + expect(paramA!.kind).toBe('parameter'); + expect(paramA!.dataType).toBe('string'); + }); + + it('parses edges correctly', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + + const flowEdges = graph.edges.filter(e => e.kind === 'flow'); + const dataEdges = graph.edges.filter(e => e.kind === 'data'); + + expect(flowEdges.length).toBe(3); // Start→Concat→Print→Finish + expect(dataEdges.length).toBe(3); // Two literals→Concat, Concat→Print + }); +}); diff --git a/xircuits-graph-viewer/__tests__/render.test.ts b/xircuits-graph-viewer/__tests__/render.test.ts new file mode 100644 index 00000000..9e5757c2 --- /dev/null +++ b/xircuits-graph-viewer/__tests__/render.test.ts @@ -0,0 +1,146 @@ +import { describe, it, expect } from 'vitest'; +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { parse } from '../packages/core/src/parser/parse.js'; +import { renderToString } from '../packages/core/src/render/renderGraph.js'; +import { computeNodeMetrics } from '../packages/core/src/layout/metrics.js'; + +const fixtureDir = resolve(__dirname, 'fixtures'); + +function loadFixture(name: string) { + return JSON.parse(readFileSync(resolve(fixtureDir, name), 'utf-8')); +} + +describe('renderToString', () => { + it('renders HelloXircuits as valid SVG', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + const svg = renderToString(graph, { theme: 'dark' }); + + expect(svg).toContain(''); + }); + + it('includes node elements', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + const svg = renderToString(graph); + + expect(svg).toContain('xg-node--start'); + expect(svg).toContain('xg-node--finish'); + expect(svg).toContain('xg-node--component'); + expect(svg).toContain('xg-node--literal'); + expect(svg).toContain('xg-node--comment'); + }); + + it('includes edge elements', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + const svg = renderToString(graph); + + expect(svg).toContain('xg-edge--flow'); + expect(svg).toContain('xg-edge--data'); + }); + + it('includes gradient definitions', () => { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + const svg = renderToString(graph); + + expect(svg).toContain(' { + const json = loadFixture('HelloXircuits.xircuits'); + const graph = parse(json); + const svg = renderToString(graph); + + expect(svg).toContain(' + + +
+ + + diff --git a/xircuits-graph-viewer/demo/package.json b/xircuits-graph-viewer/demo/package.json new file mode 100644 index 00000000..1bf6b135 --- /dev/null +++ b/xircuits-graph-viewer/demo/package.json @@ -0,0 +1,22 @@ +{ + "name": "xircuits-graph-viewer-demo", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1", + "xircuits-graph-core": "workspace:*", + "xircuits-graph-react": "workspace:*" + }, + "devDependencies": { + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.4", + "typescript": "^5.8.3", + "vite": "^6.3.1" + } +} diff --git a/xircuits-graph-viewer/demo/src/App.tsx b/xircuits-graph-viewer/demo/src/App.tsx new file mode 100644 index 00000000..18e818a0 --- /dev/null +++ b/xircuits-graph-viewer/demo/src/App.tsx @@ -0,0 +1,41 @@ +import React, { useState } from 'react'; +import { parse, renderToString } from 'xircuits-graph-core'; +import helloXircuits from './fixtures/HelloXircuits.xircuits'; + +export function App() { + const [theme, setTheme] = useState<'dark' | 'light'>('dark'); + + const graph = parse(helloXircuits); + const svgString = renderToString(graph, { theme, fitView: true, padding: 40 }); + + return ( +
+

Xircuits Graph Viewer Demo

+
+
+ +
+
+
+
+ ); +} diff --git a/xircuits-graph-viewer/demo/src/fixtures/HelloXircuits.xircuits b/xircuits-graph-viewer/demo/src/fixtures/HelloXircuits.xircuits new file mode 100644 index 00000000..4a2aa53e --- /dev/null +++ b/xircuits-graph-viewer/demo/src/fixtures/HelloXircuits.xircuits @@ -0,0 +1,623 @@ +{ + "id": "11b9d835-f7c3-4b78-a927-bec01ae39956", + "offsetX": 138.70289808530393, + "offsetY": 112.11086262472926, + "zoom": 62.96296034657244, + "gridSize": 0, + "layers": [ + { + "id": "e8c7e3ab-cc6d-4d15-8c15-25b3b24cacd0", + "type": "diagram-links", + "isSvg": true, + "transformed": true, + "models": { + "0c51cfd5-b730-488b-a722-a7a93528866e": { + "id": "0c51cfd5-b730-488b-a722-a7a93528866e", + "type": "triangle-link", + "selected": false, + "source": "15df3e50-91c2-47a1-9c48-59f040abc728", + "sourcePort": "1bfb241e-2860-4cd8-887c-ace64dc6b9da", + "target": "16949768-609b-4f49-9637-1362acd39ebe", + "targetPort": "40888689-6dc0-4d53-bdbf-f74cd85f7e47", + "points": [ + { + "id": "0ddd19f6-a0da-440f-a802-3932fb342c9a", + "type": "point", + "x": 193.281, + "y": 118.015 + }, + { + "id": "22ff1dfd-b7f5-4ce9-b642-296b831d0fdf", + "type": "point", + "x": 353.929, + "y": 196.811 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "901eb298-883a-4803-9fca-d3ed4f926688": { + "id": "901eb298-883a-4803-9fca-d3ed4f926688", + "type": "triangle-link", + "selected": false, + "source": "16949768-609b-4f49-9637-1362acd39ebe", + "sourcePort": "13ff60b4-096f-43ac-9f8d-fd7eb6c68b00", + "target": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "targetPort": "e4118ad4-6463-45d0-acfe-278473f33171", + "points": [ + { + "id": "c3b6116d-aaf4-459e-9c1d-2eac10f71110", + "type": "point", + "x": 454.253, + "y": 196.811 + }, + { + "id": "7640dc8e-dddc-4cd2-ac4f-e800452a3f2b", + "type": "point", + "x": 708.119, + "y": 276.568 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "11ae19ab-0615-4e3f-ba1d-6dea826154b3": { + "id": "11ae19ab-0615-4e3f-ba1d-6dea826154b3", + "type": "triangle-link", + "selected": false, + "source": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "sourcePort": "8d80f536-fec5-41ca-a82a-23972097d32f", + "target": "4f6b8a78-d1a9-4510-b31e-131531a3ce23", + "targetPort": "738f2d81-79ca-414f-a6c3-43ebcdc825b4", + "points": [ + { + "id": "e8436c2a-9c79-41f5-ae34-5c6c90852abe", + "type": "point", + "x": 800.006, + "y": 276.568 + }, + { + "id": "f692f0e3-1d03-4ebf-9e2f-c5eaa5c2152b", + "type": "point", + "x": 927.448, + "y": 408.385 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "9d08656b-7508-4eae-a449-f50a3a125289": { + "id": "9d08656b-7508-4eae-a449-f50a3a125289", + "type": "parameter-link", + "selected": false, + "source": "7affbe5e-678b-4a5c-ad27-c5c4a12fc733", + "sourcePort": "bef4edd7-d310-463f-8ac3-dba1fb71e80e", + "target": "16949768-609b-4f49-9637-1362acd39ebe", + "targetPort": "d487a5cd-ffe5-4fba-800f-4651634f1ff5", + "points": [ + { + "id": "16128708-cec8-4c5c-aa18-eccc1d8aae67", + "type": "point", + "x": 201.892, + "y": 495.92 + }, + { + "id": "c6baf25d-ff3d-40c2-b43e-0430d3a05514", + "type": "point", + "x": 353.929, + "y": 228.779 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "14625014-44cf-4966-b34f-7b5d2023afe6": { + "id": "14625014-44cf-4966-b34f-7b5d2023afe6", + "type": "parameter-link", + "selected": false, + "source": "16949768-609b-4f49-9637-1362acd39ebe", + "sourcePort": "625956f7-cee1-4476-a9e7-ea34af1805d2", + "target": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "targetPort": "57336bb8-dbbf-48d2-88ac-2de9f15d6df6", + "points": [ + { + "id": "b92a9e9d-47ca-45df-b50b-2725a1077ab2", + "type": "point", + "x": 454.253, + "y": 212.795 + }, + { + "id": "1d373617-9c69-4839-aea5-ec027d58b4d3", + "type": "point", + "x": 708.119, + "y": 292.552 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f": { + "id": "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f", + "type": "parameter-link", + "selected": false, + "source": "bd066e96-970a-4477-86c7-fdc2dc88c4a1", + "sourcePort": "d9cf851b-f1de-4ab8-9244-9e8b24399ffd", + "target": "16949768-609b-4f49-9637-1362acd39ebe", + "targetPort": "14fbc718-0f8f-4c0b-bc47-4ac837d39b27", + "points": [ + { + "id": "86e6c64b-d0b2-40e3-b746-dc56b9c2e56b", + "type": "point", + "x": 200.295, + "y": 422.066 + }, + { + "id": "fd5a730e-8422-4d27-95fb-b954065393ca", + "type": "point", + "x": 353.929, + "y": 212.795 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + } + } + }, + { + "id": "b1e2c329-efb4-4370-8927-38e61e23c5d2", + "type": "diagram-nodes", + "isSvg": false, + "transformed": true, + "models": { + "15df3e50-91c2-47a1-9c48-59f040abc728": { + "id": "15df3e50-91c2-47a1-9c48-59f040abc728", + "type": "custom-node", + "selected": false, + "extras": { + "type": "Start", + "borderColor": "rgb(0,192,255)" + }, + "x": 155.159, + "y": 86.223, + "ports": [ + { + "id": "1bfb241e-2860-4cd8-887c-ace64dc6b9da", + "type": "default", + "extras": {}, + "x": 185.787, + "y": 110.521, + "name": "out-0", + "alignment": "right", + "parentNode": "15df3e50-91c2-47a1-9c48-59f040abc728", + "links": [ + "0c51cfd5-b730-488b-a722-a7a93528866e" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Start", + "color": "rgb(255,102,102)", + "portsInOrder": [], + "portsOutOrder": [ + "1bfb241e-2860-4cd8-887c-ace64dc6b9da" + ] + }, + "4f6b8a78-d1a9-4510-b31e-131531a3ce23": { + "id": "4f6b8a78-d1a9-4510-b31e-131531a3ce23", + "type": "custom-node", + "selected": false, + "extras": { + "type": "Finish", + "borderColor": "rgb(0,192,255)" + }, + "x": 918.478, + "y": 376.596, + "ports": [ + { + "id": "738f2d81-79ca-414f-a6c3-43ebcdc825b4", + "type": "default", + "extras": {}, + "x": 919.954, + "y": 400.891, + "name": "in-0", + "alignment": "left", + "parentNode": "4f6b8a78-d1a9-4510-b31e-131531a3ce23", + "links": [ + "11ae19ab-0615-4e3f-ba1d-6dea826154b3" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Finish", + "color": "rgb(255,102,102)", + "portsInOrder": [ + "738f2d81-79ca-414f-a6c3-43ebcdc825b4" + ], + "portsOutOrder": [] + }, + "7affbe5e-678b-4a5c-ad27-c5c4a12fc733": { + "id": "7affbe5e-678b-4a5c-ad27-c5c4a12fc733", + "type": "custom-node", + "selected": false, + "extras": { + "type": "string" + }, + "x": 133.861, + "y": 464.122, + "ports": [ + { + "id": "bef4edd7-d310-463f-8ac3-dba1fb71e80e", + "type": "default", + "extras": {}, + "x": 194.398, + "y": 488.426, + "name": "out-0", + "alignment": "right", + "parentNode": "7affbe5e-678b-4a5c-ad27-c5c4a12fc733", + "links": [ + "9d08656b-7508-4eae-a449-f50a3a125289" + ], + "in": false, + "label": "Xircuits!", + "varName": "Xircuits!", + "portType": "", + "dataType": "" + } + ], + "name": "Literal String", + "color": "lightpink", + "portsInOrder": [], + "portsOutOrder": [ + "bef4edd7-d310-463f-8ac3-dba1fb71e80e" + ] + }, + "bd066e96-970a-4477-86c7-fdc2dc88c4a1": { + "id": "bd066e96-970a-4477-86c7-fdc2dc88c4a1", + "type": "custom-node", + "selected": false, + "extras": { + "type": "string" + }, + "x": 134.61, + "y": 390.271, + "ports": [ + { + "id": "d9cf851b-f1de-4ab8-9244-9e8b24399ffd", + "type": "default", + "extras": {}, + "x": 192.801, + "y": 414.572, + "name": "out-0", + "alignment": "right", + "parentNode": "bd066e96-970a-4477-86c7-fdc2dc88c4a1", + "links": [ + "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f" + ], + "in": false, + "label": "Hello ", + "varName": "Hello ", + "portType": "", + "dataType": "" + } + ], + "name": "Literal String", + "color": "lightpink", + "portsInOrder": [], + "portsOutOrder": [ + "d9cf851b-f1de-4ab8-9244-9e8b24399ffd" + ] + }, + "16949768-609b-4f49-9637-1362acd39ebe": { + "id": "16949768-609b-4f49-9637-1362acd39ebe", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_utils/utils.py", + "description": null, + "lineNo": [ + { + "lineno": 16, + "end_lineno": 22 + } + ] + }, + "x": 344.958, + "y": 165.014, + "ports": [ + { + "id": "40888689-6dc0-4d53-bdbf-f74cd85f7e47", + "type": "default", + "extras": {}, + "x": 346.435, + "y": 189.317, + "name": "in-0", + "alignment": "left", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "0c51cfd5-b730-488b-a722-a7a93528866e" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "14fbc718-0f8f-4c0b-bc47-4ac837d39b27", + "type": "default", + "extras": {}, + "x": 346.435, + "y": 205.301, + "name": "parameter-string-a", + "alignment": "left", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f" + ], + "in": true, + "label": "a", + "varName": "a", + "portType": "", + "dataType": "string" + }, + { + "id": "d487a5cd-ffe5-4fba-800f-4651634f1ff5", + "type": "default", + "extras": {}, + "x": 346.435, + "y": 221.285, + "name": "parameter-string-b", + "alignment": "left", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "9d08656b-7508-4eae-a449-f50a3a125289" + ], + "in": true, + "label": "b", + "varName": "b", + "portType": "", + "dataType": "string" + }, + { + "id": "13ff60b4-096f-43ac-9f8d-fd7eb6c68b00", + "type": "default", + "extras": {}, + "x": 446.759, + "y": 189.317, + "name": "out-0", + "alignment": "right", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "901eb298-883a-4803-9fca-d3ed4f926688" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "625956f7-cee1-4476-a9e7-ea34af1805d2", + "type": "default", + "extras": {}, + "x": 446.759, + "y": 205.301, + "name": "parameter-out-string-out", + "alignment": "right", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "14625014-44cf-4966-b34f-7b5d2023afe6" + ], + "in": false, + "label": "out", + "varName": "out", + "portType": "", + "dataType": "" + } + ], + "name": "ConcatString", + "color": "rgb(153,51,204)", + "portsInOrder": [ + "40888689-6dc0-4d53-bdbf-f74cd85f7e47", + "14fbc718-0f8f-4c0b-bc47-4ac837d39b27", + "d487a5cd-ffe5-4fba-800f-4651634f1ff5" + ], + "portsOutOrder": [ + "13ff60b4-096f-43ac-9f8d-fd7eb6c68b00", + "625956f7-cee1-4476-a9e7-ea34af1805d2" + ] + }, + "c67603e4-dfda-4c58-b6ab-0952eba75254": { + "id": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_utils/utils.py", + "description": null, + "lineNo": [ + { + "lineno": 9, + "end_lineno": 13 + } + ] + }, + "x": 699.144, + "y": 244.771, + "ports": [ + { + "id": "e4118ad4-6463-45d0-acfe-278473f33171", + "type": "default", + "extras": {}, + "x": 700.625, + "y": 269.074, + "name": "in-0", + "alignment": "left", + "parentNode": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "links": [ + "901eb298-883a-4803-9fca-d3ed4f926688" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "57336bb8-dbbf-48d2-88ac-2de9f15d6df6", + "type": "default", + "extras": {}, + "x": 700.625, + "y": 285.058, + "name": "parameter-any-msg", + "alignment": "left", + "parentNode": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "links": [ + "14625014-44cf-4966-b34f-7b5d2023afe6" + ], + "in": true, + "label": "msg", + "varName": "msg", + "portType": "", + "dataType": "any" + }, + { + "id": "8d80f536-fec5-41ca-a82a-23972097d32f", + "type": "default", + "extras": {}, + "x": 792.512, + "y": 269.074, + "name": "out-0", + "alignment": "right", + "parentNode": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "links": [ + "11ae19ab-0615-4e3f-ba1d-6dea826154b3" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Print", + "color": "rgb(102,51,102)", + "portsInOrder": [ + "e4118ad4-6463-45d0-acfe-278473f33171", + "57336bb8-dbbf-48d2-88ac-2de9f15d6df6" + ], + "portsOutOrder": [ + "8d80f536-fec5-41ca-a82a-23972097d32f" + ] + }, + "35a75ed7-cd63-45d0-83a8-82b6f2a1e295": { + "id": "35a75ed7-cd63-45d0-83a8-82b6f2a1e295", + "type": "custom-node", + "selected": true, + "extras": { + "type": "comment", + "commentInput": "[1] Xircuits workflows are designed around \n the concept of linking nodes and configuring \n them with specific parameters." + }, + "x": -2.913, + "y": -76.821, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "d64c2fc8-73a6-4f7e-a406-f491c2ce2bce": { + "id": "d64c2fc8-73a6-4f7e-a406-f491c2ce2bce", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[2] The blue flowing link connecting ▶ ports\n represent the sequence of execution." + }, + "x": 339.679, + "y": 51.942, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "ef86f386-48c9-456c-9b3c-7af11c9c4575": { + "id": "ef86f386-48c9-456c-9b3c-7af11c9c4575", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[4] You can also pass parameters \n from one component node to another." + }, + "x": 381.006, + "y": 339.556, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "f2c978ce-51d3-4327-a01b-2490500dffb4": { + "id": "f2c978ce-51d3-4327-a01b-2490500dffb4", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[3] Literals are one way of supplying parameters\n to your component node.\n You can double click literals to edit their value." + }, + "x": -143.813, + "y": 231.319, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "d4c2e2ce-f0dd-4104-9355-df2c96d0aa84": { + "id": "d4c2e2ce-f0dd-4104-9355-df2c96d0aa84", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[5] Once you're done, you can compile \n and execute the workflow." + }, + "x": 824.994, + "y": 456.905, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + } + } + } + ] +} \ No newline at end of file diff --git a/xircuits-graph-viewer/demo/src/main.tsx b/xircuits-graph-viewer/demo/src/main.tsx new file mode 100644 index 00000000..e4e11c43 --- /dev/null +++ b/xircuits-graph-viewer/demo/src/main.tsx @@ -0,0 +1,5 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { App } from './App.js'; + +createRoot(document.getElementById('root')!).render(); diff --git a/xircuits-graph-viewer/demo/tsconfig.json b/xircuits-graph-viewer/demo/tsconfig.json new file mode 100644 index 00000000..30ea33ee --- /dev/null +++ b/xircuits-graph-viewer/demo/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "jsx": "react-jsx", + "noEmit": true + }, + "include": ["src"] +} diff --git a/xircuits-graph-viewer/demo/vite.config.ts b/xircuits-graph-viewer/demo/vite.config.ts new file mode 100644 index 00000000..0466183a --- /dev/null +++ b/xircuits-graph-viewer/demo/vite.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], +}); diff --git a/xircuits-graph-viewer/package.json b/xircuits-graph-viewer/package.json new file mode 100644 index 00000000..48990659 --- /dev/null +++ b/xircuits-graph-viewer/package.json @@ -0,0 +1,13 @@ +{ + "name": "xircuits-graph-viewer-root", + "private": true, + "scripts": { + "build": "pnpm -r build", + "dev": "pnpm --filter demo dev", + "test": "vitest" + }, + "devDependencies": { + "vitest": "^3.1.1", + "typescript": "^5.8.3" + } +} diff --git a/xircuits-graph-viewer/packages/core/package.json b/xircuits-graph-viewer/packages/core/package.json new file mode 100644 index 00000000..55c5f821 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/package.json @@ -0,0 +1,25 @@ +{ + "name": "xircuits-graph-core", + "version": "0.1.0", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./interaction": { + "types": "./dist/interaction/panZoom.d.ts", + "import": "./dist/interaction/panZoom.js" + } + }, + "files": ["dist"], + "scripts": { + "build": "tsc", + "dev": "tsc --watch" + }, + "devDependencies": { + "typescript": "^5.8.3" + } +} diff --git a/xircuits-graph-viewer/packages/core/src/index.ts b/xircuits-graph-viewer/packages/core/src/index.ts new file mode 100644 index 00000000..309ec7c1 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/index.ts @@ -0,0 +1,56 @@ +// Types +export type { + XGraph, + XNode, + XEdge, + XPort, + NodeMetrics, + RenderOptions, + PortDirection, + PortKind, + NodeKind, + EdgeKind, +} from './types.js'; + +// Parser +export { parse } from './parser/parse.js'; +export { validate } from './parser/validate.js'; + +// Layout +export { computeNodeMetrics } from './layout/metrics.js'; +export { computeViewBox } from './layout/viewBox.js'; + +// Renderer +export { renderToString, renderToElement } from './render/renderGraph.js'; + +// Convenience: one-shot parse + render +export { renderXircuits } from './render/renderGraph.js'; + +// Container background CSS (matching Xircuits canvas) +export function getCanvasStyle(theme: 'dark' | 'light' = 'dark'): string { + if (theme === 'dark') { + return [ + 'background-color: oklch(0.3 0.01 300)', + 'background-image: radial-gradient(oklch(40% 0 0) 1px, transparent 0)', + 'background-size: 15px 15px', + ].join(';'); + } + return [ + 'background-color: #f5f5f5', + 'background-image: radial-gradient(oklch(85% 0 0) 1px, transparent 0)', + 'background-size: 15px 15px', + ].join(';'); +} + +// Browser helper: fetch a .xircuits URL and render +export async function renderFromUrl( + url: string, + options?: import('./types.js').RenderOptions +): Promise { + const res = await fetch(url); + if (!res.ok) throw new Error(`Failed to load ${url}: ${res.status}`); + const json = await res.json(); + const { parse } = await import('./parser/parse.js'); + const { renderToString } = await import('./render/renderGraph.js'); + return renderToString(parse(json), options); +} diff --git a/xircuits-graph-viewer/packages/core/src/interaction/panZoom.ts b/xircuits-graph-viewer/packages/core/src/interaction/panZoom.ts new file mode 100644 index 00000000..123d1e35 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/interaction/panZoom.ts @@ -0,0 +1,99 @@ +export interface PanZoomOptions { + minZoom?: number; + maxZoom?: number; + onViewportChange?: (viewport: { x: number; y: number; zoom: number }) => void; +} + +export function attachPanZoom( + svg: SVGSVGElement, + options: PanZoomOptions = {}, +): { destroy: () => void } { + const { minZoom = 0.1, maxZoom = 4, onViewportChange } = options; + + let viewBox = parseViewBox(svg); + let isPanning = false; + let startX = 0; + let startY = 0; + let startVBX = 0; + let startVBY = 0; + + function parseViewBox(el: SVGSVGElement) { + const vb = el.getAttribute('viewBox')?.split(/\s+/).map(Number) || [0, 0, 800, 600]; + return { x: vb[0], y: vb[1], w: vb[2], h: vb[3] }; + } + + function updateViewBox() { + svg.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`); + onViewportChange?.({ + x: viewBox.x, + y: viewBox.y, + zoom: svg.clientWidth / viewBox.w, + }); + } + + function onWheel(e: WheelEvent) { + e.preventDefault(); + const rect = svg.getBoundingClientRect(); + const mx = (e.clientX - rect.left) / rect.width; + const my = (e.clientY - rect.top) / rect.height; + + const factor = e.deltaY > 0 ? 1.1 : 0.9; + const newW = viewBox.w * factor; + const newH = viewBox.h * factor; + + // Enforce zoom limits + const currentZoom = svg.clientWidth / viewBox.w; + const newZoom = svg.clientWidth / newW; + if (newZoom < minZoom || newZoom > maxZoom) return; + + viewBox.x += (viewBox.w - newW) * mx; + viewBox.y += (viewBox.h - newH) * my; + viewBox.w = newW; + viewBox.h = newH; + + updateViewBox(); + } + + function onPointerDown(e: PointerEvent) { + if (e.button !== 0) return; + isPanning = true; + startX = e.clientX; + startY = e.clientY; + startVBX = viewBox.x; + startVBY = viewBox.y; + svg.setPointerCapture(e.pointerId); + svg.style.cursor = 'grabbing'; + } + + function onPointerMove(e: PointerEvent) { + if (!isPanning) return; + const rect = svg.getBoundingClientRect(); + const dx = (e.clientX - startX) / rect.width * viewBox.w; + const dy = (e.clientY - startY) / rect.height * viewBox.h; + viewBox.x = startVBX - dx; + viewBox.y = startVBY - dy; + updateViewBox(); + } + + function onPointerUp(e: PointerEvent) { + if (!isPanning) return; + isPanning = false; + svg.releasePointerCapture(e.pointerId); + svg.style.cursor = 'grab'; + } + + svg.style.cursor = 'grab'; + svg.addEventListener('wheel', onWheel, { passive: false }); + svg.addEventListener('pointerdown', onPointerDown); + svg.addEventListener('pointermove', onPointerMove); + svg.addEventListener('pointerup', onPointerUp); + + return { + destroy() { + svg.removeEventListener('wheel', onWheel); + svg.removeEventListener('pointerdown', onPointerDown); + svg.removeEventListener('pointermove', onPointerMove); + svg.removeEventListener('pointerup', onPointerUp); + }, + }; +} diff --git a/xircuits-graph-viewer/packages/core/src/layout/metrics.ts b/xircuits-graph-viewer/packages/core/src/layout/metrics.ts new file mode 100644 index 00000000..e1a5884d --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/layout/metrics.ts @@ -0,0 +1,95 @@ +import type { XNode, NodeMetrics } from '../types.js'; + +// Constants derived from Xircuits CSS +export const TITLE_HEIGHT = 26; +export const PORT_ROW_HEIGHT = 19; // 15px port + 2px margin top + 2px margin bottom +export const NODE_MIN_WIDTH = 100; +export const PORT_GAP = 10; // gap between in-port column and out-port column (margin-right: 10px) +export const PORT_DOT_SIZE = 15; +export const FONT_SIZE = 11; +export const CHAR_WIDTH = 6.6; // approx for sans-serif 11px +export const TITLE_ICON_SIZE = 15; +export const TITLE_PADDING_X = 5; +export const TITLE_PADDING_Y = 5; +export const PORT_LABEL_PADDING = 5; // padding: 0 5px on label +export const COMMENT_FONT_SIZE = 12; +export const COMMENT_CHAR_WIDTH = 7.2; +export const COMMENT_PADDING = 5; + +export function measureTextWidth(text: string, charWidth: number = CHAR_WIDTH): number { + return text.length * charWidth; +} + +export function computeNodeMetrics(node: XNode): NodeMetrics { + if (node.kind === 'comment') { + return computeCommentMetrics(node); + } + + // Title width = icon + padding + name text + padding + const titleTextWidth = TITLE_PADDING_X + TITLE_ICON_SIZE + TITLE_PADDING_X + measureTextWidth(node.name) + TITLE_PADDING_X; + + // In-ports column width: dot(15) + label padding(5) + label text + label padding(5) + let maxInWidth = 0; + for (const port of node.portsIn) { + const labelW = measureTextWidth(port.label) + PORT_LABEL_PADDING * 2; + maxInWidth = Math.max(maxInWidth, PORT_DOT_SIZE + labelW); + } + + // Out-ports column width: label padding(5) + label text + label padding(5) + dot(15) + let maxOutWidth = 0; + for (const port of node.portsOut) { + const labelW = measureTextWidth(port.label) + PORT_LABEL_PADDING * 2; + maxOutWidth = Math.max(maxOutWidth, labelW + PORT_DOT_SIZE); + } + + const hasIn = node.portsIn.length > 0; + const hasOut = node.portsOut.length > 0; + const portsWidth = maxInWidth + (hasIn && hasOut ? PORT_GAP : 0) + maxOutWidth; + + const width = Math.max(NODE_MIN_WIDTH, titleTextWidth, portsWidth); + + const maxPortCount = Math.max(node.portsIn.length, node.portsOut.length); + const bodyHeight = maxPortCount > 0 ? maxPortCount * PORT_ROW_HEIGHT : 0; + const height = TITLE_HEIGHT + bodyHeight; + + // Compute port positions (relative to node top-left, at the connection point) + const portPositions = new Map(); + + node.portsIn.forEach((port, i) => { + portPositions.set(port.id, { + x: 0, // left edge of node + y: TITLE_HEIGHT + i * PORT_ROW_HEIGHT + PORT_ROW_HEIGHT / 2, + }); + }); + + node.portsOut.forEach((port, i) => { + portPositions.set(port.id, { + x: width, // right edge of node + y: TITLE_HEIGHT + i * PORT_ROW_HEIGHT + PORT_ROW_HEIGHT / 2, + }); + }); + + return { width, height, titleHeight: TITLE_HEIGHT, portRowHeight: PORT_ROW_HEIGHT, portPositions }; +} + +function computeCommentMetrics(node: XNode): NodeMetrics { + const title = 'Comment:'; + const text = (node.extras.commentInput as string) || ''; + const lines = text.split('\n'); + + const titleWidth = measureTextWidth(title, COMMENT_CHAR_WIDTH) + COMMENT_PADDING * 2; + const maxLineWidth = Math.max(...lines.map(l => measureTextWidth(l, COMMENT_CHAR_WIDTH))); + const width = Math.max(NODE_MIN_WIDTH, titleWidth, maxLineWidth + COMMENT_PADDING * 2); + + // title line + content lines + padding + const lineHeight = 18; + const height = COMMENT_PADDING + 16 + lines.length * lineHeight + COMMENT_PADDING; + + return { + width, + height, + titleHeight: 0, + portRowHeight: 0, + portPositions: new Map(), + }; +} diff --git a/xircuits-graph-viewer/packages/core/src/layout/viewBox.ts b/xircuits-graph-viewer/packages/core/src/layout/viewBox.ts new file mode 100644 index 00000000..714b7e29 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/layout/viewBox.ts @@ -0,0 +1,40 @@ +import type { XNode, NodeMetrics } from '../types.js'; + +export interface ViewBox { + x: number; + y: number; + width: number; + height: number; +} + +export function computeViewBox( + nodes: XNode[], + metricsMap: Map, + padding: number = 40 +): ViewBox { + if (nodes.length === 0) { + return { x: 0, y: 0, width: 800, height: 600 }; + } + + let minX = Infinity; + let minY = Infinity; + let maxX = -Infinity; + let maxY = -Infinity; + + for (const node of nodes) { + const metrics = metricsMap.get(node.id); + if (!metrics) continue; + + minX = Math.min(minX, node.x); + minY = Math.min(minY, node.y); + maxX = Math.max(maxX, node.x + metrics.width); + maxY = Math.max(maxY, node.y + metrics.height); + } + + return { + x: minX - padding, + y: minY - padding, + width: maxX - minX + padding * 2, + height: maxY - minY + padding * 2, + }; +} diff --git a/xircuits-graph-viewer/packages/core/src/parser/classify.ts b/xircuits-graph-viewer/packages/core/src/parser/classify.ts new file mode 100644 index 00000000..4ed1a30c --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/parser/classify.ts @@ -0,0 +1,58 @@ +import type { NodeKind, PortKind, PortDirection, EdgeKind } from '../types.js'; + +export function classifyNode(name: string, extras: Record): NodeKind { + const type = extras.type as string | undefined; + + if (type === 'comment') return 'comment'; + if (name.startsWith('Literal') || name.startsWith('Argument')) return 'literal'; + if (type === 'xircuits_workflow') return 'workflow'; + if (name === 'Start') return 'start'; + if (name === 'Finish') return 'finish'; + + // Sub-kinds from extras.type + if (type === 'branch') return 'branch'; + if (type === 'function') return 'function'; + if (type === 'context_set') return 'context_set'; + if (type === 'context_get') return 'context_get'; + if (type === 'variable') return 'variable'; + + return 'component'; +} + +export function classifyPort( + portName: string, + label: string, + isIn: boolean, + nodeName: string +): { kind: PortKind; direction: PortDirection; dataType: string | null; varName: string } { + const direction: PortDirection = isIn ? 'in' : 'out'; + + // Flow ports: name starts with "in-" or "out-" (flow connectors with ▶ label) + const isFlowPort = + label === '▶' && !nodeName.startsWith('Argument'); + + if (isFlowPort || portName.startsWith('out-') && label === '▶' || portName.startsWith('in-') && label === '▶') { + return { kind: 'flow', direction, dataType: null, varName: label }; + } + + // Parameter ports: "parameter-TYPE-NAME" or "parameter-out-TYPE-NAME" + let dataType: string | null = null; + let varName = label; + + if (portName.startsWith('parameter-')) { + const parts = portName.split('-'); + if (parts[1] === 'out') { + // parameter-out-TYPE-NAME + dataType = parts[2] || null; + } else { + // parameter-TYPE-NAME + dataType = parts[1] || null; + } + } + + return { kind: 'parameter', direction, dataType, varName }; +} + +export function classifyEdge(type: string): EdgeKind { + return type === 'triangle-link' ? 'flow' : 'data'; +} diff --git a/xircuits-graph-viewer/packages/core/src/parser/parse.ts b/xircuits-graph-viewer/packages/core/src/parser/parse.ts new file mode 100644 index 00000000..31795314 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/parser/parse.ts @@ -0,0 +1,156 @@ +import type { XGraph, XNode, XEdge, XPort } from '../types.js'; +import { classifyNode, classifyPort, classifyEdge } from './classify.js'; +import { validate } from './validate.js'; + +interface RawPort { + id: string; + name: string; + alignment: string; + parentNode: string; + links: string[]; + in: boolean; + label: string; + varName: string; + dataType: string; + x: number; + y: number; + extras?: Record; +} + +interface RawNode { + id: string; + type: string; + extras: Record; + x: number; + y: number; + ports: RawPort[]; + name: string; + color: string; + portsInOrder: string[]; + portsOutOrder: string[]; +} + +interface RawLink { + id: string; + type: string; + source: string; + sourcePort: string; + target: string; + targetPort: string; + points: Array<{ x: number; y: number }>; + color: string; + width: number; + curvyness: number; + selectedColor: string; +} + +interface RawLayer { + type: string; + models: Record; +} + +export function parse(json: unknown): XGraph { + const { valid, errors } = validate(json); + if (!valid) { + throw new Error(`Invalid .xircuits file: ${errors.join(', ')}`); + } + + const obj = json as Record; + const layers = obj.layers as RawLayer[]; + + const linkLayer = layers.find(l => l.type === 'diagram-links'); + const nodeLayer = layers.find(l => l.type === 'diagram-nodes')!; + + const rawNodes = Object.values(nodeLayer.models) as RawNode[]; + const rawLinks = linkLayer + ? (Object.values(linkLayer.models) as RawLink[]) + : []; + + // Build a port ID set for quick lookup + const portMap = new Map(); + for (const rawNode of rawNodes) { + for (const port of rawNode.ports) { + portMap.set(port.id, port); + } + } + + const nodes: XNode[] = rawNodes.map(raw => { + const kind = classifyNode(raw.name, raw.extras); + + // Order ports according to portsInOrder/portsOutOrder + const portsInOrdered = orderPorts(raw.ports, raw.portsInOrder, true); + const portsOutOrdered = orderPorts(raw.ports, raw.portsOutOrder, false); + + const portsIn: XPort[] = portsInOrdered.map(p => { + const cls = classifyPort(p.name, p.label, true, raw.name); + return { + id: p.id, + direction: cls.direction, + kind: cls.kind, + label: p.label, + varName: cls.varName, + dataType: p.dataType || cls.dataType, + linkIds: p.links || [], + }; + }); + + const portsOut: XPort[] = portsOutOrdered.map(p => { + const cls = classifyPort(p.name, p.label, false, raw.name); + return { + id: p.id, + direction: cls.direction, + kind: cls.kind, + label: p.label, + varName: cls.varName, + dataType: p.dataType || cls.dataType, + linkIds: p.links || [], + }; + }); + + return { + id: raw.id, + kind, + name: raw.name, + color: raw.color || 'red', + x: raw.x, + y: raw.y, + portsIn, + portsOut, + extras: raw.extras || {}, + }; + }); + + const edges: XEdge[] = rawLinks.map(raw => ({ + id: raw.id, + kind: classifyEdge(raw.type), + sourceNodeId: raw.source, + sourcePortId: raw.sourcePort, + targetNodeId: raw.target, + targetPortId: raw.targetPort, + points: raw.points || [], + color: raw.color || 'gray', + })); + + return { + id: obj.id as string, + viewport: { + x: (obj.offsetX as number) || 0, + y: (obj.offsetY as number) || 0, + zoom: (obj.zoom as number) || 100, + }, + nodes, + edges, + }; +} + +function orderPorts( + ports: RawPort[], + order: string[], + isIn: boolean +): RawPort[] { + if (!order || order.length === 0) { + return ports.filter(p => p.in === isIn); + } + const portById = new Map(ports.map(p => [p.id, p])); + return order.map(id => portById.get(id)).filter((p): p is RawPort => p != null); +} diff --git a/xircuits-graph-viewer/packages/core/src/parser/validate.ts b/xircuits-graph-viewer/packages/core/src/parser/validate.ts new file mode 100644 index 00000000..3d00218c --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/parser/validate.ts @@ -0,0 +1,40 @@ +export function validate(json: unknown): { valid: boolean; errors: string[] } { + const errors: string[] = []; + + if (!json || typeof json !== 'object') { + return { valid: false, errors: ['Input must be an object'] }; + } + + const obj = json as Record; + + if (typeof obj.id !== 'string') { + errors.push('Missing or invalid "id" field'); + } + + if (!Array.isArray(obj.layers)) { + errors.push('Missing or invalid "layers" array'); + return { valid: false, errors }; + } + + const layers = obj.layers as Array>; + + const linkLayer = layers.find(l => l.type === 'diagram-links'); + const nodeLayer = layers.find(l => l.type === 'diagram-nodes'); + + if (!nodeLayer) { + errors.push('Missing diagram-nodes layer'); + } + + if (!linkLayer) { + // Links layer is optional (a graph with no connections) + } + + if (nodeLayer) { + const models = nodeLayer.models; + if (!models || typeof models !== 'object') { + errors.push('diagram-nodes layer missing "models" object'); + } + } + + return { valid: errors.length === 0, errors }; +} diff --git a/xircuits-graph-viewer/packages/core/src/render/colors.ts b/xircuits-graph-viewer/packages/core/src/render/colors.ts new file mode 100644 index 00000000..c2293b4e --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/render/colors.ts @@ -0,0 +1,91 @@ +// Color utilities for title bar gradients. +// Replicates the Xircuits oklch gradient logic from CustomNodeWidget.tsx. +// Outputs oklch() CSS — requires a modern browser or renderer for full fidelity. + +function parseColor(color: string): { r: number; g: number; b: number } { + const named: Record = { + red: '#ff0000', blue: '#0000ff', green: '#008000', yellow: '#ffff00', + orange: '#ffa500', purple: '#800080', pink: '#ffc0cb', lightpink: '#ffb6c1', + cyan: '#00ffff', white: '#ffffff', black: '#000000', gray: '#808080', + grey: '#808080', salmon: '#fa8072', coral: '#ff7f50', teal: '#008080', + navy: '#000080', maroon: '#800000', lime: '#00ff00', magenta: '#ff00ff', + darkred: '#8b0000', darkblue: '#00008b', darkgreen: '#006400', + goldenrod: '#daa520', tomato: '#ff6347', orchid: '#da70d6', + }; + + const lower = color.toLowerCase().trim(); + if (named[lower]) color = named[lower]; + + const hexMatch = color.match(/^#([0-9a-f]{3,8})$/i); + if (hexMatch) { + let hex = hexMatch[1]; + if (hex.length === 3) hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; + return { + r: parseInt(hex.slice(0, 2), 16) / 255, + g: parseInt(hex.slice(2, 4), 16) / 255, + b: parseInt(hex.slice(4, 6), 16) / 255, + }; + } + + const rgbMatch = color.match(/rgb\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/); + if (rgbMatch) { + return { + r: parseInt(rgbMatch[1]) / 255, + g: parseInt(rgbMatch[2]) / 255, + b: parseInt(rgbMatch[3]) / 255, + }; + } + + return { r: 0.5, g: 0.5, b: 0.5 }; +} + +function srgbToLinear(c: number): number { + return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); +} + +function toOklab(r: number, g: number, b: number) { + const l_ = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b; + const m_ = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b; + const s_ = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b; + const l = Math.cbrt(l_), m = Math.cbrt(m_), s = Math.cbrt(s_); + return { + L: 0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s, + a: 1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s, + b: 0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s, + }; +} + +function rgbToOklch(color: string): { l: number; c: number; h: number } { + const { r, g, b } = parseColor(color); + const lab = toOklab(srgbToLinear(r), srgbToLinear(g), srgbToLinear(b)); + const c = Math.sqrt(lab.a * lab.a + lab.b * lab.b); + let h = Math.atan2(lab.b, lab.a) * (180 / Math.PI); + if (h < 0) h += 360; + return { l: lab.L, c, h }; +} + +export interface GradientColors { + color1: string; + color2: string; +} + +/** + * Replicate the Xircuits title gradient from CustomNodeWidget.tsx: + * const color = new Color(p.background); + * color.alpha = 0.75; color.oklch.c *= 1.2; + * const color1 = color.to('oklch').toString() + * color.oklch.c *= 1.2; color.oklch.l /= 2; + * const color2 = color.to('oklch').toString() + */ +export function titleGradient(baseColor: string): GradientColors { + const oklch = rgbToOklch(baseColor); + + const c1_c = oklch.c * 1.2; + const c1 = `oklch(${(oklch.l * 100).toFixed(1)}% ${c1_c.toFixed(4)} ${oklch.h.toFixed(1)} / 0.75)`; + + const c2_c = c1_c * 1.2; + const c2_l = oklch.l / 2; + const c2 = `oklch(${(c2_l * 100).toFixed(1)}% ${c2_c.toFixed(4)} ${oklch.h.toFixed(1)} / 0.75)`; + + return { color1: c1, color2: c2 }; +} diff --git a/xircuits-graph-viewer/packages/core/src/render/renderDefs.ts b/xircuits-graph-viewer/packages/core/src/render/renderDefs.ts new file mode 100644 index 00000000..067980dd --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/render/renderDefs.ts @@ -0,0 +1,218 @@ +import { el } from '../svg/builder.js'; +import type { XNode } from '../types.js'; +import { titleGradient } from './colors.js'; + +export function renderDefs(nodes: XNode[], theme: 'dark' | 'light'): string { + const gradients: string[] = []; + const seenColors = new Set(); + + for (const node of nodes) { + if (node.kind === 'comment') continue; + const color = node.color; + if (seenColors.has(color)) continue; + seenColors.add(color); + + const { color1, color2 } = titleGradient(color); + const gradId = colorToGradientId(color); + gradients.push( + el('linearGradient', { id: gradId, x1: '0', y1: '0', x2: '0', y2: '1' }, + el('stop', { offset: '0%', 'stop-color': color1 }), + el('stop', { offset: '100%', 'stop-color': color2 }), + ) + ); + } + + const style = renderStyleBlock(theme); + + const flowInSymbol = el('symbol', { id: 'xg-flow-in', viewBox: '0 0 24 24' }, + el('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + el('path', { d: 'M3 12h12' }), + el('path', { d: 'M11 8l4 4l-4 4' }), + el('path', { d: 'M12 21a9 9 0 0 0 0 -18' }), + ); + + const flowOutSymbol = el('symbol', { id: 'xg-flow-out', viewBox: '0 0 24 24' }, + el('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + el('path', { d: 'M9 12h12' }), + el('path', { d: 'M17 16l4 -4l-4 -4' }), + el('path', { d: 'M12 3a9 9 0 1 0 0 18' }), + ); + + // Node icon symbols (from style/icons/*.svg in the Xircuits repo) + const nodeIcons = renderNodeIconSymbols(); + + return el('defs', {}, + style, + ...gradients, + flowInSymbol, + flowOutSymbol, + nodeIcons, + ); +} + +export function colorToGradientId(color: string): string { + return 'xg-grad-' + color.replace(/[^a-zA-Z0-9]/g, '_'); +} + +function renderNodeIconSymbols(): string { + const s = el; + // Each symbol extracted from style/icons/*.svg in the Xircuits repo + // All use viewBox="0 0 24 24", stroke="currentColor" (inherited) + + const icons: string[] = []; + + // start-finish-component.svg (filled direction sign diamond) + icons.push(s('symbol', { id: 'xg-icon-start-finish', viewBox: '0 0 24 24', fill: 'currentColor' }, + s('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + s('path', { d: 'M10.52 2.614a2.095 2.095 0 0 1 2.835 -.117l.126 .117l7.905 7.905c.777 .777 .816 2.013 .117 2.836l-.117 .126l-7.905 7.905a2.094 2.094 0 0 1 -2.836 .117l-.126 -.117l-7.907 -7.906a2.096 2.096 0 0 1 -.115 -2.835l.117 -.126l7.905 -7.905zm5.969 9.535l.01 -.116l-.003 -.12l-.016 -.114l-.03 -.11l-.044 -.112l-.052 -.098l-.076 -.105l-.07 -.081l-3.5 -3.5l-.095 -.083a1 1 0 0 0 -1.226 0l-.094 .083l-.083 .094a1 1 0 0 0 0 1.226l.083 .094l1.792 1.793h-5.085l-.117 .007a1 1 0 0 0 0 1.986l.117 .007h5.085l-1.792 1.793l-.083 .094a1 1 0 0 0 1.403 1.403l.094 -.083l3.5 -3.5l.097 -.112l.05 -.074l.037 -.067l.05 -.112l.023 -.076l.025 -.117z' }), + )); + + // component-library.svg (3D cube outline) + icons.push(s('symbol', { id: 'xg-icon-component', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': 2, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }, + s('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + s('path', { d: 'M21 16.008v-8.018a1.98 1.98 0 0 0 -1 -1.717l-7 -4.008a2.016 2.016 0 0 0 -2 0l-7 4.008c-.619 .355 -1 1.01 -1 1.718v8.018c0 .709 .381 1.363 1 1.717l7 4.008a2.016 2.016 0 0 0 2 0l7 -4.008c.619 -.355 1 -1.01 1 -1.718z' }), + s('path', { d: 'M12 22v-10' }), + s('path', { d: 'M12 12l8.73 -5.04' }), + s('path', { d: 'M3.27 6.96l8.73 5.04' }), + )); + + // workflow-component.svg (chart dots) + icons.push(s('symbol', { id: 'xg-icon-workflow', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': 2, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }, + s('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + s('path', { d: 'M5 7m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0' }), + s('path', { d: 'M16 15m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0' }), + s('path', { d: 'M18 6m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0' }), + s('path', { d: 'M6 18m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0' }), + s('path', { d: 'M9 17l5 -1.5' }), + s('path', { d: 'M6.5 8.5l7.81 5.37' }), + s('path', { d: 'M7 7l8 -1' }), + )); + + // branch-component.svg (arrows split) + icons.push(s('symbol', { id: 'xg-icon-branch', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': 2, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }, + s('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + s('path', { d: 'M21 17h-8l-3.5 -5h-6.5' }), + s('path', { d: 'M21 7h-8l-3.495 5' }), + s('path', { d: 'M18 10l3 -3l-3 -3' }), + s('path', { d: 'M18 20l3 -3l-3 -3' }), + )); + + // function-component.svg (math function) + icons.push(s('symbol', { id: 'xg-icon-function', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': 2.5, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }, + s('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + s('path', { d: 'M3 19a2 2 0 0 0 2 2c2 0 2 -4 3 -9s1 -9 3 -9a2 2 0 0 1 2 2' }), + s('path', { d: 'M5 12h6' }), + s('path', { d: 'M15 12l6 6' }), + s('path', { d: 'M15 18l6 -6' }), + )); + + // set-variable-component.svg (world upload) + icons.push(s('symbol', { id: 'xg-icon-context_set', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': 2, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }, + s('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + s('path', { d: 'M21 12a9 9 0 1 0 -9 9' }), + s('path', { d: 'M3.6 9h16.8' }), + s('path', { d: 'M3.6 15h8.4' }), + s('path', { d: 'M11.578 3a17 17 0 0 0 0 18' }), + s('path', { d: 'M12.5 3c1.719 2.755 2.5 5.876 2.5 9' }), + s('path', { d: 'M18 21v-7m3 3l-3 -3l-3 3' }), + )); + + // get-variable-component.svg (world download) + icons.push(s('symbol', { id: 'xg-icon-context_get', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': 2, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }, + s('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + s('path', { d: 'M21 12a9 9 0 1 0 -9 9' }), + s('path', { d: 'M3.6 9h16.8' }), + s('path', { d: 'M3.6 15h8.4' }), + s('path', { d: 'M11.578 3a17 17 0 0 0 0 18' }), + s('path', { d: 'M12.5 3c1.719 2.755 2.5 5.876 2.5 9' }), + s('path', { d: 'M18 14v7m-3 -3l3 3l3 -3' }), + )); + + // variable-component.svg (variable x) + icons.push(s('symbol', { id: 'xg-icon-variable', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': 2, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }, + s('path', { stroke: 'none', d: 'M0 0h24v24H0z', fill: 'none' }), + s('path', { d: 'M5 4c-2.5 5 -2.5 10 0 16m14 -16c2.5 5 2.5 10 0 16m-10 -11h1c1 0 1 1 2.016 3.527c.984 2.473 .984 3.473 1.984 3.473h1' }), + s('path', { d: 'M8 16c1.5 0 3 -2 4 -3.5s2.5 -3.5 4 -3.5' }), + )); + + return icons.join(''); +} + +function renderStyleBlock(theme: 'dark' | 'light'): string { + const isDark = theme === 'dark'; + const css = ` +.xg-root { + font-family: sans-serif; + font-size: 11px; +} +.xg-node__border { + fill: none; + stroke: ${isDark ? 'black' : 'oklch(0.8 0 0)'}; + stroke-width: 1; +} +.xg-node__title-text { + fill: white; + font-weight: 500; + letter-spacing: 0.025rem; +} +.xg-node__body { + fill: ${isDark + ? 'oklch(10% 0 0 / 0.85)' + : 'oklch(99% 0 0 / 0.85)'}; + stroke: none; +} +.xg-port__dot { + fill: oklch(50% 0 0 / 0.2); + stroke: oklch(0 0 0 / 0.2); + stroke-width: 1; +} +.xg-port__dot--connected { + fill: oklch(100% 0 0 / 0.5); +} +.xg-port__label { + fill: ${isDark ? 'white' : 'black'}; +} +.xg-port__symbol { + font-weight: bold; + font-family: Helvetica, Arial, sans-serif; +} +.xg-port__symbol--connected { fill: black; } +.xg-port__symbol--disconnected { fill: grey; } +.xg-port--flow use { + stroke-width: 3; + stroke-linecap: round; + stroke-linejoin: round; + fill: none; +} +.xg-port--flow--connected use { stroke: oklch(0% 0 0 / 0.8); } +.xg-port--flow--disconnected use { stroke: oklch(100% 0 0 / 0.8); } +.xg-edge--flow { + stroke: rgb(0, 192, 255); + stroke-width: 3; + fill: none; + stroke-dasharray: 10 2; + animation: xg-flow 1s steps(24) infinite; + filter: drop-shadow(2px 2px 4px rgb(0 0 0 / 40%)) opacity(60%); +} +.xg-edge--data { + stroke: gray; + stroke-width: 3; + fill: none; + filter: drop-shadow(2px 2px 4px rgb(0 0 0 / 40%)) opacity(60%); +} +.xg-comment__bg { + fill: ${isDark ? 'rgba(0, 0, 0, 0.3)' : 'oklch(0.98 0.13 108.65)'}; + stroke: ${isDark ? 'black' : '#ccc'}; + stroke-width: 2; + rx: 5; +} +.xg-comment__text { + fill: ${isDark ? 'white' : 'black'}; +} +@keyframes xg-flow { + from { stroke-dashoffset: 24; } + to { stroke-dashoffset: 0; } +} +`; + return el('style', {}, css); +} diff --git a/xircuits-graph-viewer/packages/core/src/render/renderEdge.ts b/xircuits-graph-viewer/packages/core/src/render/renderEdge.ts new file mode 100644 index 00000000..acc169c4 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/render/renderEdge.ts @@ -0,0 +1,23 @@ +import type { XEdge, XNode, NodeMetrics, RenderOptions } from '../types.js'; +import { g, el } from '../svg/builder.js'; +import { bezierPath } from '../svg/bezier.js'; + +export function renderEdge( + edge: XEdge, + nodesById: Map, + metricsMap: Map, + options?: RenderOptions, +): string { + if (!edge.points || edge.points.length < 2) return ''; + + const p0 = edge.points[0]; + const p1 = edge.points[edge.points.length - 1]; + const d = bezierPath(p0.x, p0.y, p1.x, p1.y, 50); + const extraClass = options?.edgeClassFn?.(edge) || ''; + const cls = edge.kind === 'flow' ? 'xg-edge xg-edge--flow' : 'xg-edge xg-edge--data'; + + return g( + { class: `xg-edge-group ${extraClass}`.trim(), 'data-edge-id': edge.id }, + el('path', { class: cls, d }), + ); +} diff --git a/xircuits-graph-viewer/packages/core/src/render/renderGraph.ts b/xircuits-graph-viewer/packages/core/src/render/renderGraph.ts new file mode 100644 index 00000000..8d0c2fd3 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/render/renderGraph.ts @@ -0,0 +1,61 @@ +import type { XGraph, RenderOptions, NodeMetrics } from '../types.js'; +import { svgRoot, g, el } from '../svg/builder.js'; +import { computeNodeMetrics } from '../layout/metrics.js'; +import { computeViewBox } from '../layout/viewBox.js'; +import { renderDefs } from './renderDefs.js'; +import { renderNode } from './renderNode.js'; +import { renderEdge } from './renderEdge.js'; +import { parse } from '../parser/parse.js'; + +export function renderToString(graph: XGraph, options: RenderOptions = {}): string { + const { + theme = 'dark', + padding = 40, + fitView = true, + className, + width, + height, + } = options; + + const metricsMap = new Map(); + for (const node of graph.nodes) { + metricsMap.set(node.id, computeNodeMetrics(node)); + } + + const viewBox = fitView + ? computeViewBox(graph.nodes, metricsMap, padding) + : { x: -graph.viewport.x, y: -graph.viewport.y, width: width || 800, height: height || 600 }; + + const nodesById = new Map(graph.nodes.map(n => [n.id, n])); + const defs = renderDefs(graph.nodes, theme); + + const edgeElements = graph.edges.map(edge => renderEdge(edge, nodesById, metricsMap, options)); + const nodeElements = graph.nodes.map(node => renderNode(node, metricsMap.get(node.id)!, options)); + + const rootClass = ['xg-root', className].filter(Boolean).join(' '); + + return svgRoot( + { + viewBox: `${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`, + class: rootClass, + 'data-theme': theme, + ...(width ? { width } : {}), + ...(height ? { height } : {}), + }, + defs, + g({ class: 'xg-edges' }, ...edgeElements), + g({ class: 'xg-nodes' }, ...nodeElements), + ); +} + +export function renderToElement(graph: XGraph, options: RenderOptions = {}): SVGSVGElement { + const svgString = renderToString(graph, options); + const parser = new DOMParser(); + const doc = parser.parseFromString(svgString, 'image/svg+xml'); + return doc.documentElement as unknown as SVGSVGElement; +} + +export function renderXircuits(json: unknown, options: RenderOptions = {}): string { + const graph = parse(json); + return renderToString(graph, options); +} diff --git a/xircuits-graph-viewer/packages/core/src/render/renderNode.ts b/xircuits-graph-viewer/packages/core/src/render/renderNode.ts new file mode 100644 index 00000000..11877176 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/render/renderNode.ts @@ -0,0 +1,117 @@ +import type { XNode, NodeMetrics, RenderOptions } from '../types.js'; +import { g, rect, text, el, escapeXml } from '../svg/builder.js'; +import { colorToGradientId } from './renderDefs.js'; +import { renderPort } from './renderPort.js'; +import { FONT_SIZE, TITLE_HEIGHT, TITLE_PADDING_X, TITLE_ICON_SIZE, COMMENT_PADDING } from '../layout/metrics.js'; + +export function renderNode( + node: XNode, + metrics: NodeMetrics, + options?: RenderOptions, +): string { + const extraClass = options?.nodeClassFn?.(node) || ''; + + if (node.kind === 'comment') { + return renderCommentNode(node, metrics, extraClass); + } + + return renderStandardNode(node, metrics, extraClass); +} + +function renderStandardNode(node: XNode, metrics: NodeMetrics, extraClass: string): string { + const gradientId = colorToGradientId(node.color); + const { width, height } = metrics; + const bodyHeight = height - TITLE_HEIGHT; + + const elements: string[] = []; + + // Border + elements.push(rect({ x: 0, y: 0, width, height, rx: 5, ry: 5, class: 'xg-node__border' })); + + // Title gradient + elements.push(rect({ x: 0, y: 0, width, height: TITLE_HEIGHT, rx: 5, ry: 5, fill: `url(#${gradientId})` })); + if (bodyHeight > 0) { + elements.push(rect({ x: 0, y: TITLE_HEIGHT - 5, width, height: 5, fill: `url(#${gradientId})` })); + } + + // Icon + elements.push(renderNodeIcon(node.kind, TITLE_PADDING_X, (TITLE_HEIGHT - TITLE_ICON_SIZE) / 2)); + + // Name + elements.push(text( + { x: TITLE_PADDING_X + TITLE_ICON_SIZE + TITLE_PADDING_X, y: TITLE_HEIGHT - 8, 'font-size': FONT_SIZE, class: 'xg-node__title-text' }, + node.name.length > 40 ? node.name.slice(0, 39) + '…' : node.name, + )); + + // Body + if (bodyHeight > 0) { + elements.push(rect({ x: 0, y: TITLE_HEIGHT, width, height: bodyHeight, rx: 5, ry: 5, class: 'xg-node__body' })); + elements.push(rect({ x: 0, y: TITLE_HEIGHT, width, height: Math.min(5, bodyHeight), class: 'xg-node__body' })); + } + + // Ports + node.portsIn.forEach((port, i) => elements.push(renderPort(port, width, i, TITLE_HEIGHT))); + node.portsOut.forEach((port, i) => elements.push(renderPort(port, width, i, TITLE_HEIGHT))); + + return g( + { class: `xg-node xg-node--${node.kind} ${extraClass}`.trim(), transform: `translate(${node.x}, ${node.y})`, 'data-node-id': node.id }, + ...elements, + ); +} + +function renderCommentNode(node: XNode, metrics: NodeMetrics, extraClass: string): string { + const { width, height } = metrics; + const commentText = (node.extras.commentInput as string) || ''; + const elements: string[] = []; + + elements.push(rect({ x: 0, y: 0, width, height, rx: 5, ry: 5, class: 'xg-comment__bg' })); + elements.push(text( + { x: COMMENT_PADDING, y: COMMENT_PADDING + 12, 'font-size': 12, 'font-weight': 'bold', class: 'xg-comment__text' }, + 'Comment:', + )); + + const lines = commentText.split('\n'); + const tspans = lines.map((line, i) => + el('tspan', { x: COMMENT_PADDING, dy: i === 0 ? 18 : 18 }, escapeXml(line)) + ).join(''); + elements.push(el('text', { x: COMMENT_PADDING, y: COMMENT_PADDING + 14, 'font-size': 12, class: 'xg-comment__text' }, tspans)); + + return g( + { class: `xg-node xg-node--comment ${extraClass}`.trim(), transform: `translate(${node.x}, ${node.y})`, 'data-node-id': node.id }, + ...elements, + ); +} + +// Map node kind → symbol ID (matching getNodeIcon in CustomNodeWidget.tsx) +function getIconSymbolId(kind: string, extrasType?: string): string { + switch (kind) { + case 'start': + case 'finish': + return 'xg-icon-start-finish'; + case 'workflow': + return 'xg-icon-workflow'; + case 'branch': + return 'xg-icon-branch'; + case 'function': + return 'xg-icon-function'; + case 'context_set': + return 'xg-icon-context_set'; + case 'context_get': + return 'xg-icon-context_get'; + case 'variable': + return 'xg-icon-variable'; + default: + return 'xg-icon-component'; + } +} + +function renderNodeIcon(kind: string, x: number, y: number): string { + const symbolId = getIconSymbolId(kind); + return el('use', { + href: `#${symbolId}`, + x, y, + width: TITLE_ICON_SIZE, + height: TITLE_ICON_SIZE, + color: 'white', + }); +} diff --git a/xircuits-graph-viewer/packages/core/src/render/renderPort.ts b/xircuits-graph-viewer/packages/core/src/render/renderPort.ts new file mode 100644 index 00000000..4ef7c675 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/render/renderPort.ts @@ -0,0 +1,83 @@ +import type { XPort } from '../types.js'; +import { g, text, el } from '../svg/builder.js'; +import { getPortSymbol } from './symbols.js'; +import { PORT_ROW_HEIGHT, PORT_DOT_SIZE, FONT_SIZE, PORT_LABEL_PADDING } from '../layout/metrics.js'; + +const SYMBOL_FONT_SIZE = 9; + +export function renderPort( + port: XPort, + nodeWidth: number, + rowIndex: number, + titleHeight: number, +): string { + const isOut = port.direction === 'out'; + const y = titleHeight + rowIndex * PORT_ROW_HEIGHT; + const isConnected = port.linkIds.length > 0; + const isFlow = port.kind === 'flow'; + const dotY = y + (PORT_ROW_HEIGHT - PORT_DOT_SIZE) / 2; + + if (isOut) { + const dotX = nodeWidth - PORT_DOT_SIZE; + const dot = renderDot(port, dotX, dotY, isOut, isConnected, isFlow); + const label = isFlow ? '' : renderLabel(port.label, dotX - PORT_LABEL_PADDING, y, 'end'); + return g({ class: `xg-port xg-port--out xg-port--${isFlow ? 'flow' : 'param'}`, 'data-port-id': port.id }, dot, label); + } else { + const dotX = 0; + const dot = renderDot(port, dotX, dotY, isOut, isConnected, isFlow); + const label = isFlow ? '' : renderLabel(port.label, PORT_DOT_SIZE + PORT_LABEL_PADDING, y, 'start'); + return g({ class: `xg-port xg-port--in xg-port--${isFlow ? 'flow' : 'param'}`, 'data-port-id': port.id }, dot, label); + } +} + +function renderDot( + port: XPort, + x: number, + y: number, + isOut: boolean, + isConnected: boolean, + isFlow: boolean, +): string { + const elements: string[] = []; + const w = PORT_DOT_SIZE; + const h = PORT_DOT_SIZE; + const r = 8; + + // Half-rounded rect: out-ports rounded on left, in-ports rounded on right + let d: string; + if (isOut) { + d = `M${x + r},${y} L${x + w},${y} L${x + w},${y + h} L${x + r},${y + h} A${r},${r} 0 0,1 ${x},${y + h - r} L${x},${y + r} A${r},${r} 0 0,1 ${x + r},${y}Z`; + } else { + d = `M${x},${y} L${x + w - r},${y} A${r},${r} 0 0,1 ${x + w},${y + r} L${x + w},${y + h - r} A${r},${r} 0 0,1 ${x + w - r},${y + h} L${x},${y + h}Z`; + } + + const connClass = isConnected ? ' xg-port__dot--connected' : ''; + elements.push(el('path', { d, class: `xg-port__dot${connClass}` })); + + if (isFlow) { + const iconRef = isOut ? '#xg-flow-out' : '#xg-flow-in'; + const flowClass = isConnected ? 'xg-port--flow--connected' : 'xg-port--flow--disconnected'; + elements.push(el('g', { class: flowClass }, + el('use', { href: iconRef, x: x + 1.5, y: y + 1.5, width: 12, height: 12 }), + )); + } else { + const symbol = getPortSymbol(port.dataType); + if (symbol) { + const symClass = isConnected ? 'xg-port__symbol xg-port__symbol--connected' : 'xg-port__symbol xg-port__symbol--disconnected'; + elements.push(text( + { x: x + w / 2, y: y + h - 3, 'text-anchor': 'middle', 'font-size': SYMBOL_FONT_SIZE, class: symClass }, + symbol, + )); + } + } + + return elements.join(''); +} + +function renderLabel(label: string, x: number, y: number, anchor: 'start' | 'end'): string { + const displayLabel = label.length > 40 ? label.slice(0, 37) + '...' : label; + return text( + { x, y: y + PORT_ROW_HEIGHT / 2 + FONT_SIZE / 2 - 1, 'text-anchor': anchor, 'font-size': FONT_SIZE, class: 'xg-port__label' }, + displayLabel, + ); +} diff --git a/xircuits-graph-viewer/packages/core/src/render/symbols.ts b/xircuits-graph-viewer/packages/core/src/render/symbols.ts new file mode 100644 index 00000000..76692f02 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/render/symbols.ts @@ -0,0 +1,46 @@ +export const SYMBOL_MAP: Record = { + 'string': '" "', + 'int': ' 1', + 'float': '1.0', + 'boolean': '⊤⊥', + 'time.time': '𝘵', + 'list': '[ ]', + 'tuple': '( )', + 'dict': '{ }', + 'dynalist': '«[]»', + 'dynatuple': '«()»', + 'union': ' U', + 'secret': '🗝️', + 'chat': '🗨', + 'any': '[_]', + '0': null, + 'flow': null, +}; + +export const UNKNOWN_SYMBOL = '◎'; + +export function getPortSymbol(dataType: string | null): string | null { + if (!dataType) return null; + const lower = dataType.toLowerCase(); + if (lower in SYMBOL_MAP) return SYMBOL_MAP[lower]; + return UNKNOWN_SYMBOL; +} + +// Flow port SVG icons (from CustomPortLabel.tsx) +export const FLOW_IN_ICON = [ + '', + '', + '', + '', + '', + '', +].join(''); + +export const FLOW_OUT_ICON = [ + '', + '', + '', + '', + '', + '', +].join(''); diff --git a/xircuits-graph-viewer/packages/core/src/svg/bezier.ts b/xircuits-graph-viewer/packages/core/src/svg/bezier.ts new file mode 100644 index 00000000..cb44d2f8 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/svg/bezier.ts @@ -0,0 +1,14 @@ +/** + * Generate a cubic bezier path between two points. + * Matches react-diagrams' DefaultLinkModel.getSVGPath() behavior: + * control points offset horizontally by `curvyness` (default 50). + */ +export function bezierPath( + x1: number, + y1: number, + x2: number, + y2: number, + curvyness: number = 50, +): string { + return `M${x1},${y1} C${x1 + curvyness},${y1} ${x2 - curvyness},${y2} ${x2},${y2}`; +} diff --git a/xircuits-graph-viewer/packages/core/src/svg/builder.ts b/xircuits-graph-viewer/packages/core/src/svg/builder.ts new file mode 100644 index 00000000..f85e3771 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/svg/builder.ts @@ -0,0 +1,57 @@ +type Attrs = Record; + +function attrString(attrs: Attrs): string { + return Object.entries(attrs) + .filter(([, v]) => v !== undefined && v !== false) + .map(([k, v]) => { + if (v === true) return k; + return `${k}="${escapeAttr(String(v))}"`; + }) + .join(' '); +} + +function escapeAttr(s: string): string { + return s.replace(/&/g, '&').replace(/"/g, '"').replace(//g, '>'); +} + +export function escapeXml(s: string): string { + return s + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +export function el(tag: string, attrs: Attrs, ...children: string[]): string { + const a = attrString(attrs); + const open = a ? `<${tag} ${a}` : `<${tag}`; + if (children.length === 0) { + return `${open}/>`; + } + return `${open}>${children.join('')}`; +} + +export function g(attrs: Attrs, ...children: string[]): string { + return el('g', attrs, ...children); +} + +export function rect(attrs: Attrs): string { + return el('rect', attrs); +} + +export function text(attrs: Attrs, content: string): string { + return el('text', attrs, escapeXml(content)); +} + +export function path(attrs: Attrs): string { + return el('path', attrs); +} + +export function line(attrs: Attrs): string { + return el('line', attrs); +} + +export function svgRoot(attrs: Attrs, ...children: string[]): string { + return el('svg', { xmlns: 'http://www.w3.org/2000/svg', ...attrs }, ...children); +} diff --git a/xircuits-graph-viewer/packages/core/src/types.ts b/xircuits-graph-viewer/packages/core/src/types.ts new file mode 100644 index 00000000..f609425c --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/types.ts @@ -0,0 +1,75 @@ +export type PortDirection = 'in' | 'out'; +export type PortKind = 'flow' | 'parameter'; +export type NodeKind = + | 'start' + | 'finish' + | 'literal' + | 'component' + | 'workflow' + | 'branch' + | 'comment' + | 'function' + | 'context_set' + | 'context_get' + | 'variable'; +export type EdgeKind = 'flow' | 'data'; + +export interface XPort { + id: string; + direction: PortDirection; + kind: PortKind; + label: string; + varName: string; + dataType: string | null; + linkIds: string[]; +} + +export interface XNode { + id: string; + kind: NodeKind; + name: string; + color: string; + x: number; + y: number; + portsIn: XPort[]; + portsOut: XPort[]; + extras: Record; +} + +export interface XEdge { + id: string; + kind: EdgeKind; + sourceNodeId: string; + sourcePortId: string; + targetNodeId: string; + targetPortId: string; + points: Array<{ x: number; y: number }>; + color: string; +} + +export interface XGraph { + id: string; + viewport: { x: number; y: number; zoom: number }; + nodes: XNode[]; + edges: XEdge[]; +} + +export interface RenderOptions { + theme?: 'dark' | 'light'; + width?: number; + height?: number; + padding?: number; + fitView?: boolean; + interactive?: boolean; + className?: string; + nodeClassFn?: (node: XNode) => string; + edgeClassFn?: (edge: XEdge) => string; +} + +export interface NodeMetrics { + width: number; + height: number; + titleHeight: number; + portRowHeight: number; + portPositions: Map; +} diff --git a/xircuits-graph-viewer/packages/core/tsconfig.json b/xircuits-graph-viewer/packages/core/tsconfig.json new file mode 100644 index 00000000..792172fb --- /dev/null +++ b/xircuits-graph-viewer/packages/core/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/xircuits-graph-viewer/packages/react/package.json b/xircuits-graph-viewer/packages/react/package.json new file mode 100644 index 00000000..74d8cf7e --- /dev/null +++ b/xircuits-graph-viewer/packages/react/package.json @@ -0,0 +1,29 @@ +{ + "name": "xircuits-graph-react", + "version": "0.1.0", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "files": ["dist"], + "scripts": { + "build": "tsc", + "dev": "tsc --watch" + }, + "peerDependencies": { + "react": ">=18" + }, + "dependencies": { + "xircuits-graph-core": "workspace:*" + }, + "devDependencies": { + "react": "^18.3.1", + "@types/react": "^18.3.12", + "typescript": "^5.8.3" + } +} diff --git a/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx b/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx new file mode 100644 index 00000000..9ada6db4 --- /dev/null +++ b/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx @@ -0,0 +1,125 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { parse, renderToElement } from 'xircuits-graph-core'; +import { attachPanZoom } from 'xircuits-graph-core/interaction'; +import type { XNode, XEdge } from 'xircuits-graph-core'; + +export interface XircuitsGraphProps { + /** URL or path to a .xircuits file. Fetched at mount time. */ + src?: string; + /** Pre-loaded .xircuits JSON data. Takes precedence over src. */ + data?: object; + theme?: 'dark' | 'light'; + interactive?: boolean; + fitView?: boolean; + width?: number | string; + height?: number | string; + padding?: number; + className?: string; + style?: React.CSSProperties; + onNodeClick?: (node: XNode) => void; + onEdgeClick?: (edge: XEdge) => void; + onError?: (error: Error) => void; +} + +export function XircuitsGraph({ + src, + data, + theme = 'dark', + interactive = true, + fitView = true, + width = '100%', + height = 400, + padding, + className, + style, + onNodeClick, + onEdgeClick, + onError, +}: XircuitsGraphProps) { + const containerRef = useRef(null); + const [fetchedData, setFetchedData] = useState(null); + const [error, setError] = useState(null); + + // Fetch from src when no data is provided + useEffect(() => { + if (data || !src) return; + let cancelled = false; + + fetch(src) + .then(res => { + if (!res.ok) throw new Error(`Failed to load ${src}: ${res.status}`); + return res.json(); + }) + .then(json => { if (!cancelled) setFetchedData(json); }) + .catch(err => { + if (!cancelled) { + setError(err.message); + onError?.(err); + } + }); + + return () => { cancelled = true; }; + }, [src, data]); + + const resolvedData = data || fetchedData; + + // Render SVG when data is available + useEffect(() => { + if (!containerRef.current || !resolvedData) return; + + const graph = parse(resolvedData); + const svg = renderToElement(graph, { theme, fitView, padding }); + + containerRef.current.innerHTML = ''; + containerRef.current.appendChild(svg); + + let cleanup: (() => void) | undefined; + if (interactive) { + cleanup = attachPanZoom(svg).destroy; + } + + const handleClick = (e: Event) => { + const target = e.target as Element; + + if (onNodeClick) { + const nodeEl = target.closest('.xg-node'); + if (nodeEl) { + const nodeId = nodeEl.getAttribute('data-node-id'); + const node = graph.nodes.find(n => n.id === nodeId); + if (node) onNodeClick(node); + } + } + + if (onEdgeClick) { + const edgeEl = target.closest('.xg-edge-group'); + if (edgeEl) { + const edgeId = edgeEl.getAttribute('data-edge-id'); + const edge = graph.edges.find(e => e.id === edgeId); + if (edge) onEdgeClick(edge); + } + } + }; + + svg.addEventListener('click', handleClick); + + return () => { + cleanup?.(); + svg.removeEventListener('click', handleClick); + }; + }, [resolvedData, theme, interactive, fitView, padding]); + + return ( +
+ {error &&
{error}
} + {!resolvedData && !error && src &&
Loading...
} +
+ ); +} diff --git a/xircuits-graph-viewer/packages/react/src/XircuitsGraphStatic.tsx b/xircuits-graph-viewer/packages/react/src/XircuitsGraphStatic.tsx new file mode 100644 index 00000000..bac816d3 --- /dev/null +++ b/xircuits-graph-viewer/packages/react/src/XircuitsGraphStatic.tsx @@ -0,0 +1,76 @@ +import React, { useEffect, useState } from 'react'; +import { parse, renderToString } from 'xircuits-graph-core'; + +export interface XircuitsGraphStaticProps { + /** URL or path to a .xircuits file. Fetched at mount time. */ + src?: string; + /** Pre-loaded .xircuits JSON data. Takes precedence over src. */ + data?: object; + theme?: 'dark' | 'light'; + fitView?: boolean; + width?: number | string; + height?: number | string; + padding?: number; + className?: string; + style?: React.CSSProperties; + onError?: (error: Error) => void; +} + +export function XircuitsGraphStatic({ + src, + data, + theme = 'dark', + fitView = true, + width = '100%', + height = 'auto', + padding, + className, + style, + onError, +}: XircuitsGraphStaticProps) { + const [fetchedData, setFetchedData] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + if (data || !src) return; + let cancelled = false; + + fetch(src) + .then(res => { + if (!res.ok) throw new Error(`Failed to load ${src}: ${res.status}`); + return res.json(); + }) + .then(json => { if (!cancelled) setFetchedData(json); }) + .catch(err => { + if (!cancelled) { + setError(err.message); + onError?.(err); + } + }); + + return () => { cancelled = true; }; + }, [src, data]); + + const resolvedData = data || fetchedData; + + let svgString = ''; + if (resolvedData) { + const graph = parse(resolvedData); + svgString = renderToString(graph, { theme, fitView, padding }); + } + + return ( +
+ {error &&
{error}
} + {!resolvedData && !error && src &&
Loading...
} + {svgString &&
} +
+ ); +} diff --git a/xircuits-graph-viewer/packages/react/src/index.ts b/xircuits-graph-viewer/packages/react/src/index.ts new file mode 100644 index 00000000..20db7b40 --- /dev/null +++ b/xircuits-graph-viewer/packages/react/src/index.ts @@ -0,0 +1,4 @@ +export { XircuitsGraph } from './XircuitsGraph.js'; +export type { XircuitsGraphProps } from './XircuitsGraph.js'; +export { XircuitsGraphStatic } from './XircuitsGraphStatic.js'; +export type { XircuitsGraphStaticProps } from './XircuitsGraphStatic.js'; diff --git a/xircuits-graph-viewer/packages/react/tsconfig.json b/xircuits-graph-viewer/packages/react/tsconfig.json new file mode 100644 index 00000000..e658ec45 --- /dev/null +++ b/xircuits-graph-viewer/packages/react/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "jsx": "react-jsx" + }, + "include": ["src"] +} diff --git a/xircuits-graph-viewer/pnpm-workspace.yaml b/xircuits-graph-viewer/pnpm-workspace.yaml new file mode 100644 index 00000000..0a88384b --- /dev/null +++ b/xircuits-graph-viewer/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - 'packages/*' + - 'demo' diff --git a/xircuits-graph-viewer/tsconfig.base.json b/xircuits-graph-viewer/tsconfig.base.json new file mode 100644 index 00000000..3d92ad0a --- /dev/null +++ b/xircuits-graph-viewer/tsconfig.base.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "isolatedModules": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"] + } +} diff --git a/xircuits-graph-viewer/upload-demo/index.html b/xircuits-graph-viewer/upload-demo/index.html new file mode 100644 index 00000000..8ad066f1 --- /dev/null +++ b/xircuits-graph-viewer/upload-demo/index.html @@ -0,0 +1,93 @@ + + + + + + Xircuits Graph Viewer + + + +
+

Xircuits Graph Viewer

+ + + +
+ + + +
+ +
+
+
+
+

Drop a .xircuits file here

+

or click "Open .xircuits" above

+
+
+
+ + + diff --git a/xircuits-graph-viewer/upload-demo/main.js b/xircuits-graph-viewer/upload-demo/main.js new file mode 100644 index 00000000..d1815a4b --- /dev/null +++ b/xircuits-graph-viewer/upload-demo/main.js @@ -0,0 +1,113 @@ +import { parse, renderToElement, getCanvasStyle } from 'xircuits-graph-core'; +import { attachPanZoom } from 'xircuits-graph-core/interaction'; + +let currentTheme = 'dark'; +let currentJson = null; +let cleanupPanZoom = null; + +const viewer = document.getElementById('viewer'); +const fileInput = document.getElementById('file-input'); +const filenameEl = document.getElementById('filename'); +const themeToggle = document.getElementById('theme-toggle'); +const dropZone = document.getElementById('drop-zone'); +const zoomInBtn = document.getElementById('zoom-in'); +const zoomOutBtn = document.getElementById('zoom-out'); +const fitBtn = document.getElementById('fit'); +const controls = document.getElementById('controls'); + +// Store the current SVG element and viewBox for zoom/fit +let currentSvg = null; +let originalViewBox = null; + +function renderGraph(json, name) { + currentJson = json; + + let graph; + try { + graph = parse(json); + } catch (e) { + viewer.innerHTML = `

Error: ${e.message}

`; + return; + } + + if (cleanupPanZoom) { + cleanupPanZoom(); + cleanupPanZoom = null; + } + + const svg = renderToElement(graph, { + theme: currentTheme, + fitView: true, + padding: 50, + }); + + // Apply container background (dot grid) + viewer.style.cssText = getCanvasStyle(currentTheme); + viewer.innerHTML = ''; + viewer.appendChild(svg); + + // Make SVG fill the container + svg.style.width = '100%'; + svg.style.height = '100%'; + + currentSvg = svg; + originalViewBox = svg.getAttribute('viewBox'); + + cleanupPanZoom = attachPanZoom(svg).destroy; + controls.style.display = 'flex'; + + if (name) filenameEl.textContent = name; +} + +function zoomBy(factor) { + if (!currentSvg) return; + const vb = currentSvg.getAttribute('viewBox').split(/\s+/).map(Number); + const cx = vb[0] + vb[2] / 2; + const cy = vb[1] + vb[3] / 2; + const newW = vb[2] * factor; + const newH = vb[3] * factor; + currentSvg.setAttribute('viewBox', + `${cx - newW / 2} ${cy - newH / 2} ${newW} ${newH}`); +} + +function fitView() { + if (!currentSvg || !originalViewBox) return; + currentSvg.setAttribute('viewBox', originalViewBox); +} + +function handleFile(file) { + if (!file) return; + const reader = new FileReader(); + reader.onload = (e) => { + try { + const json = JSON.parse(e.target.result); + renderGraph(json, file.name); + } catch { + viewer.innerHTML = '

Invalid JSON file

'; + } + }; + reader.readAsText(file); +} + +// File input +fileInput.addEventListener('change', (e) => handleFile(e.target.files[0])); + +// Drag and drop +dropZone?.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.classList.add('dragover'); }); +dropZone?.addEventListener('dragleave', () => dropZone.classList.remove('dragover')); +dropZone?.addEventListener('drop', (e) => { e.preventDefault(); dropZone.classList.remove('dragover'); handleFile(e.dataTransfer.files[0]); }); +dropZone?.addEventListener('click', () => fileInput.click()); + +viewer.addEventListener('dragover', (e) => e.preventDefault()); +viewer.addEventListener('drop', (e) => { e.preventDefault(); handleFile(e.dataTransfer.files[0]); }); + +// Controls +zoomInBtn.addEventListener('click', () => zoomBy(0.8)); +zoomOutBtn.addEventListener('click', () => zoomBy(1.25)); +fitBtn.addEventListener('click', fitView); + +themeToggle.addEventListener('click', () => { + currentTheme = currentTheme === 'dark' ? 'light' : 'dark'; + themeToggle.textContent = currentTheme === 'dark' ? 'Light' : 'Dark'; + if (currentJson) renderGraph(currentJson); +}); diff --git a/xircuits-graph-viewer/upload-demo/package.json b/xircuits-graph-viewer/upload-demo/package.json new file mode 100644 index 00000000..a7cce80e --- /dev/null +++ b/xircuits-graph-viewer/upload-demo/package.json @@ -0,0 +1,15 @@ +{ + "name": "xircuits-graph-demo", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build" + }, + "dependencies": { + "xircuits-graph-core": "file:../packages/core" + }, + "devDependencies": { + "vite": "^6.3.1" + } +} diff --git a/xircuits-graph-viewer/vitest.config.ts b/xircuits-graph-viewer/vitest.config.ts new file mode 100644 index 00000000..168aefc2 --- /dev/null +++ b/xircuits-graph-viewer/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['__tests__/**/*.test.ts'], + }, +}); diff --git a/xircuits-graph-viewer/xircuits-hello.png b/xircuits-graph-viewer/xircuits-hello.png new file mode 100644 index 0000000000000000000000000000000000000000..2f4461dcd534a1f26f22d37afe938c8755d762f2 GIT binary patch literal 243301 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

)VMrUwnE zV=Q?m#n)#Z(m~ZSBMF=4yC~j?`>#~5tZkrn-dS7l%tr2aD{{xH6yQ{WhW3iwrIdHQ zdy`@J`JUBpeNuZ0NC7hx#P@s)bq-EZutP9G+OR^AfBGP&T0?EuJ9o2}9)y;T;`dfZ zM>}~QtH9PtY8`)njkl6C!r4845Lgd0Lxi3$<3{7()q%NHd&WK$ue*2-KQI27eKGlhU7>I+vQ-vMUfhk(Fgp$h2L&kt*1sJ4T`8EvG!Wb~p94^x+&^gV8bL0s73!wCXboDR0MXA|u3 zN3duKN;zSa%8AB&PgnNm`fcutnDQ5@t-)y8awaw>VAo?{REg5oM4YAyuWHDHi*Q9fdSA3o;a~+Bei?%K_Bh%Jhwg9 zj{%t2uJq;&*p3D6g;(P z_Ca{_^E$Uzkivs2NL0VdBE&tGd2zDkw?OWc7B=d$|kS8;5azeFI zWwHSMcnQjbp2~fL4!XC?*8}I`*Nv)k*UT&&GXW`2QL#BU>Cf645J(NM zD}Fn^2L7TS2neF}#a32V*;u+Gb+F&2gw4+CnW_Tu_O{1Lz2hlaM>9*%6Nd3My|Z8+ zQS=4yaLP*D7(xDUN_%Fnu#=XLi!#e@AAI!0OyKB!zW26AJLdQA zvhB7;U7H5q3o1Kn`b=})_iWRehB-Qm5}iD&k}WW!1_#CgSF6GfL3;WGDHA1`sj823 z==b48N=icRx}4~Fw3_=4+)xelADo;@CXd4ONPI|Iy$Y4?vy$Bdm(bhrXsWiG7#Z~) z*ckgN=L!gSA_pK{vnNPTBxF~gr-vl*A=5b>w8y+|BwMY5UPSp(*7spB#a9qbj+}R{ zuE&S-Gq)~@>m9TtN~L{butYUR0>E3>s&{?v*a-3ng2dE07r;W`V7htjBVR=em>tHZ zAm-;M?9}Y^35?LcdOmu9Z{ObTCt30u%SSw?JB9St>NFZ4vKDgVIpvCirTxXg!vU7VAy`I>h1l`-lby{G^!2U3m8Wl$G|Y=ivGo2 zCh~izTKb%+xHz>+TL^TK17D}P&o!ccl`v}ObBE%Omr_Lcd}~jqYFY#Qx51&q_#oSf z94*k z28w3~MXl7LO`Q9>*s{+B^?bm60$vl|Ii=ck3IonPf=s@(wWq?ufy+=?^vn)wrl*s@ zf!wBaQ5cA17XNJsb1puP)YQ>Ax8#PKC*F(@r}KHzASS@-;pEhv6?>!C0X@AxkJz25-Ej zc7gE^Z)noD5lw+hO%Y_)+S0f8I@wr@gkmHO7sOnpm% zGt=`FRgCYcm;r$CFw(Mda5g0gHccRRGiaB9nq`~vbEEF)aG@&{iiw2mLReT>+}1`EnJJ-Y ztrU15UINcVn_h37^!;hs7LhvvSQLeiQ*UtRwOOKd7nxY@$RS;pbpFGiZxe}OU(;u| zy-)QKZlT!dpVf|uk3XKdjyu(QLoAFBzFRtJnEXc?DUue})gkBYop2_!_V(iOK{e*l zhB9g_fREaD*Yha)Z?`M_zI{K(U)7syDE|CqGQ5`Z@!Zhx{)_q^?;c!620X#r=nP)o zNjKaZ=!sH+C!}<#;&&BH7vexy#G6uEgmVnfnYiJigb%g}p{ZsZgsUqnafrLO(BH>6 z$UBsO`8Fq@Hx{1`A}R&dL$XG%K)rsnaJjd*u))37t8N%Psr z$VjYc)$WXgHf{s-PWzeI%;F^?S2heG;f?7_4fSVCwTxd_QDAJK@ofz?U)Ak}G1-BbdwW_RvL zlE=^oxPN~88Eiul5fBgHC9a_t$!j7y9{q{#%``DKg6#Nt8^O(0ZVE6n0aiF{RCx7I z;QXc`0)gmTG?vnqphSI)EID>owQmqztUfuZ15clq2QrJUot|cb`L-Z6V6r++PD%e0 z2BN1VJSB-&DO65^eR7JYEnBv*G`sTFc|*_mrAiOR0!HHQ~)KI#dVZ7Clg4fDh0l;be!T#db4$^2NtR935HX zRAQzke}&_OTeVb&ls@#rWr>{1<98vcLtGW?td(Pvj zXYo0r0GA2H4eSoU4H(%as-Jkwu{yv#URYfRe7>UZdRFMmU@)pGpVIqEy6L$^xT}no zkKJUq1kiEr_s0lbziL(GXrtN86D>CXgE1ZtE+_uM=ZoVd3X5S0t>9 zo9mx6G&IP*7wS8-#YdYQ;M+-hNO$ImSnYCbe{|Ee2@-%GN%?k-Dj@lZPH8^H#d^#XnOj~-WEeO^8fuYHv9W0^=m~*p!crhJ}`Z;ThWZR>Ny#i*% z;_ulX{)9oq6f4>;qF4OamwCnJgHHJOU%#%U4g3J2Q0^fR@vL3P!F>B#@8dJ(TW?a8 z*ouj7uv{YW7+!qRyZzJ+7Rk_xmiu>d^#7S~`la^G7_J?n@#Z3)zmIqI#w#WI4P}7v z&K zVrdqkM`(AC|LSU%w>zs-PCmIs8!5?X)xV?%p=t9jol-+q7B?Z;0K0DFrIc8g!gP8} zyZq^HSLj%RisBPfTlnA4p+iD&!8^w7pz_myB}<$1<_P#BB%~;>nI{31!s)RQvbR4;Mc!<$JaD^W0-y6{J5?Az1V}*^Va0f)(-)Z8(B$DfUBCJ z@V$B)r;$TKH*X$UxN1hYj}DLB9I`5rX(k*sWWM_@LX+~lIk<5T{n?dp_-MPT>j_-j z4>monw{EFyW{rgG3u);1a?^I46NNUZxvwtG?4_+uzhj=XsYjxI{O4_s_vh=MQ=gg@ zR0H7;+>p7;Zk@$2yhE3TkZ>V4ocrcSKO*8?!t%lGS<{A?65~WEWXH+7*Z(z`-WOth z)zaaHbQ-#E``L{7q7H4WWF=!F&g?DZ{{#=jKhcrX{1ss(-mr2dzEOn)Upk_|@&A$I z;EC{bG_iHi3^j#DW@KjOB&~vXuA})YcZ6R&qTY<8GYxF3&rg=RDww)F8iA5Y=hdYe z=znISs#Fn5{zCY{J-4E10T?g;B z3hMTM67zpHP0->23@7%C4nYV+2W@?GRg@yQdw(UaN7*aKsm0}d62QCt2{NEgpZtY# zIUoIP3|$Y?-mir(Z91y|2LApisPulOIACC%pDKX)c)kFA=KnPewW6Q+;Os3eflAoE zn7+p-6hXe|a^gC{tduwUd=uWfu~$d5?{YDy>U~8l=I%dY1#6z!Y<3b7=iKL7d!NR9 zZHLlR&_eYCn%@@(W2PX31HQbtoN1DtnKsV3cjvcb6p;loYuCn6y)Y9FRQ*-T4Dy6@IX zI&-Wks36-mf{x#dg$VA2m4|#bRBMei0KyKLe~lZa_@H5OSXfeARJN-`mH%Z5fiYwC zlOCsFu@*2%p9~tX#C;q1?~4FYsqMF_eko9?sl9Px|krQez=4tDuBX}YF zOm4^7DsVKFLx#z>`gU_@8+BRk-}*z!-Ya+ELVvy?guM0W^-j*Z*G#ycq5tk6IWIzC z$WKgwQV?x`yr2}v7cWG&5$zFEhYb;0bklJFj4Z?Qh<$j73fPyJ}*8M!+El(6}vJHtZ@2Iyp_$_a3K(QDv#K6~xl~NviBESp@qBd*|K!#t%opSk{*s7^? zs6k%y5}7Z|Y}wIhQT;)nt9IZq|HWjOct9#MJS(+XJ=Fc@$1|GoXGR7!7rqLh7&grP z1@M?iq7|K+|Ixq!43u7+2W*%wQx3RJZADdVs5*;qN?ny96}kH}3447I>82j~Z-eAv zEJCXLFrL)Gz#W8L3zNN90?rFT9{5+hV$7?odwWx!rv^%N-Nu;F5GkSUQC(u<-R%b` zp?qWq>|dLvN`GZp;l}@MS)Chxwa~h`#p=Zl4&o30n$>7pSuyn=AxD7D{Kisja<;dV zL5qm+aD3Dkrdyv1Sm_&_AB$J~HyjIQRAj8WTcACFr3!{Ri&>V(a#e~;@rAL< zspqEv_|r1Z(f`=j!wS|e3QzqJm5Y~YgY~09#xfl!_O~B#6ViQ;@JvujnY=cpGR^{|MsjR*27@qbUs=WRMvcemuQf|iyF=N4n3Z_=F_ zf9CWtRd9#y#>P79@DT^V`7WZ((y5;2;-0w_b`_@-xS?u|L)Uzd3|I8x5)ZEUPqstlEw zb{>cVi7!KgEsHXYq4T&qbD_r<38xd|r3Ke*d}v+L*WN8F!080SXbF3J`yq6oK2^u? z2m1MFT=#O8_RS~~maWQnzeB1kB01$e7{}$$F zS7op8i`B-M{D{;-{QpGTP703}ibnZ{+>^7}8h?dr;KEahF5t6G-YXaKh7FK= zXJ@CUr^k$LcP$Tr*d4QR*PBq|J?JDA3{|*zATQ{z$b6)b%h+n2$ z#7Rn516|_+BKfUV%Rqv*t-&j)8VXHr7`zgD6O7gD_(We>j}4-!QppktA4TSmD#mXn8=@mG{8d zlwVawS@dBsd_MIbyj-9ASL-9oaG~{HSy{=+a%(7<(9Z9Tc8bWBEjP3QRor}yn(4U^ zEBebv<1^`0h8lB3qU6>NL$gy6dqW1G359fxvP0NKYm};l^xlKZnST&>rbo%|C$58r zgvYKZ{g^3_i29}GLxyYype)Zx*O@X*{wt-locA9CI!vO!@S}t;;!Ft(TF>5&NIpd& zE&2+dE)f~rahaFL!fe&P_1I33O%)hCvmpX`lXv|nUW(0l#y87Y9@ zYN59;<}s7h2K?r#iI13ZYVBg&r2Q7YoWytfr6`7MwkD7Xxf{|Eu$HXONJkrKV%!Ce z2y3Hy`?9$E-+B7-%WpqAJXX?hv!ma00)!;yFK~c?@0`&ogDt^4z+^#_6rZLvxh{MT zI6+h-&6eYTG~kyoMbcD}oy7xQmVoe={RuDcD-=;`>(}qs=U)$Xhg!Vuo{c51Oh>l} z0M@PK%F;HB{(5N&z?%aE@1^|sa-@bPy^M~tSy2kfckdpO`WHkF4HuZlGc&xH&C=X; z4iphLl~XmaYHdGC>CWp8LJO(Y)JRL1+N6RC53WlO60>bh{BI0G-BUq8v6{2gl}kL?Mt0S}c?e@J(hPp?y5x{SX}`u`o+618~ZDw`p7 zpm~~{tY`iGUza07#@0DD4Jma5RqD%k8V;DNLzkrnx_o_oJId`*m4y2Mpo#d0BwU=}x=prrJ5GK6M(5YlA zz6Vq=q=T$kNbX?oD2dNz=5z?odS81wb`d!I6nL}dOz(k5ot2(VbT@(WHc?FQqpwoH z!_zjzfqrm5-(0oIp(z)l*8ze zT>%3_>?PV`50ESiHhmFMOgVed7yd*zS1wsL8Q7p&+^aM86_hEkm$LqiK?)0*3GbLT z6q=2T?ESusYktr@epk);br*G@6elZvrhC*`oU9+(YZ&}X03F8azJ7a|Rfeko?;U<* zT4JJR;3!=I^1knd9TWufmk(Jl+J|$bmVEY-vp@IFO$z%j>?NEg?J`9G&C*SIb2$PL zPDVoN_s5Wij)pELPRGU|0Q%1Y$iG9(CLN~pd;f*g2Zf7e#h?jfFloQEt#Y&rzd5%3 zC8!3UPMG(64OIp~jcV0ZU__JQ^2=KG zkP~Fc4TAYgJsAkf^|nP{<$PvG9=D(q{WuL=enI_b8U7{igmJgn7r@PMQ&bKO7v2%$ zdl!vUN%9&UbTLoH%F4>jZ2iDQjp)X?n>C5*PfSeEFSIc%4DXx94Y1w`jk;p*-m#ag z0K9%zfCxj3O44FD5%nhvRFS!w%gB%rHKXI0G@7mwNgQfX%FT}0J^;>a5?vaUS8V9x zOq;RF2gkj4uh%L9P}U=d#OSoA44DHyhK1?w)zXr;KAQaS^~5Jb4|Z;>qa%Zc$&0~0 zn3Myc_K}M>9YJz@JQu>?A1}UOz1XVj0zR?+rke`a>(w5?$PUL92K>WLgx}%{gdMe5 zw-E^`tr~@ssyRf`cd;3BUI!@ymi@)6{CSPVksfvJ0z25KA*$5{a7la&c6w&!lHE76 zlo^>Z!%+Y2*9uPwYuqw+cl!hc1Uv}AX_}$nU}LjWsM=gPJRILIIHJJDpt(7mBG*g5 zl{HBwYjmwEIXZYHofkytcuRTLzz^bHRs_Xf`p2)&Zy7=k0Q4~g;nxu>_C^l$zt^#b zC2@Wi#0}7>^l3OONrS1-`LpM)wi}6LSQ4(;MJQ)j(&T$&SQg|7|HcCD7`y%kD!m z2SK^1R!MS_a@!*i5<80%iw*?2eClA+I zsa;j%vpaFgoh3F_EjC6(8 zwhN?%4S& zfG4ou+NeIjw~Vqgi{If{f<4Shm}Klqo#wtR`1mqaI?z{z7{ljfx{oC;Y@1c+Dr2D? zJv51X3br7qRMND&0xppKeQj7^-Zb2Qn}8F(=H|pp?pVt#gb3!G?OAt#aZa`rXszL& zgrTfJe?cJiG+~+9+y`M;A$G`(Lhb$F^QwijlF7-sBML%r9=0om6&`)PD|iwNd_u^% z1qo?yLx1%CkuTxBh}HJMGHXAdd1gTD7NxB2W5CsR-yar=i_vx!ckxmXMsLcmOu%W zzaZ1rpdX|=Y3J29yr5CXpO*8OJrYLjrH-Bqtu1-l@qm725{(`~(KH-OcguS^Nq=@rpp1kR~_TK{YV5N-{kH#!F-c|SoETvslG(t z2QK#pQQ%^}G7ZA_fSrhJtMsw%Ik3T)kv1R^QBpty*fl%73m%6BhhNwaCi$}6xwAA= zB%7al3Nc3-Y4U@(tK(lgbm!6zF(U&(gk_@2xeQ#BxNP{fk6uZmb7lAM545+7?S(RR zU6zc)Z$5NjNLba8#HdnX#c3fYC95rr?wrReqUME@7YdV5H=s1`D z_-jz4JsZC@Xnm_70Pdp!PLPQMZm!L$%fjOA?VYnA1xig)bTCbf`bP(u0|Whs1_tqA zdKZD}D8g`|EIgFQ?Aid)+=Pw!SIDVn1iwU1tLv47 zgNgqtWIcH&%f{V|=xBfyp5NnuGp2R)bOGxoclUQ;0sOiooiU=-{|$H{PpkSkFx~?Y zK3U9|gp7;%fn~3(v>=|hebDDn!MMdE&Ze(97NMj&zjOJTBkY%aGwcqiA>~sfyybvLNc$Nx9aL-ZHqs`Jzx!V zP|1t-Bp4XqLq}%AYgT(5-3uhz8L|P|-g<9IANSc}6>TgU!U+eJfAloIYDVrp6&7{_ zl|T8X$%TxLjhY;A(b&T`!;(v&1#MxaPM^6Ph@sG**xSS2{VQ5JMWf6)Y;SR2JYN}d~f?IrJT{{`so3x2V06D`uT5NA*SL&ytyUs<>VyHB-RObKp>)$*acAc zdN!~1Zx+<%iUJu<`fgsNbDhu3SIxdH5|y@CEUAj`xd>479aStv^b{0;n(_&6&IC9mN#*_4_=`kZl(g@|4Fg_<508j+-pNRxT@zYFImH3@BgIGv%wDY zTggC#u%EwSq}D1t4A$*S|0R~YD^lAb$Z0f?N~Kf+9i)R&)zs6Wge1Lh=Fnch{#oJf zE6#gf6JZ9Y(`#Evyfp^FLsq4+ywQHDy%yzs=3MJ8yWJDeq~}J!T4L)U>y~O}V?9E`?MGQ6rUot@n=s3*Z(6G2@1YAU_;P@4VS( zS#lnFQs?!{P446LQJ>qnjj#*9$8WB^cFHe1 z#BxA{y92WJCl^kbpII-F!|dWwm^t45Pho*%R_!+9?X^(~IcAwjbWx(KB(JnX(1RqN z`0o9%>>?J>BJ>!ZG~Hn1%;A9{)XY*=6-$Ymi+LYGhtB9`)9*qww|~W3FFp+w9&IQ$ z*Wq1U{eyp9D+w7fu{N@0K|uXFu+(vJGyr(l>hFJF;L5xU54v=-v(6oV`&faeE2>JCUgMc6O3%rN;P!{$autZTYW4GO8iT`{Ht~Ue;1uQT1LB!;y^K$ zLI=sIl&Dd~pxNL?%k|Ah+m)`stk6^64Rn@d5J)^7H&9mE84Bsc#7wo0|KWrIYKT5Q zn6N#MOnxphc=+7ljn@i`9~DH+yM=_pp<6keqWq1q%SQn!A)9t$K)^SYZ@FPo|It6I zYNs=vlXIBSQW?8XBDHUA`_eHYt^e%R~=Y$ ztmK4EkJ)K2sEquE$<7x|bm#rqt1q&dAFRQ(Y@k>&ct3tsR%< z;%XRrZ4_1h&@5MFJkMD9ugm0yR4_`q`Z{a!C&t_#*||zSfQmnFTPw}|h|gX7mWZYA zkf^yc)eh%y{>!H?!C(fJYR~Hy?7?816#N-q?AMuLr^boGtq z`!7_y0NQudUgCDt*|JS(8;y_A+A{iPVa#+Buxw# zsDjL)`r!WplG(cg>gdDl)m|Ng&dqk|?0DSvK`mf?eX>IkFG&T#$p2Kl_$KO$O(&KW zrAhGw)zI9#BzDW`?=K&hZK*GgJvgW#UpqjOdt{8Wc|e?^*)MwjR2yrp6$DQpc$j}^ zH}3RW(tlGLX=ii}oH8w*$gfZcPwQpnVuzSiyfn*m#73QrkM;!?7jmm?xRiGCB10}( zC4uiLJ38bi27Yla?Wt}xW;9Ah*x0R?lJrFJp+zDgxKWj3X{v0w*qjej617{iWJ0P}#5A|2eN`;QB$NOsPc2z4MER zVVq*yC%eh*c&09Nx%br$%fJ0mhf;YN>IY(t*&gJ89zu73QmaP!WlzQJ9##?@Nj<$u zk{e14ta=dw$6PZNq(^LPV;h{p)>)6iC3KZ_9x@*qwei3BU#o>5bjZYZ)y2rOEtc9bc7dl#uG2KJ3^I0#Sc*gaB51?|GiQ4=?*sKj|DKCBxm41unh^jfZkUSKgW zylC)sDpXFt9W9EQ)^jVyHHyM`<0E8lZ=xwvU(2qL4L*s|Mvz+9e}AkKRcAYI{FHF8 zd@v4KCAt|zg7||#Ft>*26}%wxf|9=@=bIX}8Hp!LkjDg1S-I|(`<904j%(lgq{sWb zXv+#d%be7D&^_h%$O9TGeD}@mOxKi+G4YHM%D)al+uMwR`Xj9(BZoH%!rn}>|7-s9BR!f|AEF@D(yn0FrODY^9n zr!{qIx>nz~uylW8o9IQ=)SrsXtae5t#cJF2mL_#_PKmg#eHAXWwZXJh)AFsQgaT?` z{_F?UtFh!{==?oy7PHmBZ}~Cs1EKn7Px?kiab=X-bg|13ErV+&Ml|>n3yOqeM9u65 z_QN^IJ(G%fcx6p`EH@b?p17Pre2G4IO#rQB7}nYdp3;g-ggtzQ0;gVGlj|2EhR!Wx z`JzBAe$D+N+GGg@j)$6^ni(Rq-@N~jTSRnAGQxc!JrqsXOe47C4S>G=d;jRt2{m#n zpDO39o8@JvdW|d z&c>IQd1f%raAYoSvjq>*bF+$j|dTN|&G?x|^t>S52Zf`_t^4od9EfhetAc+V+EjAttI6105Fp=~k6*{a!UQ1nejU*U3CqJz z;2OG0XKIKI($c!Y-R+>JbJ18KZUb&9Dnn6FER+;6+4DRJ1J8eYgez2j%sAfx%aK1z zGQqk`ag*n70JZ$DgEEF$7oxvqiJ^oWM>#$FA@b3FPusLB=YMWq7nNynnmys;duC^4 z&@$L8wP}!vKhvrF@);v&e-jdAG-;WKRtI2&3!fOlw^gj{HvS|5cnWjtAToz^AeQ8(sY{NtdxWzCc^E(n;>@>?(@GbcWIJpkB!B z4XjGa;>0msrGP$T=*B(pkCGVB7LBYc=luOgW@xRam%5yYO8+@03Xugm|hQG5Q})yvO^ z!j)<_5W$8cx9)Zri>^tA-@T$5^wOHCv9xi*LHqMt-1`r@Owt;)NR>T21P%O-^qG8{ zrl#t5t6FBJ7o0Y9Y8`bFzW#CP7^-uapGI!Op1elHfp(Bw&^D7W6N5X*{8}z6&n!mq z%vj<+u1$V6E)>L8xps(EuE=_-dShlIa+tPo?c{Jo-=!2TZ@dIwxyVH@!sC@068-re z8ydE<9F8gcD&3c8O!B){kp(L9tz;L>02L$qBapM!XN(eRTL9HCm7}0sp;}NRrhzWoJ0guEb2i=cy6= zx3Qq&EnkA>e1gP|!yWl>&Gd^kw`bh+`|3k+=5x3YiB_O9Ccc-I5h$Y=^5~X6ntCCo z{r}`_iMN-KKMeVHgW)-Y9PQ_Dnp?l-^aah}ge^OB_(>lWg4IZ|y2wgPO2Hvx5R_ZsAacJEiz)2J$NTqru7x>QBaLot02^lTkc+JZ;g z&5mkgzIn^lb58|v-1-?;mBQ^OQr~`b?C-S=bv-JHwOSiDRLz!T(9rf|>uHw2z`pBw z+;hi8xb>;8=W6WXt&hkJgEcqTgXWi@XWN81tp4{-u(jJfm}ID6{YoUgn9x6?n_EH^ zN$ei_C;n1d=P{oy6lQ-XeIphSRv^{m;cbe~N7B-=&Po>YIlL0k8UNbCC9g`=1u`*} z2P=!)kW}JMww`q{f~(S@^=FaGzTd-!|IN1G&o3J6)}6zKf7mA+Q7P2c(d=GRXMZas zxn~;5@Ng3J$sDzqlggoeE#BEFJ<5(_JjmI1ocZ=}^Bytb(q$4E^jF|v=1N&5T?cFm z3=PCsx%ZB#u=M4+Vh095k+T_AgwWRFFJAhw4`^wWzRs7w->3Y)VNk;Dp@A+mp{kAY zT-{9FY>xmS%CPe>f{DeiRe*&-QKnvGv{0fBVUF zfBy`C=p)-is5Rs@Um~bMVL*(igh{8t&h|v~TgDA92GbF-g|TtyR^|E0hr5bb!Ufsh+`iuOs{g$IE zQvza;|J30yID6hghN(6yAx3Ygb0lZhWPIV>#mP2k_Kn!fEA&m%-`bKsPF`M~h?rTP z7G0P=KGu(svZY6<$-RH3_blywSh!cPSP{QoUPvJ()zQ_ZM0@IS zK6&?|NQZ%8oVa?(1fZU*fK}>R4cr&lL{p-miinmc{B*mj^DTWbjsu<59OUo{C6EXE z;J%gS7YP%ajz)&wH*e;=LA`%phQ`Rq&~--iCzg0TABcgzG`X0_w84rzjW|hhIOHml zz0k~}Zsvatm29t9WF#TG&sgF2l63&^8WRvVn-rq!lAwz1o9=gvl`24gSsL8EA#$V$f zJ=b3-dNu+p3BbX8gKqUhbN33%yw^b!AqjXAadB}uSp`}!ygT0b^)@dy4Iv)aS`~i) zIoZa>!$-js-OUrM#U}2G^RKRiA+H8yDZgg~oUO}vWUG^O_EHv|>CHub7Xu6AM0S+` znsd;nnvi6cl?g@R1b->esl}_6w2u4sL8X%u^#t7JVQLxTig9zr;N0+p744UG@>y?wGS#6YAD8c8)9VvOmOVD7uI?3&PBsx$3`EBt3MRrs8 zM2Ctbd@C+)tE?eR^c}KE%i0#&LMy)a&m|2*yI(I+o)aN*PHXVr#ywBmr3L`TR@x!Y)=@c(16_fj z!G0EgOh*>q(p-3|4bQiT2us7@oU9xBH*b_xjg`p)_bE=XxwbY$3g$Efy8;#Q8oGXQ zBvOnl9Qjh9bt2(FCz3Gk2eu`#m99jS&n)b*bzXI3e#K=Lz`%!`|APlE;NW-jbUBW?=ktUL(1(}@-!n&qSOIJ0MS7JV7$-`y6|dwmRHP;Pxk6om zKLD4#Y?>$c{DX%FI!m(`kKX?xDhh={_w)YAGQ2pu7(_(FI7b0zQA%%dTO`+?6gd0T zPj>`~t&XgY z+F^Yo)kEmtb89#BQZi7dnPkpvH*G~NHQ#QXhYe{XPp6bCXxi6=9-8{fi>-%?XMX#( zj!wV6*eKkR$cdnKD(DatNbKqCl^0k%SW6(e6r*8;C;fks)i!AgBm`vJU%WCNoaJY6`qPAPmCr)1 z@B2w!2z@&EyH-ydegPeZ*|!!QjsdI0hqU-AE-!X0l3uCmOGVx=%5 z!#ZPc4iSk(&c^cDt9jR6GKCV zjec22h5uFV-22a2R;iM7c|-#=9bfjw&i6#oi&-YC=M=)&L_DlR>+9M#jU~+jZ_|wx8x|uVPu<%6J?&}HovosuJ4gIsb z^d8vl1&j@a@T0!fc#K;%wZ`n2EO&c&7ELQ4XRXBrEvlzZ3KS^5WrLQM-M}u!r1hvecG7O-_gjhnKy;uy~ zz^OYUX)HoygFU$dwC-b_2btnzl9-V2eJ7Eoc2DQA7Bo%3|T{NaxVkP5&+`sVHQS zELz!4rW%n;N%gnD#a&2-6D;%k;tTuS7rD&O2uO2;1)c?t39$V+7>T!k#j$GO6T=&r zRY1}F_Q~ljAfO0X*!k9yEcX=vV)Ak6(DPPhx!Hc#4W%oO<|31d7}6OsmhGpGnPbG` zMXvt8r-W23R^?LdN8tkIiF%^1Q=12JK@dO;24uF#j8RBV9Ne;C zVhuTbxf`;Ypx;_|Cf|R2p7I2dYyN?s7%5Fm%1HS~U$0^lgVYc{+jvIkRGrn7bAqjR ze0CP;SKpBD`2R==0SDi5s+4KOK3^@;yu&MKu5jn||9XjZ5dA=Q#$#Euz8_D3m`fNC#8h{5LEj|xS zJ8nnw^C3z~A{d9?Q0wg|W@lhT8cl;5vF8UGxDt4V?Yb4MJUk%1uV&KjK@5YcNWYVVOK#RSw5C5mGvGR27U&A6nI@PLgV1R>% z=Y`A&&`%c^ztgxuCVFn8o5SHWgmV{`DfcZc0#dF!8G5&iUe|k_BOT{(2ct)ivJE0p}Q9?c~ac1?{t0?m3tpJMS_y^Ptb|Q-y z)Y1h*t*}$4t2t%n=Ko2?sL=u5(bD^+KESj2>RNemmB-BY*DtaU+T=-Bp3M7Ijl0xN zW!8A}(j%Shf8TTf_!}b(8W`Q|2bHnNl0s+V!VwlH&j&MC<@UWVQ4(+gh~ZdFSU{Gz zyUcxUE@XZ*E?QY4<@Md>RhayfJCIq6;vzZY-{Q5eu(Lj`!kODu*2TB)OT2KVRjsgz z7<8(Ta9ArsAf27oex#>fX{}u7xJIuDBx-PM1Nj{jYi=deErDni&E>agf5Iiqmq1|k zJKbGI&3U!xEM~ zuJmYC@v1?TTSETodURdl6S{r}AEueADZv&qk9+B(7M^8g_EXh?tEqfpEFQ7;qm$bbgni4=x*<_o^TKhffhUEoyR*lf6 z3hcog6MvhX!M_8EpC%VI1k131+D+oM?4Kbk1%6)5Uzpj z%P@tO*1K!fuZNR(>AI={L>-hGGz<{WqYmz5XZXU<00*viI{o`K0gY$DsFAWH`<#LT)(!1JbM?D^$F0-2EaV6j@SCr4n zTAv9!Rv7kpdYq18fRu`}qn~}egQlQ~1{X)zGVfmW-16j)7tRkyX6jlTP}=M9+$E~| zB`6fzo$a9`$=vyJb|KnXo2B=)nZ?OKIjer4Vet^g7u&Nj-2`zu_UuPu3#!~%sfkb6LzpaFvCNlQ^deku%-p??u3SmY zPb&9oaDi4SffgCc?-w9$IxE#mo7Gz=V0O`(5LVEHo(`qG%`gD4ovfGw^5DFItc`@h zmXlO$KCHvY(HC35Cq!|z8GxbJ*gzvS;$n>JX3`)Z5j zAbYye^ad$H?tFb(257<@@0JzZiyrynKx1qG~f%a*dXJkq(u^eSHtI-+cSFwdM9w-rM@|ayNjZI%B=ui&uRj4mp=u z5Z$D6ay>kO`_grE=o$9ufDV9UIzm#?>G?$8kS z!!$)~Zsn8>m!H-9Q5!Z2G~I2H#?#pK8y)|Z)Sx*q=K27@bN%1L8t(CpOgu_+rn(p1 z19iZ)31!CeVa=1*m)k7)!a^~n7**j~p?-jb9{bD1-rYO=2?$hJ-0V&m$s%@*`%e__ z8K-lLBGD3{;Ruqf7BwZo{j6*H&lA@JngWGxUmA~b9MpBC5Twuz<1wCcQnbWknQOKCQ1Hr~$Y4 zgaCikBO(8WN0e>)GR&RM1#;clj+V?9`4IX)gArPXKOvgkah$iw-3j2s$-#%!E{0%) zH;!J(#|2tn&)fs|n8|S^k`E%?;{H=>J>VmWF(Z*>vAIxsj5450B(+sNrIkq`*{t5H3a;O2hTdvH2) zLrDM+2lmt_uPJZY&jOW$IfjLj>NFKy}@{d{aM>2YDP!M^ITB#NR#27aTHYZ zFf`OU47iJDmZ}!1@1`Y7Z>OXx?_{`mbgGds?ZE*EE3*YJKG7yRl*3a}3>?9z7@hmw zg$?BDr~}=5w{VfL9aXF+xBGH@jws4<9JIe9)SoO<(?Ct5$h7?V~${iBE z_a}t|`|-ims_bXO`*Yy4J{8~Bq2k4(U6f&Ec{aWS_Ybo3F$U>b9JariQ2A*U-;hT+ zdaiC31KIiYC{~JX(fq_w##V~x$Smu`D3&7t30vbT^>qnVS;0*c3`Y>rLB!%#B7b+{ zCC}`EiJBUIC&+2Zow3PS3(@f6LWqSJFULUBQU8h_Ke?m()SzPa>*M{^B;KI4RCRTi zahZ!9TAW7&iP|w(7bfCpkObRD{JI)MP_AfyfxW#%Ka9l#*&-4gUWZpepz`$+-xFV6 zAQJ176FZ2@pmH%?RUM!d*U!*b$z74=&6lQ#wa#s)s5fQ(5G9lO-H<^~cEnLGIh66F z>%cLQ;DhL5=|-FtLy4zxJQ9J&jxPJ0ft)~~^w>mC+vq2>6t$FY?#wc^u*y(551cG*YqVa^W*)GwbjV}kEKR5wGly#`njiul$9zB}SO_RoRjWvAaBw(mz@Rh_35pd7-cvojcqxe3>T zUxDJzqaA9MXZ(vwA0A40N_ac76HCSRu@pIv4JU~OvveX+-M*;+Y zEWW)JH}BmzTw4Qoah8$7&rvhGa$-W2e{CsJ!^1*@g9#`4aia-UJ>RRAGnYj%*+?u^ zSTLm}+09w9H}~(GIjlr|8FOc+l_QUh<(M4DD^_)DxmuUjlsD@)nr-<{Z&o?;=7Wu6 zll*09OBp!B%SS2qRiF*WcJo3A{gN8Drp^Ja4_Toc|3?nP?t#JR%XP|kd|EL6P;;vw zx0fgR9mnmH<+@upwKWL`9~1goSdOxhTna=@dHKtQ5CRnixvi`CjtgvK%3x>!AWMsS zD&D*jc1c_O2*PaUu)rSV{CQ_;+pKIpqO4uh=`2^|3|pFZRz87KZok`l7r3=vyaF`< zsg|i~@StDk>cOkzHZ*K}124u*uwf}B!$UxJXNCDI&L{@ypOd7A0E3L(phB%f{tTg- zgy}7p{onMLtxVE&vCP^(n4UU>J-#wOH}_sLj~?p>*IV5)LVg<=?aI zS1$uM)xuW6O2K0IUIXCUUI`u9n4ErL&1SYc`^SnylV9dm<>pfbWBK7|Z_=))0|8YLMmMuI?HXswVR2 z7Ed>K^AV40#nufFkCbY8)Nz2&G!a-KJ>m>`_3}ehq<=V60+;MMcj6mV>i=pog*-D= zTq8lnCeJegC}uz6{9CeroP3~?m5`(^vjjvUq(Yk^Mos_$r@uUd4VOB34Z?F%Jtl3WbH z)rhEC5FZ{dompor?%y>&xk?(#xvrpaxE+pe71j0&Bxuf(gatIC+WMhIS*y)U>E;9jWz7r1|0%dBv84(M3aPzc zGsOcbXOAE2Rwz#nF$M`*)@rz=r~zmSpxJr(^5wJ~?U+}5V)q|w$6qPee6T3K?jhvc z#Uvyn>sXs20UBA2P7}?tmaxbn!5J5(rZ1|?e;!q`!uSbkE=L4@0KnqONWHIa3kJg8MR9Un8 zYb~}XUR`YQYNXHJyNf_uKYr~s9X~o(v&LZDbzDZ&`umFh;eYfij|AnTf@4r9inPU69sP>s`A!UUo|~Bl!by7)Hb?uFH{^{Gnz)ZoA+Ny1bG|+>6vq$ z2H9ow=KTyJRMN4--c!8480EmVD_g0ASs8B&CF|cEKY=}lTCo!94U0)?uY2v(iWj1x=}D4qU{-ei3<3uc<5x~R;?<;pg4U-Sf6K8cqCh985b%qhn}5az(}P)Vb@Mgm0L{(9*y-u% zv9U>sTq_i=yW{%>o!$Q)KER>N)uq^91qJlH0+feC_Z_#dg(*`snZ5}X@6HQZ+qn+{ z<@A~&Y(IDw#mU6ZyEr&eg_f*Gw?gKj+(3|kpb?iS)1zZ~! zy|n?(aum!<)9RE*3gfk=6MN+e5Xuyh)8`VM&=s{34#dNjR#nCle)z?ILV9;Glcyp# zP`ehL2PC|S>p)-z0Exy?a{h95b=aq<00JyNtm~&G?7Lwc$?nfBEvxK^GC5`)#gWX` zul^!RLJMO<>vn())eUzyAnDr4>u^8DY^UC621JgVhM9X>8-B@l;_)6EpE3Yt6%W$? zh)=aBDXAg;7-1Mr@|2fn>z>H@fHVL!SFIBpH{w{hS~Z9CFx62eB;S*CMej=*TTW~r zlZN|R1pRVwmflPXt(jmD-}?Sswo=8@$q~O%un6oWdTo5Igg6wSLl%fM&%9%!QUv_) zPtCEglgYJfrZ`H4>V3(uT%_q;;%SQX)RYFDMY55OFR%^%Yu0i zB#{nT+Fq8IC;m?iKF>{1l)53#5m0=YrC$e(rVKSBg&{?x6<{cN}EvMDPwnXi^i&;FE`K9>Gc;sF4e4jEw1?C1S8rmQ7Q^7`<9#(>g7|6DJ>b+~ zuEBXC1)omheR@@jht&G`wx?b%H-EuDUaV)svt@|vI`a+{fP5JJPC?$UR2KDPe@dR-%?5qmy4?$FEtb*x@|dal zoigJf2Fgtgc$Z#hG6u}5ngm!R(r#G^8zJJh|0N18dXxV z0r{SM{e5WA9MCoY3gE4pZnyrcCEwc>KNzNWpOs(qLLYMLKEHDVVG4c!FdMa~rm0C;;`3?Cr~ zX$wpWVUJOdbk$}(1?Xs#FE9Ub*aByC-n9J=vyg!Gail8K?R2Jkz#uGnPs0+LWn?nx zpYc#4FeJcm{jr!tBlhi+-;1oSisC>j`~v&#&C1cA+N1zb*}A3ss>*XV328}y?Od+f zE=TEd0$W{$K&}$z2;TrC?0nh3=)YgNUW`_@wyPKn0Id7{o8kWbNE6X0!);s4-4G8S zRw=1;b^W>5M|rQMF8(Wuh{cm00^sj_Kw$HhZP(6bAQKtPw)=Yjc9q=WjATpb28YRWJg>4^cRIU`#Pu!&aB{By5f$X0Q2V$!V@ zi&Q?uiTR%OO6s}*)SC{|-MoF{Q64m9{FqoRK=-Z>#4M^3z7}b9k#8|~p@3C!bW@22~5hvX!_ANN%Z)^8gwlIpCm+QHvroN2# z>C}EKxvsnW&>yUsri#Gwd9wHnaZ{c<3}OqITYFy%fyF^8%ZAPTUk#k^^#|OhKYy;w zKc9#49ib*?68C$rUp9ksNwNrqw74R-^64=nF9J}eY!)1letdGd*Hl$i@!?{maMCMM zVaeyD&pc>?7Bw@21S>O=;`%C5&kDW5)+rGWra8Ebr00%BzRi65R9}5ggyH&cl&zNI z?`c%q)j)K4Tu-clo?gh#0~%7()=|4pQ z8NZx#J!{HGQThJF^@YRRs+rwc2-$WfeJ_AT;+};J2Om$|IeY`Gf@)+H;y$ zM#jRw#j}?D??&EUAt?ox2H6=T&h|3Mm!Dtw1fKPA0W@2Tve4Q;Mr=_M>s|8YheNJW zaK@mno*vbe%8UUuMK-!yItK6^O-rM+A(r>nmJZ=VEKwm*_Jt&FgCy>b1H=@a(1o9q zXP&*!#9U1y))(uZ9RnZEp8x;~VCUY-wB1i^bd-P1|9|9JzJ}sN-M(SMoU14eseD3W zq5!S!AY<0oR{L2Ll@6*V(jY}FMK>vrk&uWpqC z)hB*$LXMA)yh8p5r2tp?h_y~2KJQ<#R*O_StH3Kovelp;JkntP{Eji55JqF0CP=+g zkJ!Cv$=R`n3cxbEOT6eh-Bi0OOOh3v`ZQ!@bv8z>IQE&RsIiRF;s)E@8Sv zd*Kr3;KJ3qmG^ZbD^>%j)YN_@k1THE6VC-j`(9X8Wdta4YlixNXuJ%50MK3QRFAq0 zfVZriNE-TPSoT=jC$)%!vF6>waft{toc@K#Q|npco)_LR#!$C68t`LYzeaJ}72kdB zjLmy<6OM-Hq+SV#<$_|59YiOfUVm%asza5Wbs-;&vrpNk(ZdOBd& zvo{)~jBS2GNB!QB=QBj+XOl>PYJ!W7RceFPED!JOg zn2SdogZ(TWow0=)5L)Gy5*llr`idsi%I2bs20V6NpqEsDMMs58N|NH{dqr)X(G@7u zb%V)&rL8xnsuugJ?cB-xD*?5US?fa;?TyNJLc@;JEN)3@8;PROw{JLw3tjK?{X>-J z))GNc{>wzXU``6a5Jw1wwmX6QmJ6t(k%5d~1{~bwIB@X}nrIKepGXfo3P=dgn>|fs z0lY!asr_#jp`C&f>^~c{6n;b{kMD6KZn^6(v*`7E<;HQiMG}o-$S!(r z!-tsb^hlncNtB;~2Vv`72RJ4%eyO3KtvJy!?-U0LQ?FTk|Ey&JLa-)dwl4W+NHe!B zZFffwq>N6M#XhjMnmuf$n|Jwlu9CMCLs1&?+@`b8RJk*fY~~ZvzA$O+n++J5$ND%( z03axPN1y;eKLYGcQ-;%ju>SxW=0ayOmeyi9g?5M5a#-XXmwDFKs@p7TejL5Ml32Z2 zEdRx!CVBOU&%L3yQd$t0F~18kpHqBdd4vWgpVaJ#rzW!xD}R-CfcObJeN04iUHTUJ zuhe(SDo%wBE@o|0Se}R{A%1Rao3t(pZeB|@Ooy0ylPMfN~-xTeuV!B&^do?} zb$fWX?2hg1PEZ$&`@$m-pIs>8c4q9SnK{0@Z{Ep#d;NIm+}(8{G@FN_eB7R7@an_Z z@azmp-8pcOjB2OZyX@eNjgpTz1!+c2M@O*qutMOUpTBT{V~X^!Ef+5jYF<(IwP|4& z8J$aWTYG#YXL{RD??qhTFMu_Dw{6DwneoB35Z>C;X%8`_K1TD$5B@RWC_AUqP6BG2CXJHTXu;PX_p53JVQGzZD+mMBY*OqXz?++ziZSPb$jaaBfDf z@v6_A$UV)sefnj>MRV3{DQHsPVeXjpkXp_e_)wW(N`0J$cx$Qq^O4CQ=mYD;x};WI zMHy_uUTQRJ_AA3Ccwr%!+5YyU3m^ZEA#TA}So2vvtbT8lY}~-F_%+_>552v|5q7=} zB8_{v{Fx0p+FAdHmkx{}y`csU!%tUKhxr!F($-l!JStD>you zEPs?%^LoKwlI(@okKG48YRdC$cj*88%{)N0hpK{2InP+;S+(xUO}QxbkRCpJ=*&ND z+!GAF+m&*ssT{qx9+B^YXWP)d!F)5Xd0Q@P@bL5W53fL&h14|S>Aixg>oj+I{=mYG zCqTpD{2b*E^q+rx%2CZ`4@cCP`>`%TtIS(#)^c7_DqaAmocbS%1(?1$E6f^!#hP+;A$H*mx zy58~0D^Dc3LPHku=^d6U?i%3_%05z@wQNs?A)TOF^hsa!Sq&9U8(}$oQl*+OcsKF= zI_>c(N~!CAKR9lO;l@^)!u|sVTdo`$aPiK1ifNy1o6eXQR{Wu%mF;X@a>$=_(nEgN z!$43Pt1jBxr9m$Ch83MG@;u{nBI zH6rq@OhRC6rESUNR@-%cxtA6VS6pO)3rKSWf<3i*We){e7(aJ7T8T+m{zN;UvEq)^ zPo~iF3o#`%oihFSLV1Bj-2F)~i@Hkqh-aMjvNx`|q+eqdhLhXG zlOTnrjz@=>Ti_Qzm4j9{NN##A;x4uQqxdM8JktCMGfi8&fcVM!>yt~AHvrMna}5nL zNYBWMo&60i)8T$G1sR7)B+cc(;I$v|@$r@FsSj_9pwhEtxa|gFTO8{@St@Q}Xr20c zBZUOV1$VEJkoS61#qig;ucd59n3j2Vh7J!rj|rmrN6~G={4HedL@+`tZt(^q$TC{W zPhJZ(O%czcg-hLhD72#77FX{Sm|7o1d7Jb%rTnAd4+8+e*s|pZ z)-yN78t+p*IKue_nZ z7ECVvpbhdKRY(z=<1-pk+USI>cq>%(a|uTaT;8o*x{NOoLT>*=0e_2r#c{Gq^XH-$ z64caQaG4FZ<&R<2qz$PVr#zOVeM1_yGCs}6E5Vrq&zwn)Q8x*mC~gf|1*MZg7hdtGP3Y)pqtS>R@5I!355D zVI$}H%e6YSRkrlmF}s(@C>~^&l?^dZyj^Q)dqA~Jtr#)D2iu9#r%q$gaUmEUU;1)iNQJY8oWtXnqNr$;%^~TY3Q<);dsRZQI8XaYr(^1s-QS$( zutQ$B)EBi(jqcDJ6cvcyI&7wAc$~L=;erX42RsP`{apzYkRuYmn3a%0#n?MtY!bu<=|av{f}45u_N2i5zYj;-SN5 zp*@Ylb`9-?!io3~6-!Grgvck)6fga@xzY3#Ztr4yK2=bAD99S zX4?G!%mwqO4Q+O6w=^exy?sPPC!y;P9QaPYM*==;W@Z_dSN!kn92{DdlS$3zX~H*y zPCt1M7n2OiTk(L;2&diA$mUwFr{RZiYJy=57A;@4b* zCQn){gJ_j+ku`p&hTin-)5>LyMT*-}Bk; zJ7OB)!;ZpisG9sRD{=+U2smWuLL-_mBdEHpZ&AKV&sK8~iy+(dw{J-eRl^KpC0t~_Vu%$jW@hE( zQ3YSdZdl6^4^`7=kN%vr3YZA4wPO1>mG3oT^tC-B+Ah8+FY~#H+19b{+L@hxvQ?usI87{+V|S?DVD@^poZpF zAD;5$HZbnqW!=p|R?mE8&SuawJPyoSm zCvuv_(o29ZQcYJ9(V@~|ywRk7Qgkh9T6|g$!^+_LG_zK1n7cDG* zTMj2BrvaT%1)H3Wk6~&;j4&dKij@rn`Y^*sKd6wqlKpe%&=V=M^@~L0O-)Cf^@tAm zc?7IiK0de3snb6~%O7>{W4M2?2WfH&vjZ}R_mm=N=O73qhak@X^zL1pS~-fu4YtdOk&A$dX0^1ztlO|Y+vrz z*Ja!fQF&jb-@0{@4Z<00SXJLmHVRi=<>vv{1dQjMzESuYhnZbPBv2i9SyUz@lyh+M za~swkY-3v_Xh`#DZ_Av052wgEqNqf(p5ZJ8E3ccCIp3B=(6o}ET#AdUsHjt;G$g}0LKeYSb7)VbHC(>%g9+Fooj-m}@@Z6Ap*>D~kCZ>Z53(K3 zz;15dbcrCAUd)O3cuQX?{o{k&FM02z@4CjqCdGlS8Yy4$eyP$XANZ?Baa8F2@%4KH z&CWyF-KX`YmhO;3lxd@Lds@Dzp4040Lo{DhCIWx{7G%zG5mp{}K##JL=^eQzcv_FUXvKyMTRwMb z$gli_F6XkH**dD$8 zvEbj7d20Nrf`Mxpx@adBDqepNZ%B#5@mL(jQGZy35>=el1oaBG5*r!$Az`?D|NW!{GBeF^=$zv<5h-#`YFctN6J$9u5Rzu5+z}e7j zaX;*mOzjaotH89Zr%JvW(OIXaQn4yGMYtXP`3W--$Yv22eQbTez7F^E;4TX;PVT&^ zaFPDzw}$%8?4bT>DvZLcBZw+V20s=~!7Sk*Ci4iob8vpHV_MyNyNs@A~EM$387@T+5J5_0WZ)=k(;L zVtCW>#12%yS(l%%T|?gS!T{f6iLr?*O=nDzf&`qOZJn;+Iw(f3Sj~#dM6y+U&s*dI zvQO7+zoXe#&fpa*NNKPipXoJg7i&a+L2M^y>|PToCG#2tC855TOU72XPZ;? zr)=VS440JcAh(!oBZqILmOblfLH0CGPI9S6Nyu|iqP*WCLK6D=;v30x%kP4^mNXv% ze4~i>S}5yx-;2Q%l$2DP5>ULFc@-Kf;j>qFM_OER?dJBv$(*TOjZt&kr%|#=rmO`8 zyi0Op=^**AXKdDoS4w3NhwVyg!m;T*%34$Ur46W3w-ICE@+RJ+eVdwAerGRIucQwublN-{3`~A$&|slb5qn=mlMj3tj@y_b zxcZ-5+@0j*4)4?B;VcZaP+HEFs8qc-$eR>e!Y}uAC$ZTf5{6qzj4_&>Y#P&ksb^aK zc}R=+BMua{Je8kR>OY8XovwCl&*4^2H#2eIG^}Wxo6cZV8*>VCX7SN$?8&^lWOaor`y!6v;Rv3J6t;vE9RzynmOGq3iWe-2R9h|x z^uS2ss&DeGgNyaj2EcHR8_Mm3!vM>8w!Qrt@-1T>cf;5)U}W4YFTx}GXID2%1MvFR zLRtJmsRQp7!=^6Z9KF6`)LG_*a0Me)Fbr$2F-KT>crgzY(t$~p!%tygZ)Xn+`5P<2)xDI@;0NPp zU}RIis6|tQ%+Ak#ouGQQWy4ff`6k_%h?ofcXu!Qp3JYy zkUe=S>Wey{hYUcMn+MXlQ3C$lDh#ZR9ha3?&DZ{7%YEfShed>9?j!2I5oF z183^S?=3wyWy5B#PF;H3`lkx|h(}@yZ3G_j_VKBc*__^sJc%qJ5^f~(D=u%ih`<6D+~cs!r8Zt2FX8H8gsahlS}z7h!>4!nSF1O1@?^Hy3gq3~ka7?tSWE z456;Cb@))j4oPz0Om$$3Td#F4D!i@6)lh;K)8peev8qiNctlS)TJ7)|(?#Od0(jA- zKG$PMOuQ?v1#&1a zo;E^M7fcG~jKwvyGul7O%l>I06l)Bws1bcsh@0Fmw)W&^{V;CCpN`|?jSJlvr$+#7 z{g*lw^)@4vta-H73SG{kX92{@8k_RLEZRh@X!_f5b&r|oH28FB|EppIWoqvOm204& z#vK3A+J@ITb-?lK${85BaPg%(l!>o#aB+*0OE`$?UPsw_W&rFybX{;|KdID1M@bk5jVbo`}z^(=C> zAD4|Q?`SS&Iu!-b1Ecbi?$L*Bj8jQn^8CrSj#n4ySM3XMyxbAg zvaP=0@<{X7k|Xoh*g8Vyg;7o34>f$=$M!2Gmnl% zR48Iq1*sD6(S~h^lD z#RwEb_r@P;;!^x_Y8z#K&ohE~-{AZat}ak?>7%71f1r*V{KtvL<|B8gifim}VH`!*e#FFB8<6hzo#O8^~n_8P~xM zl{P;qKU7|jU)H1%YdYR*>K#7DDnK7-_Qpz|H1=!%xOzGTKwd%m+-mShEHsTGw@r z%FcNp**h`yF{g(NT&l|_Mmq@X>C&w@g(+fTts>Q4Xluk~O|LZ@j`VtqE!r7BA93Fc z+hbRo0x;jf!A4l#I1Xs3P;qY+&BpYa;E!?=Bx|jF?Cn)5a(`Hff_d)YyojH1pWf8#-4(LM zeSLo#$RHTI+#K{clRCKP<SsxDr^zG%EX4F`5;f=ZvEsNX<(P@e#9O` zCE07wNKLU;hbIHdZ42@yzrN#JVt!EzJM)Kh@t37$866{_3RHw6f}OjFRT@j z@oT5^V zX0>|BOpTlo2jP-cerw$WvmbU$lFYPCcxA_h8<`r(DJe8leGnzvWJJynSJJ0s^Dsrf z7d?J)Uph)&F4ZKtBQ#U-S>>)MTbV~TdsJazDlo`(Ke=lm)F`PbDdTO{PcL+Cw|~5! z5v8M=)2vc&&iA2YsMq;p!74n3Xl;A!X)Iym%jPOOVpWln{Z3iCnw_3?zfWG~9ZTWE zSjC4@8?pCaVs@$f3+l6$G_1X!8I^0LK(`d}Hu_K|)!};Dac)ata5m3! zSx5)cY_79zbIkJNq6Ys@jl#bV?CK}%Ozrq{#;etdSKIItF{%{dX{@Q!BnTle3|*G*7_}i zRhTAkb%h1Q!lu9eX~>9 z?w?U?73)*2v>|s=ce9Y{#?0+WDA`ZC%xnd84SeJcNy5oKrkyDIZc0PHz_JkATT z?ICEatozBY#s5Xtmq$a{$8W31R>@M7B0I@W*5M&pvPDH%%aSbyV`og+2@{fi6rz$P z`!*v>mN1fi9kNW8nX%4b%*=cD^!$GBIq!S_Gv^rR%>CUz-|M!P=r z@jVU?hQdCrQ^+1Il`ukhMElZ{q_r$PSJ|XqdCCsT1$OA%L(u$u8MOMHXN)L-iTa@R zd;dt$$-}@o9prp^2~nv4RAaCWbq4bd@x19#Fh~QkaGO9?u@P@~>YyNRF!JM}!A3X3 zF5_b+fpmsjR?G3u7!ikf7ai~PbbZ?h&@qIg`0&t(y6V1@=hU5dqzw;9`Y-X%hZ;s;ym|hWJ)|ewySBu zmPtS*sIR&QXHm(^EZz7Er_DsrB<+i~Qa(VB$Z!x}vR=BlNI2;z7oQzL*mII3kfP^;9Ue)6$c7tL_8iaU%eOYU{2R z3PRjU?tVwy)d={ks$_k7c;$mtkK;|=D5o<{{RQDJ{oSQj1IAu;(^quUn#4a7rygJN zG%p=*IQN5oA+2fBQ9fGnLbixtTpe1vrQfWQiv9dY9Go6l4ZWdIe_p zx=Aq0CeD8~@Fxu_9JY!xvT|wnDE!sqEy9UHOJ3D^; zrgS!h6lLZe3=JEcFAC%~)JtE}kUn}2Y)1t?`E%OB*+$*5$-{RaDh5P~s0YY8$o^T5 z7R7rZ!JqQoHT=foa{X~qFUqZ5UB}67Y;H{GAeKbSx*NJMg`!A$F|?u2FC@NzyxvbD z+z4u@iy@^$=j!qfiXYG}N<5(jjO8_<-$0;hZ@?L$1g4^IJ{+^k$`N0SsD^|n#0v81 z3Ea9sWT>}#@J<{5C)7&p_XHtjIC60bgTE&(MRMS~tZGVlnIQY=c^LYhf=QakNv+({%aTial#%Ow zS&fkom@Tp66!Ahk1J>5(oj4127Q-&8HF82v_|elh+%AlokAVnSMn*8Ld@RiClvdq79sh(2 z#>UQ5EG-c`Bzf*m*JYM|MDTucIsY+q!%5_0YQg4*vQKsFmyEuCiG-iy2! zx#)Lw#>P&JGyBeW*QB%G^-C^h3`r`nPX#`hP#XR!n{gw@i&-VHT^Dow2UN+nuzFA-?P$aJ4|k9 zfNdRvVxZqUhy&fSbbT`_L%_>A*kP~9U&tJiWwb+H+BG`GI!+EjoxqB+vo}4%(x&fn zM~GFASx(e3f*{0W4o-GMXzO!ms8{b!2qn_l#w#PVgSG#LHlrNZpiP_0#ti>vaKJD< z*B=eY9{qD*wFnaNjY;Wu~6|Q0$Lj$amO+3 zs3=GJ+r=4`2C6Mmra?OTe46v!(P$9X8u;i!|7FCPP zF&wA+^F19x15w$%^-!nx0gu1;$o%$QIr?-~X5u>liau(iQZJzdmqvfZ{6R(kT)(VF z^|BQlygyBC`6Wjcr|CDe9xb>2dUlHalGp%r^JCAQWZm&kiOr%@)=2l3R~^B_W?oB z?@`dRPt_cTB5>r^apI-2+9g1aPkLmrvIY-f_N8J~Z+qT#{r@ee!G# z?hv})w6k#XAOcaDQ>$!!Cvo7Tt}Z3mt2eN04%kC~?qpNLVS(F}jRII<*9?5LbYmiJ zA{NXCHR>DPDm2RCPuuK_z*W^;Vdi#VBHJ>BMt`T;iTTi<{U8{V4vnGZO(eXSdC9vN&(!Vhwc z;Y@+P+PJ+9c|Lyyk&^PNf@630mi6>GzEBc+*Lad~K9=9rdGn3^Ju;dzOijGqXHLuH zk$>GdZ~D_bkc@KXhyA;rK-IwyXmY6iCmXuoTA%+2*JRJs2B~yoFPQc!Z}_XBo0@$t z*H3oWJaEv_eumG}F*H(bn~NrZJgX_#{9dv?=M z*SXBP;pqnT_oGQ-^I+LHS6g#LMN{zNk@Cfg0F~Yk6{g;m_Pf6;J#ylIyR9s-Wu1{J zmsZH69piSyt^kypiC#jyv*))ZNoBkj9GvGXpD7Jni&{As*V&@c;x+T>fec|^`r?mT zr@@_!pRAr(n>+k7t=M@yNI!rPZ<#Y4<86U{o?bxUY|k($6~+8l#72EfE`60 znjJ_Zo;CE9d{yE(3P7#f9$a)9?#R@9Xb>PXi(FVkV#(7!Q}y7_wieaBjtJT;qYK;` zCvT{?e|w`!JxR34IjL5j@{g?~A%rV;V8yJ>j#^vp*f&@9Y@4qOwPaO>sBYcUbsuis z2M^e6RLxMpH-Y7{y7rJXW6)i=vm*K3#5vvLQ{X7uY`*lLiTGTFyIza~&;X7z!bSsY zWvzx7A7bOnte-|?#>)pCO91%Xo>N(nS6JZ-oB8>IujdZ_!H^@CN()fxK(fj#u|!%# z#Cph!kqrqY~ zk+pcac2#U*Lk9u^?-{)Cz7#QU^`vrqgb`m>vry(l3|!l2t8^Nd9ejANq6p;1uz7s) zUUb5Cg1?$ws9tEVdd%*t%M@{-!l$6)Aw$V?{jkG8CnoB>=L?HGe>7TJDpdC$w)MES zrwziNC4_uu#)0(k>!`uJ&l{gtt(kkZw%kKs>N z=63leN6B-ix}$%TEmjjkJ+?O)Bpp6{{#etOHsvUnT3!*l`-!23wx&$Z`Gvj|=D?dW zoxEXRvH#u)*>E+w&lryN2p%GJ(rhpLqXIpPcfF?TybtI45uc9tvg|C`JS(RT7QQD3 z2)LdPMwQxWV_O~%rtn~Mvori_cbWjt1aN%uysICo@@$hkIY;E>gjZQzpR*!>UA&xf ztDLJ}e9;7XgS;!rneF=8+Cu285U9H@kx(~$pHe0!x!y|q_Bv_G!XXhi5kiPEdw^=e`I{KrH{KGKJ+>0 zG11dKdZTc;VTAVOzI1E#e#zl_M863J$M=ZKz9O#xY%$>t5B~j%4ZWQ-<#3@qeUAzi zdE5~$a;+Ovk-2xaAmRu;3l3>+77W~|vc@!1h=Bi$l8Uv~A}-XBfFZrSNFYqXq^Slh z6{S}3{-+6;p~Vpb*>QQ5W`9Kd<$#!+czabz8hYILI=Z|2J7#P)z-bHyTR)@H47=YE zrsOZ+6z^L?mFq!uELs&!9H6MDmyVP3NMN7G7)wC0CUWtL*v-Rr_r*ANojld66UdSO zRVf|_((`NjEyO9$ALBeLm3fM{LS3S?&2+0b6HBWfrJd1XYM9|P6WNQ|cm)0-=h*2v z(D}s`Y2U+>?!ql3Y5>TwqbAR^jCVuiXOPbty7!l`LfiNo-Oq;AP&L;49S3V z*~6OzEv?-%FXaFQCeZdD%oqRa#g=dl7)>tf44@YTzJao&99()+IN()~Sx_EvBV*92 ze&87K7!-t)FRZo8FdVnWn9U=Q1y3%05l`>=Sl~5gbHWjR_!_7C$Y}S5gn)!9aIj3_ z$npH1x!2YhQjG#x3tKmg@CO^T^|Z8;EddY9GityDk7v%hrww5dAkt+xBJSDHxwxeU zKC_KpId}I|PBwAfZ}=66=Q@@~0*R>msppbr;EO8I7wTgtl4c7iV0I|Hs|&CTM@*$aU9 zdwWSNQg0FC^aa*seCU(v9}vLzh3`Je3A_13g=Jt$%VMnO5HOUG4iiuf3pZk>>&%R= z?GAq}vc{k+d~=pk^+WGr)8xYzkPA&rmunFc40b2m=U3-v&HdE4cjw2(9u`^>GLbp^ z=&9eC0M*4`}-Z>F|*S zMj|Xih)ah@aXKF3eeel0bO zm|+9v8ZFSBL0zsV&AtRFx>Wqh_`__qMmQp25U9g_l%6wTFL_F9OOj4ofKpa>3M*$S5Zw`?0e-Q$ z`QvuGOX=*?@E;Pk;*TZ+Xaj5Fq2?V%C5|G4!Jku3j|epCtkla!&As_OqM@>{gq+uq zI?CAXtC)2Fy4j#+F(k8g!^9vhgDg5xwBWT#EUDa>r{W{OdJk0=P-`8Ig$hB|VYZkx zx__?xJJopjqR%H5z8WXX4dh1S`%$mcG(uPRrOy#8A>RFbQ&3+zP*;f9jVX_2|m#eyEOL=DlT^oYH~z}&-N`GCu2ZLh$*roWzF zb^~N|>eQL@0E|aR7t0vH;TNOgR6H(TmNAGrddl7c-IP+c_HHtlyfiw$Q(`)htF}Eb zU&;2YENy0biQt-59|w+`W@4-cy+vzQUDlM48@2(-sIcE_kk0I1@%wmU{!=KS9{a}K zAs-pUI|=zGh7yuez*;d*(J$fyD#oU}M_vrz&{0%+vgXEfy0#fHWGmeuiQeJnk+!XG zh|r*vxAQU3ef1IPuZB5Hz`p^u%CRXQ+`~8`W0r4bqv`}&Je+pDND>Jj1nxJRlwZ>(;f#yN!h|T}{?(4zZP+0`kDt1gEhX8FX3^wT!pz? z?e<1dkVTU+-ZQ5ilOT)vUyXf$&-X1YHsztDh*Mw3q~njrh|BrCa5+(f1M=ot8*Ir6 zthW}DuYbK-tng2YO^|MX)5Y5fd7G~7G5ftK9Sc9*qckB+bKX(yvXfCjHWm+uZ3Q9^ zX%7cp+E(!Bb^S!0va6NXGgQDAF%i%*Grl&jME#9RM5AF4{uv<1kMDI4OMK*`r777W zE@V_Rd?Y&2d2xp74dSz+PATA`D5z77^nck^4f+aKnO-aAs}Rh?EM@ok*#SABF}~)Z zx^d*;e6|cqR4)!g-dZO_NcPL;#8>3msr_npCpSD8gAs36LeDMz0qs~DFg0(oax6*X zvt|90tOB}^4>hoMb8{ZkHs$3cP?M_zQX5mS%4Xd#KLOL~8HiaJo~W_Xf1Q=}>UAF1 z&MV|c)kc9k9zcEi&c`EeipX-3%k0CBlhU&WNY^%yee_e z`ad1bHQ5j#rP(@&x5C1J`pks34C6E%l`GLK#|o97*EOyZ2RdQzP+3d0yf-U(=$q_w z6|5oF`g9lBPx96XILxxIlUpcHp^iF7@g3Q0GFo+|frK}0ehre=v`!?@CC&>oLgijy zgVC}|ehYpvK>;rKPuwO^nf_Ur+Jk#k4-Hm)lj{s&n{j+fKaatnIntzq!ab;8c z1l^e`R58wQDe$Qm?EQXhSl;UPqFtR?&YJ0v3Ffd_&sX1Y=3Z^cj>JOER?|(ZAS>>X zgNwbu(ue@JsFHe9C#310Yij>Vi+db=J`xg>{^ro~3cMBh=s3Dk5NuaAh{u;S1wd4=O7jni=06dUujs`jzqM%h^Xmn!l9*|F}z+ z*4|y{(@~ttWqy1h%X20>duniSKFp*!f6kTHG`AWOpcZ}wsOj0CdP5zkGs^eAR8&T$ zk}jy`#8(jsd@V?bmyBlWMDEX-F&NzIoyPOF%}_rE~ezLC=DJOHPc! zqXX{NUGx{_8$|csBzp1-vPq=G6(Hg`@mwYWI9XyD(W=~eT(I}mU_+mP0*GUACdV-| zS;67zWZkxsSx`_?Fs!AfXlX?2_&dpC5sahX!Fu!HaJ*#IyYeo;%~&vZN8oDX4< z&az^iR#Gdsue4GjU04hY2nhICP{JdJw|R(Q-$k4A*Lowj_-}r`27BBs6COZhe+k4T z&fm|4$kf)>hiKq~=amlTxnomWXCsM$as47?THmW}VMq6$>RI~vv8?tn0=*Ge7(9K& z>zuyL+MVI zKZ&|r$OZcqQP(KFg8nAG11(GqLOS+{`r{Ha5lODL92ro>X7Tbr{+pgBs}U^LJt6-q zQckqh@b`15w7edCs|Rb=?13Jl?UyNI)OQv!Mc>FI6RV```USiqWayK7>}zNA?b?H{ zfs_j?4b*2PUpC6-Je9A4{qz$iF1Pv8q+V7QRyIUzVG8_xL{%n=lP^QDgNInnSqh$6 z`DK7T1X#h(;%HvPL)@)5t&ZLM#a)`MN{(;o01#k z0!78^+S@s`tv{yQ(XSBbaa}V4V@% zEgV&BIl22hqdTv9WQj;$X~vU*_ut?Gs zxzH+oMmnD-w~c1V-dSvJ0_{A8rRSa^NiC3?i`V;L3-^6;r(ZJ8`o;^}njXe`mV7XKrusyoSXji> zWj&oEWWec=1l`SHedi;s`#L!Jmz}8{kXkDp&r#iv3iEQWSfX6DW#U89UQDq)Tbv~s zJ`(pJ-k7ej=r(=0Ly<^7X*q5ze>pv=oBd6PXX!X)sGp4TCiRFJOXpJO)?$m2yHvTq z=&vB%A|cZBgrO;4(=K{nz?Zri$mEoed%=p14oVCQ*dR8#lx~`Iv$Fe^MZnMBeZW7j z#rqYLvM^iFaV9gJ)7qI3*fKMHWxLhoRYBZ4QSCcbNmql8qsMUPa>P4uflYH2?R-~( zkms7gojZIWj~gX&fY$8T6eiE;s43# zbBKQ2&S1qQpkl?XIrWtR;c5{cjT0w$OQT0Bld>~nuo04Z~}rHIyi^QiI^*r{%vCJLjh`D%RIO7 z2i1PqN*D>QyfN(pZn5kf<=l7=yUm^lU|aT1$7J^ID;#S^**%-8s+HmMuMPFq)gm0p zyy^hRP^op;;N@vQyG_nNYocpdlz4Ga!eD%_i>$U!;-q-^D|*o=DGuP{aMB~QEwC)2 zhV@F#bXN@1tQ8kft78=NuH(X4Cl;&d^L+5qvNEGZTb~N?#06X6^PTu?8<1SBYBi)M zzAnYkPGJ=YrgdNWS>eM+t-BrZB7t76ySlmtNT^l5Y5s$B>4pp@cLHA88{vj(VGlo~ z7ZVk=3;7m3%H?!y2802P_g!39Y@b{LfH{iPt*!sy7LDia>{@T+9iJow=;c4 zXj+b6_q71I@!QM7>w@c|iS?DME>1lMr2OsukN6;ki)ICL+>Nf>PQC~`hsxO5OgZ(q z?yRLI^tt42QIT4YfW%@#3Lql+P0*$n3a*M=;(7-l60%}HHKfdYqW=XC{>?1Zkp))e zyAK!o=0CYvkVN_xOgAh6m($W&N{w&i$@{{_;uz;cF+%-C z6>asw_92eV%3%NBo%wYaGJyLnO@M(p24W~LzMgy%<;1{eH8&B=cwJGge1VU!zV>9h zbu91*k_!t@E8e~El~tgT0|^sM+f!3&;uY#{lQBGscfuzugIqt3xQEmtI8B?Zn2Ioc?7gf`)J7 z20erASpv9fqDDyY*2379iM$y|tncjUD7{X4?#O7pGV}E9ykINWOf^1?%lQ-JuK2yv z$k5W*AdB#T6GzXfmxM4mBq%Q=3G;R#Qc^pBc=-F>951kA(i!S%-)9ircYNwx>{-`d z6T|wXVdfO?&Q8q|%;qpmvyF7^-@Hq;eD8rQN$VNw%e+Hs`E$O+KM6__hK8nt{W8XP zj9H#tsixun&9Plzy?Uj5TC?q|u!?d7(SG4n#q4nYQspk~x2b|shLoY&(YFj&kEYoR zp{-RpVch22=84X~1^wI=ak0@{a3c%H_qLau);mJBf5=`8&HZQK@#V{)9)1n~itdHv z?11$EJ8O`Tyg_J;I69AVH-b%&r=43-CF0r6*vRSDdq6zF^N^8k3}ksUD5rX8U2e&= zBPCPeJ@%m6km)k0D0o#%N~Dkm-RvWtZkhHrFwG(6gY8r|PS;7oZ$RLV2E+*Mac7YI z?)n>u*gAz0PS)aAUd8g29qtiiS}*^EbuF!TV-&C$Z_|z0hFy$9{WQq@SAe@Rr9eI6 zzOI9J2ze?W*JtHGJE)dCiKl6j#%1QoyT0(t;NF3zC&cL73dQ7JrQn<)90qn=gkvP- zb5fTsS6+WaF*PSSNm_u6>#sk{5HibL*jNO==D223$e-RPuMgugfa?a!RROwCw>4sn>4 zj^Kb$0JLhiINvgTm4VW6GL&gE&assPU6~KD$2_C8&Cp1nw$sBWhRFJa#%-(Ol9JOX z_G#;xbNred$E)$JS)i8|!0B8pp7?WaZY8i~)|(V_Pz7vjvi@$0my!0B$_9OgeNmu` zbkDUfZo^^V2jRgr-~?4cj?gINvDh8QJHdI~E5?*xQOlhL`k?DYM@Q+*Qds%4G?6H- zJzI|1C11(Jfs7w=3+amI*;8Y)w9Ax!``dC_GtW+q&Hwg$pL`|#%^SJNPI?|c&C0oQ zyvFW;!muM>#KDsQ#*IG=_Zc>-8u{y|?H^uW757=JMgv{LdeF(aY~fqm`y`p(`lN9~ z4ntjCzp$QC7L#aIV(zKdbXSZc99&B4ZVubnJeu0R8Z5sEo+IV8tt@&x}%97SGE@Mb-4z;qt zU~aJ(&2NfU1iS}!?%mdpJ8!G}tDBdIo)z&>QPY}l$`zMQ@Ys9DZ!a_+A;4;0kjWn<+@u6(<;o>cr^Dqx}B<6{{G1n6myjNi#7;+4u^Ql0~eI30Hg`ykzsp%j8F{`M+ zTizLH^Bb6zWR5%R6{GNZ2G5)7EqcBR-kiMm~9nY~5`n|wBT^<@^A z>GJ|p((&~9E}MBhMQf_fce!GARXnQ}cS?eLML6Y>^@>=tE)GjY=Zbp)0jLl2zg8%Z zgYQmoPjD>h$abqRU#ut4dV8AA+tPPW!t*~IlS&g&A^k~&Au++0{eu?T;pZNSmsJtR zkThh8UjqouY$0y)ll5h{Uv(#smrH@ew#c-3GqaRxn1W&H3ULQuA zYC;ODpXRN+`7G%zK{=G-BY#OR2>01q5=wTR)^!Va-A$p*jbvNPst);tf^prrLGSi> z=G%53K@wiCTS9tP=LmcgT+YoT<)#c>%(wHli;;5s<0s^ovwx;sJ=k9z@>q8fC@!3F z)$+GOM^B}Tj$0Bu7KO7Sx+Y^V(#E9~GV>oI);bl+z29g&olPTqH)_J;=~IObS=g;q zcIQpL(sSoY&dtpgTQ-o_*P!G)9-($<-M(<6^|5J^T>EV^7Y+DQhED`Jb-YHb5U6JN z>LR>nWcugDprhYJMviYoBvZI z+~Mp+9dTP`_!sjYJSpfHGE$L~r2|pv+%GUcjCM?HyP6kHm@TWgDv;fsL>Y&7N4)${)8tE=KLtj)f_`2+u*KAg#Yjem zRThV)AUbCPsS)~4nU8zSIM~f~hCJ{(;*kn?%D`;v(msf$vLYy0h`-g+HV=cK>)hRo zlBUgaX1n&BO6?xK)+NF=!xxc9H??&~pMbVntSqWwH&^a}M%LryD#TB0{D4U7TDg|e zIALZW(4p8I>y0og{=NC9i(x;)$gs-F=-nAB!gZ$L_pBUUJpJF%EFr9u0N8`E(Uqtc z(@6y&*+0)27j`2Y68`FZlHi3|&eR_bH=WxWzVyqF$?e~i7KznzkX==TLvni7Y|x_o z9}G3Nm6oV7FGu~@1n3E#At231x2_39_biQj)Ll-lry)-~XZb5w);8(nOl^=yG{Qvu zXqpV~lWzwn{W3~95*>p7gj=6Pha@@e?@5IE5r)Z|hErt{UZ#m#V^~Ss#V&gHbiEWK zh4cCK2(MQRBrPj%t-XLU&+tHP^Vn^IR3IUmsOvQtW)?{HHhJ9D7=CoHN>ja9rPuPK zv;=-RJM8wSlz4-FRjbCwvtcdI)zY7H>~1!1Xkn13Kr0LH_Sc3*C8jsTFBiCc|K3C# z&-1M0Z==BZDG~5aT(VWGVOWJJ5gpHr5k9^eSB_QVVh>h28NnLKgI(Wu_n;mb4_)fZ zzbfS|_;Xz`k~K!r@Qts#u3cPPbptTwRykN)so7QU96uLSP8BvOwZRg>Y3}OE&8_jw z@DSmGgSrss?}UOu$OUS~CX(z69O#e&as>anl7L`gQj&kZDfiCls+n7&-SCqRLVri- z>#NeI?Lsd2OG1f?W}1ii4sOHo>F9JaaMK8IkTcO;!{nzFI6?=oHKr)MAIpqX%(%wsz>b0u^qQT9`?soVk&1 z5uwp@>1t}l3pqJ$A9O<5RlpOX_lf?fXiARaQLJGT!{MVMeP^ujzJ|>Qq5IfVzg6|w zdsHoYvXAmz*Mq#p1aGw;4A-x@zf+S#=9)vfXaI zx3%(zIs=|F+`}yRqJeZXYGhdQOm@AeOLKZ4-H1aZ&a{}h5oe-{8|ym3+++K$;m+c90i?v{9#KR(aWhv_YVdDPk?Al z<3p1P;m$H@?E5K?l5DlQY?-_eNLTxItE;A>g$jHUel+|Nf{tNY({c=7C?@6Yif_;6 zW?a-+d?67=c&Fl|b8s5#0hw$OoF&YKj7yXq`Va&_9?cD|8VQerqzhV>J(SF4lo8K9 zczLKsY$;yA_>dl0@4T<2)aCiM*Y2pMfo82)TM` zp|Cw8@+D@<6oOTcHK4URwR(iLwKJNZS@vZ{s}j~QB)Y@tu#ycnjiTo*0OnvIxi`;$ z0nL!we7)7OXU}>S#2>?o$=R#E7uYhlo<;He$?3#(*Njm93F{#OV*Bvis^&0KPS3nz z=xc46a?t@;MBoq5Ws&?*pzXNihaeeHv&5OE!T2+&tq9Y9!7GHe)Q;3$l+mnsj+JK?;jO*Ez{G}O#BTm z;swpPPS9bQ|4#cC5Hy2Wi~*&1HTO90Br(@)dNh{(TY8S!^f8Va3@fy?yRFe$U<}c= zj*w~Rb1YS6m_mJ*>Z&y$vBOSS@zC@zrIy|p}pC5?&q=ZD`lTrc?S z5kR(Rr2>f7?XUjFItM*PgW3K#J1a5siG*a@gZ*)dOyxTT5n*56#P8`8iRW=joG=XA zN5@o2N*EN#2cXYl8h&V-(++J+5U&){X3p`s`I___p-qi{FySw*FZ(asbv|d+%S-Qu zUBe?4=c&;ClRgeDTMhJxRHoLak!tz%(rl>$b8bKUrc88;hdqQPzP-x)@StEbHwA<9 z>#N?BvS#~SjLnn7An6t#>}y}x(nZy+2-)#p{t&ny$$%O)DcO9*-PW_@?(Uw9^@@}^ z^Y5addpwzds23|SE$JyN!6k^VEg-s_$judvC6HNv5mhN2F}|RVJ~aYcN7!ylP(kQW zlZRqX*T2v5uU~Rb-Qm-vDIw^UO#46JL&@%98?@P?Q z8yl5F;7%%tJ@F4)3_Ooj98n2uLRueI@txCQe1Uy^0kqyjj4M!Z(z~jFCBaBz`+@{w zLF|xtX_qRKGPA(R!C|bbIx(2#OU5;9?1u__o}fE@e*G``OmN<3VSAXN(Lt1<5qCq( zs5Ty^#A5Kg--?MyOMR<3d9{VA4?PUnkp>YwW%B&T2K%{PlNHP0C?x(cR;Z^}{Z?~4 za_q=T-AbQF^{3SX8G3FVb9%YOH*>&M#APj@V~wM$H()0nT9CPtVT{7ZxeT_2R-y(? zYUE(JL2v9{xR`lroEwf;|{-Vy^&apu3(+Ua=Ep%RVost#mONEmH1nz^U#jtVtH3{+b4 zn|H2AlqLC1JO><~yfn#m&=g9luycUzKd=rBwFHW)>vi|03XP16BpCc5?OfdJreD8) zt&9mD!38b_h5+J`7k|U)x0YfGQp^EO5Q3#$Mk`Qqh`PzocQCPm3Yw@R4P>OHKc)H% zFROdcZMT?=+Z8D2QP=Pc%oRS}y;hRT>4CPuRyWnJJOE=F_M@%*w%(J)wS)VGGDOE zOP2w^{#wEy4Tr;CZjN6|ewv=rd$>}d`QZcPI>6&_(S#3eL9789=;n2(lJcCjyvGrZ zL@3D-^1D;-etaSO(&=@#{o>+{y+>&X$Rk-PQt7~0xbLz;!1x4Z{ZeO?R(1g3FTfA7 z-7ETW4>EeZjntax>)^%Ag-HbN(6@5#$3e-wbyb!NzSw@ z{v+8#uH}4W2`=^p*4-?jEWz$+m91aavO_oUTt;S)beMj+8I}?PcAP%PbkPgtQMHg4s(&^j?Wv1-ts{fv)c>3Hh)))BJp zScXI)*;)C0`#r-F-#g-W@U5STM7sIJzc0Z=9ufiMyE-SHn~1@qb9_U5k+u8(nHGHu&0+_9(${jX_f(}aP- z*U_z!IXW*li;R=_)eJRJ@_z^X`Qr7^c94^9WCBnB47s2*wZ($?pmekB+~%8FwGxFr zwddweQer7r_bI{#RnybR9(Y0H{-!b+55(OuB3yJ3 zaa)(HHLcnl?B{5GoxSgBK5epgzlH{FF#|b;Z8yAj{N6VP(JveMxaK~wVjAv0Ht-RD z%8a^^tDbvFPFwI7K$sKyr^9$pAGUH;#xNvz+u;Av3AD|r4zi^f>nAYX10I*`Y572|2hxBj_YOnT1ot3`|! zw3RZjUUYu?lq0oJ{OsAY85tRYEp|~u3z?D)J-EOY{r^BjrxX7_h^WuGy%^bXC6V|4 z%C4E(J@TQo<))>{lMy>FD`DiKxH1IID=0TA9>`8%H^~Z!%BiX>4<~#h^H1&`)qenO z)B)1w>M>q_U%hUgUAn#S#qMzPir7MN9i|w`7vwz1twk>gBIIcwD^1?Tp93J)=&c@p zf303(YElSs;MW)xZCuEUdlnE{-aIrG3LNPj(6jG)n%&yk5lepHe2~)(b#)^sR8&mt z6Hr%U)t-}h$RNr>t`@NF_?LD1>%sZILRUZxn!&pk;x{9eo;^i=lu zn6R5c3oW6b?GSIpzuCCPh{@KhoW(3|50M^Fj)DeD*E^Re6rMAo=%yTtvs&H;;gQaF z?{zFvqI-DHgi1$uWW@KJO)xWfHHs)oR;aSOTBDX3e)l+LL)D^nx#hB4#lr>gD^@(^ z>?g?|5H!zHB$<>DKcxlQ8hbWUTh_L{*DR6jC7pTgR;ZpSN7Fj6Wt1@veYZUrPq2c2 z%hImA2a8IQBUtaO4>vKb6|hQ+7$g?jMq?iTQ1z>*2zZs6S~2DUgb%9b2NxNtW^i9H z5Yq4>14G)3#PBJe9Vf#flT%I}hjhNpLG^E4@I z`YqJsaRJXvWi$;d2zceKjNMmbH@|BQ+Itw~m!h*(BZaj;YA$I#u6XrrbLKySV6&HV zsirCqB-#xy0)Ms>BjY_Tb3m;Vl?P;EHU@k2?N5}J6n8VFyBr3!k@K5jooAJev*o|h z?t0;{1>qLAbkm#<7TI9MH|v4SxP!$wGU}kP0Q0C_HU=nczBLb#&CDH-lISzWo1_vmyg>;`tWJe zH|{7X0CC1D|0h**x|1j;a)ETiq4{JP=9I@~wkQB?2oKvIBb4E11&*7%*q!kn0<3^pos;GnUfuE@*w%v+4Osj*z@&YPO z0}XH@&mSqI+;k@~q1L*bbPMcrh8s{%$*oE{aHF7L<66qQK$K2=O}W(2Sj3f`$cCBR z$hODv7S8;EJtt7t{vB;#xE~JGg7!b#^6T$V^MmFAYk}Ze{i`WAAH7NVT?wOLIK@oE zH*7FKJ+R>qnxVwa>;z7+PvlUffRa)j5(%xUJWKagHui7W=~ICOsY_(^I%o|>AAK}B z&@6ukdP@Fr$uPJDydI1}fiIB1u0sOkLjoLp0^UV$-Ch&g=X4-11#|PUyL&}#&(D|O0T(_Cbtw;eOA*xO{|OTKi+0y~p@B7P{rBALe?;HLq@Tl5J+aheh(KpO-xB9 z7V^3M>PlE&oSwEG(+5hkPz`RIH>=!`AcMyCHxqux@_KJox`G?Rw5nWPb4RcK!CcoiH?M3;o}iO${SQh~QBxlZ@E3Ng z-F{%@q;A{b(V_XPNQVi1_!jQ-xPe7Te~U3Jvwv)SH6Cm7;#lMF57O;RK`rMw`MdGmS69 zlI5ATQ#~?=`O2YHdOtTT2gezSojglamN4l?o?aHRfZtW;d_A9rk+r=xGy~Se#KadV z^6Ks1{f>@lsjY}|oJL9$2KI2EopZrUXVb+uS1y?nH#6c8}hM9yZZJ6l1s_a0BH=;Cu+*Nt0 z>7{Be=6lPc(5I!PCDf0IwYCQFnQ0K1!Y}>T{pUMF#0ai~IZB@6pTEATY@>!^(fRAB z;Vf(Gb!aV+rsxfR=H~YG&-$PMZtVXGsnu7|Xz6mx8IkCyFS_qiv-FrMObgIFobzhW z2%6JTGwyfweqpT2mLspuJbks_cLnD=l0vV)XQi2@IBpV3-n4+gs5oNUHEt;j5 zUOXnwXBPBNJ`y?1ciaJ&my7rRoE@?BrxHezpnNF8Q<~W--BJ9At~*lt*XK9?o&24GtS^Y zOvgX8+ti%Kx3XA&s8gQZwZC52>`4nR&mWVX=DwS&*f#Uj>$-4TsxzhL7LSD^CORU* z6MYt%B-gEIT^=i!EPN?G9x^{akI2e0&;TK(S$Bm7;|n2g|PC9mS;?vT%5zLT89_2rm*CC1ruPO+v~lk32Rk5AR_pk_#u z^)TXA*~oQ15wx7p0S6NRnd;8Vcsue+6Sx48&)29WE&*2{e&eJ~bp3Dea`1~00w{g; zf4t8gNB$qqzB{g|rE3=}q9`B;*g!!<57I$8v4kc9A|TS67>aah2@n;O4gxA2lqx}p zG^q(4M4FV)dkZ}TNGKu6-4xF`-}`>|{&DAz{37nm-g{=vD$lH0&n3eoIvAnb?~$Y~ zubmy4oK35jHzCaIi(Jkwi7IXGNihn1X5zYSK}>qW0SE&0LrVX zlJ@x8w&Zr6{;b7AO_sJv)bP1?amKwKMP zNPhJP_!iCfR7-ys^YswEQVP@pfv=DmPbe-dyae)DBroA$vK(F`}XZ8+S)(!MU!gBNe4RM)!O?HyJe*Uluxw9TyKLowHXNjMZ^Fl15r<= ztaoVuTIpU!oqzME#!04o&(a_h1e)LQ{aar=`PZUKva#_WWS5XbR zcXhiexJJt1#fzzv;jCxHnC1Tk(QMff@gumxlJecZSI+fb9yS@pK z1-#j%fS&*)?ZWlz_VgLzQyPI|2Y0KLE`{j@t`%f6g2fEsne*AgJUo^?-}F)y!_`$) zyXGdgYel9yza}rQ4D3^f(UknYWEUn^zELuq+t)S8#6;)(3)qe7AI1#-?z{8meUASf z!xO-HSE=^a)@b^tO&kX)zcfNZ+w0Y?Pa#>DYJg`A2o0yFX0G$_B)aQH2*6BQAw#Zx zK9bpZpAl{OZv_M&U1QJbR*BJs*pHS%>;j#bJ$1V`Iat+fj15qI(ir5{Qj*$uhA#*R zOo21$If}vUy^Op9C5@Bg2`+6>k&#Ma?7nOaRd@Ds+G##Buys~2JiRy!ySm(De76qdc^5Ie|LEv17 zjm`Y!(TdtnZ9ob=aY8N&B`k6n0pBjs3&}= z=3u2aqx=P6jNL;CJ5y7@ADF7rkMC}m06E3?-z#adD3ty#BCv@9W!__4*KTR4hg~D^ zn`wZ@*O&uJunkIoxNA&JEuTM!Jbw<8O*C9QS8} zUHKj(_9QlePxiUA^il>^-V>*k+V(^s$gfSpk~Q9v9c*_R4rd=BmT88pCjooIW@n824{^6lILEsw4DQc-V4 zMn+O2v-m^iksBUfy(jtrL2{(_ z0;Prac>3z} zrjG&XuP43mjq)vwp1b*pf19rV_`2fxzgdvTcV=-b)lP>pDmBXIN;O7E9bXGR21AB* zogSa@mUO4^CGSvVJb5Xb!+M~Ro;%o%SPVM@=33Gsr{LxaXUv&d1-A{<-#s39sdG$73>*qFSaI-MF2kN~+j z(COj=^yRrC7%o7W!=YaUiyO9Wd2b9uIE3$|c04i>Qq;Gb9i|DINKC0p^#E|K^-O;F z1&~h)2+gb29#DVlkEj8Y&Hm;;bKx=_OiFh-z^bZ#@xcjqR3W;$v(zv$@KR`Y#k#bJ zwPde(;AQmPsZb}CyHBe7@{Ywaqe;P+bLgVr-=C{({TyM7jn1WXxM+L~Pw5%1G?En; zwO#DXi#^7(L3T?PHQRAdg3dv@x>7(oC%*J96iFMI?B;OQByn|1lU}valA?jzA2cDW zgZ0?iUFK}Pv%}fimfmxjitoalBXtLPY)$FTObc?b+^i;zgHe_EM?4s^nbHmFyfIad17-m6J>t9Pi zb}#Oxfx3@JHbVH=Og=^=d|=tG6y6}Gf8l-bD^b?P@Nh?*q7TSL1T@>o^h^d1W5AiX6aVni)ez^N}uPN+7^1yCku~)ke zJIx(K_Ktczcey9I1O1K@;B3(f)Y7B0p5MI8Oqzw}P`$AJBNmHOO;OB2L4X;U1dvKU zt#K}NAYSv?zXpkRe~{h z5#0U4BxRscNQfkYJXfE&yGJvgcgkoNkNX{nf6M4Jvia)o2oR_hcKv(O-jh}c7;?oD zI!nFGN5k%`KZubfWoW*R^|T(^DDF~p!|M4cg`){&sTBX&9vRpt-`JSsB9=S7D zpesjcm)MG2w(f$jcgL-2(sloUwSW0x47D00H;yh@rB|#%;FZspC5vdShjucJy%DmB z`XI`r36anP3}Jx=$kxtIlO?_PkU#R7VE1mF=|Ann0pa$xVynW2=+-3&0`2dWKM~0L zi?>qSm^f8Vf;+DOEP*v&@u_D6^xeNv<^<)J`N!3-!M7TDDHg=!q&V+k4NBn#Z(G4> zySdU*Ixv{`FI^D6QE+-h+B5_>Ugb@|=mHwBzrR0EL$E?5$%TVkeg*nD;|~}_LnCld z!d{ZoTfK}{c45c4bM=c_a3vXKqP=XZ_VY53F0zR)wWD>XP6y(KcTl5?b8;3M;O-w- ziC~=m&H}gg{ZUIvaDQKtpr=iMzMHk|iO-u~#;4q=PRF^P~Q&+GavwG5zd z%VRJ&a6_{@nO$^O{l>_+lLCyaWOy{Y>$@HIQ5bH0ZX2L7T6wkdaWODJ2}Te(d(Wy! zni{UWzZQ3Ut+M2C-aFDj5n%iixU9TAqyF$A7uVI49%tLyUvU}uQ^SoKYyQ!&biRzgc8}SRFacH(T_fF!;EWp_p=b806_~OvV_wSWM*#7{! zzzDt?M`|qeFHFoa0slB|bQis~5^*Gf?_{rycpSz3#BaEb`taNbDrKV*zN*stHG&&i zvU*Y_@~{PqLZAmWi}9ZK4PoK_!9mmHGrJSA*Q)CM_aTV)F)`Zj9pt?mX7DAk>d3nT z9Pj8G*qJ61lJooLHF~3vl%xQ^E78s8C@gKIDIStoJ-v*UkXt}9uzCn*5C5P3XsUS5 z?B(H@am&akeM)S_#`!S)mLWXCt6J!Cn=&61OnB9e7y zy|+!1S^nwf^L|#bua<|B~CrhoMt| zNG4<(Xt}A|+rO4L^9PIqI&&=DM|fhITAMV~gp=gG5!vOcnk?c)fk%1i<=wy0V)|Dx zcK7a?`xu)!JLgk1E4=>E_W1{Ctx+F7c-5cNZOShwD5#xV1df9RP0YcIX|O8qM?Obi zyO~xB97uJ^UA6_nijntMc&_oJD@WEHKDF>a)V=UN7R{&f;C-4Okf>*9?8i8MI;5jc zMd7Lx=||6xTL18)wA{@9SO~@kq6fBY{DIn7W_qSSTYs`0z??O!(pNB61AVso&$Bx3 zfwwd?bvzY6jnxK#0Lu^T=I&Z7bIHjyC=mb8g{ub_CNPM|I4S)I^6$zE z|GxYm=DfYX%D(EG%FaCPk-001jyLJHM77^vxx01D^VqSit7gFFXy>F8Z6P6T=6=xP z`6vH)g0ED&|5In0%IytS0MEn&BJeB{jVxz9bGHl~|Lkn+-T}Io>H(xMsa=GgN z7F>R(P4&Aq+j^Z-l7F9yDR0A*-ZYpu4^yxySn zC&d}K=NX6F*4%ZN+#6(9zYk{de5`9N+hVUm1Uu+S=KXJ((M# z%TjM&Oxu|9@4;X=xatZp7(7kyV`G`l_V-!ovRHm^JoR^9LLmxm|5+RC58t1bM=CId z&CRE8=4(9saG~w?(MCmnfa#n4EN{Tyrsu!oH#UArbtdOs(9ucYLD0W01VA}S;FOtP zz|&_)iP?hug2M(;QOp2-2f)pSwKq;&Rs_5-|DTwDg3SMt>M_dE|3So8tNqg?;muLH z3&J%CQMM=P1~=+;?Th(7^8>Qh7yb`k2ROQsM9(FAS8OaKDUfw-rIsOEX3wh8&{S}- z_Ak6Fd!hA2`I(lMi(`$v^tFGUacMDcmX=-*y}lW)c(pA->f)t~sGmOH+jk?Q z{bqXO;L?B;mVVo!I6x7-|2gBrFQ6Bet+iJ%^Weg|J&>G+20X@>-`-(W8?>mAOc$o` zFJY+i+|%+jG~17!jdl*qyp*1tXZe>Eph4|JI5hXRf)|UV0qWep(E{Ke?05Fpf#EV2 zTmM2~Y3UaQVor`7u;l}2&VT8 zDn>TrXM#uP2;1360rR-egVKWo13;X8_R>&P9K+3g2ml%$Og`XY!~Sc(%a{* z@$RPai%j*#|2a6`=@<8pB{AbHSbgb*FaQaa~Jt1mZuqMD!T)mAeE$Ky`C3p(ta(K*l|Pr~w@MUL2>lIFJ+LnqGs)aDiL5P9**^ z4uBc}`mUqwG@Ry77;1Rw-U0J-g}=77dYpy%OXBcKF_x%p#tb>lc; z@9(tYxAwhm$5>{7hxh7LQBm%x*E2IN>Y1VgU4JA&hy`#7C+a%F+KAO0K>aGi9-!ut zdV*wJT-m$H<7==Fhvu7Z(cFPw%CU(g>IUy5YgY2Q5F989cu>jZ8V0z8Rb_YT`JkYV|7k zj^+o8#xOrGH&xLLpkxoK+VuCuS zA@;~9t;n-cOT^=E`E1I&`hg@$n?2mL%It{CABl+%9)Y(APg@nmykQ34M5=6wFg zhzO=UIS^>Ha<|kF5b;batBpaPTVC6>nBBjB&*D8&?@a2?LO?<3uL(XiN!t4 znCr?U!NGe;USs*G*H_e}uA{CNo|#;q>q_8rBE0#h%i-aId*7?Cj86hDP0s}QGLAa1 zTh#e7ZC12I15&%I|ub{pAFMY7Wc&1HINa0pK zuurkI<$1Llit4d<0I1&dpP4)ox~9(fpNdJa)>Hr*w8*0p#13Hj9Psu(Mvg)IdxzCJ zj<)S2bH^i+;NmOVY@lqWwe?&ikE+jhSF(U!ep+Fnc4pVH;7mjIu zsN$dUAdujSqB<8qm0UQuq zgT@y)U}FJtx0Ac-=(Ku1W@wVVYN0xd3PUgb4e3RBjS`q$O^4R`xsfj-%uH z$3=j|4!8mkk}-fG>t!nWTiI?Llmr~Gz>P_4{E8T+mw>L0&Po*Fm@1{J*}eBbm6o;`|bUP4QIi1B{qm$wOh;TO9fD*`094_u>C^p_Wevd zB^eoD1wYI%w6MAGcLYL1!?dUMgem|=-ETQL(@MpyrFPCv#)_YS^hkhy<$~2~{vXwY zC&Vs!Rh6WTIFp@eW%yF21UHBi)E^TObO{I(6wVH8d>eEjPtQ>v!R zKT*fNQKx4MO1UKCQ}-dE!e{ILSb{T`!^N)MD#6d3*A1a=^|bb+`Zt7>-pi~XP1zq8w!msx3rgo( z%X$m`=fVBgnt&3$HaXeDnt9d>XKYEP;r2Hk6g?D|nI{e!`N{zsLnZ5ZO}ZKv7lnb} z-x2gA z%kgtRFEM+u#VnX(Vimz9ZZMcfGqnU`=WT&4HZ{(~BR;jlD$1T@bAqn`m6 zB|OsT1b`SH(xym|k+OxA*98y_ESBvIad6-F9y=Rtv^~3~3BcUX1Wc&k7N6!L5FF>G z!Oy-At?guMM8^jH1kz}CE$y*SOn~IF&l?Ivqq4?LD#bxO!huYaL0o>1SQH$;99>M6 zdjjM#HPzc-PqN)}Y{Pg9lo%tK@9mX+Y%66vi3N_-p4=c-l|CwgHv?t!t6?WNIw3!c zLg5Mb0>C%%9jl&dt)clqrj9$H4S`mb-eOt`Aq?;+jQF7pb@7`MQlgm}Nx~33_r>g- ze2HHo@TFAC=e4E`Zp!Z;DzL7ZG5{-FKy;7$l70Td5~NaQvLSFrQ##RDlcj;3Eg_;3 zt;ZNq7Eb)SH;`z#?-z`7e0jNYo@8UJN>biCSi|lPO=<$KSf(+R6Ub)s*1PJqwj&iQ zp&qK}qF`LT@xUJHK-J||4B=Rm*w0I;O8=|KiV`W}a9lrkxWuc!?6R5&lcpA7L8E68 zVN|)b^%EYoJUs&eQ{m#6iaf3R~E zm-*{9`jMuE1Z%rdp1HBLQ(pbG!TEU`J`=rSCm2eaezKc)q_3>|9ykm^JCmE=_7wlS zrZbW&7%0-)^F+6zytsC#w-3)MxzZJAIGO$^f zYps~Y7zG2g6fFkd?HyoMsbTYtIAh{KM^!K#z|F<5=WNnj15OpvtiLG>oTmPlI(ooz zv9S^aRGegL)ApV|x_t54{r2oe-RpwohCwM`4{>>%CcR=aeU#{}OeJ3uwP=ZXAM>>r zDA;<9hn{F~dQV)(&OQ^;;3ulB+2@QHV^5s6LVDvzE}GE8NBUNIlT0dqM=$YmrIvoJ zGt_>38}8Zqj+XO86PcMQHb}Q(<&kHe#4vwsa5F1wv^xLD%R-Mi!&6)O!4Fy#cv!n4 z>uue{j>#E`e3aX^={Fo@Qu`DsqN<{ziGNc1QYEVt!kE4m{NPsSn|i@zLK47%o!*Wv zEbC^G{=G{-Z1Q8C@VyWyo(~j))r(bFWypF-neXiEY-AIJ*-=fYXdo=jf4iRuA{O1O z^FAVdnJ=hDY6HmX|L)-n!)e*d(G( z&)*};W%trNU$7#m-5!O_xQC% z%ktrII0B#`Em&Yv6Y`T)%Ks3}cCpD=SIfujhUI*Pf({F7^>>h&fz6(mba%IY(}Enu+pd}b}QG{?%SUjyK7CNgva^` zL7o96u_%>V{~hyP6)A8I$;f9ru%K|B`!((=?`Uk*6}>OYDv(^ z2{xMwJ$H*a5c!*|*qr(^q`o+0Ch^p#kxJ98cV$U47Uw{v_@1o|!I)xGog#_z_Ju6* zp=S5L>&Oa`WI&tIB(_^#pKE3uKH8c*b+qV51+xvKHnXH1W`>^K6iGj88CGUb3G!rx z_vKh_2pBlw68f8OXT5HSR9Fl0KDJ3G*TlGxVJYg6P%uj=hqUXJwz^+)aSG(o$sI*M z?-=GQ=2&B}o~{|RPo#DQkp;LSms~%_OV|xmSa;2+eIzZR#eCY+gBPOT>^X7L_x*mh6JF;>5I10$Ow+=5! zet#uPrJr4x;_YjUd}7qNtTh~cmfj|#xL26|SB#*4HdD#-iZb9T;fC%cZ{{)J`0(P( zvleN_>{q+JRaQg$E8ocp-;L-^<9siiEjs02A^2_p_Ft|vP|f=JlQPCP%8}cQ4}qh6 z?Fl$O!(w}=Ii>-n1_tMD&qH)`FOnLzMVOf^O$>}*ws4p9Dq0eB9d zadAb0h7Ix7Q4hfauwkEzA6c20R31P5Wt=$DovENOAb`^^^i8o$;ED~T{Q$eb3Xl3_hllnC4`0g zHp*7Q0g>wt(5{3%amdMQO>_WA%tJ<0KbnQOwGM1Nkwq1A&8IJPx$e2)W2%yy>vOr1 zzWzVqVuFT_JO5y~LXY$f3>2>^hYw4E?moCOW2+PO+j~@_wSB2j!X-R2nM_}~SB14u zP?=E}7rA~-S;)K&IBXCr3@_ZE19m(qmUG;XwFo2L;`Qo>$P7aSAUmgB2j%%WM_g1i zeot@ET(O6=C)pP!>uhv&iFS60a4DQWi3O2}+alZm3m|lQ$nqQ^cLdrd0Gkhuo&m<< z#kpXt+~eVb<%(+Oc2x&iBb#en`Syk$8*xU?9b|(MkCdkX+17K+PO7 z#L*So8F_7_$}EDx?~+WFFh^YAhI$$eSsE32u32vbej0CemFuE)1eux6eRA+1dAjzw zUR*Zb)V7mhI(B^UuTL#{rM?f6y-1k1GfyFtUyY?4^y)REof?=OUJyCHnr|h197I9R zbz@h{b?qIv9`Jkagz~F)|4;*-mBSJ6s;+S4C~AGghLi;LHc5U>dLw-MRj<|w zr>pi44k8nPLAQx`oi-xkXK|tT)3y;Yi>CW7>2W#dbYSs-oT@w^V5(#ef6C+Ka+Vrc zLN8xSy~cD*_Lj`yUax3w@n#ka9S=RXE$-=8JyrJipL~qIX5mn90(>H3`ZGt~V<4QO zKgf`Cy?4U3-igcMTv73Ie==iezx;MaBp)Pt{w%DA@fU|f6Nf|IQa@~EX~XDpq7%`D zu5h~Cz@G1iwCP;3t*bO#?HhGz?DD?>jV-KJUkhSlb(@Jv@4<7n^X^N|M~^*YYc(jdO7iTeX?$io9Y?EcKOiUr z?cBMZ3hrKJxUHO}Xd(}iR6yR=tmC4TxJ*P8VDpj$NVuEdb#KL!lywr0;eU1lz|VW% zz5PC+s?wC)kY%Htc;Ux*3@8N))Vrd^B4u8FWp!N|KVAk%I`Yjb9UF7kN{2^g68{68- z0nvmx{wTu1ZOiR6_?i0U$u-*@yt?hl@lwyzdOmZ4usuvXUGpPeIG|?tBo4m0v?gze z8vlV4jAWyDC*Eyj*J5$)fEL*&u_#1X#xhM->kz=;k#6)AuA(;MVTMJm_v|Zp7lo^7 z2ROOFCBVt;>KVwNu0PA9Qm<;_k?OJVF4Q2~_C>=)DIW*yd&@-g1A}6KRhO45+Ev#w zCpE2G8T?5>BezJt#CdYWO@!r>e2GtyV70@brk)n45349JIPzDv;p1Do{lTRxx2vNU z22}pK1)I$(nzuViM0`BOF=Vr3F@c7ly;M#<7`S*cST*S3S*9jpS=_+3&&Y1t;@JLH z@O$2)x(g9Up0I}hK&rmKJ|qQeQ4{UXbS}pJ9Hsbpz=|3H8tK9$1eJs|{*^3k-C0~2 z8xx!KA=YV$e5&oT9KJqz^aZGkv7BmF0l2Cnj-)zvC-`nj&Jbb1z8%fIFL;!Detz-n zJ;&7yEN064x4gw`BPf=4?6uD75m}$GJr@sn9)a(~IJTZ|@!RwBXN&HQXv;bf*4AoL zUYx6hmiDNF!K)pJ)A88ouhu>;{qs2_j)Fl;*CelxsnFVH46#~Xc$bGP-sVz$x+0gz z$6Ox^15dTY7Xml)JRnCLyX}xg1gSg$nHOjD`12$_Ru-cAX1?plm%SLyb!#%*{#{_J z8VYa``|K=RA}`n9A_3a%&OtnMl&-q8=A3KTD*GT%Hz)=@WsGu|+ty0hI zJNT?sanE&wdt0Fs zB0xq^?m3OH!$v%D@89UvpN`}rB!oUM&=i4O>@Ni4Lbo)b36v1R?x-}!U(VH*2z^YwtWn?rAHzbE29KA#iodb(4|LFYI zk%~z6yh_Y_Hx1MQZhEx@3!Z@W1Y&`bX39ny)qswOQPO;-$C{FvByTzleQeQ3qn~d+SCMbd%oMTs9dOxi zqf5S+>yo!H)iU$9b3J?Vp`LmX(DcP82IaRboB+tUa{BKF&|grhkxK+4gEqM4@6F^5fuVV%9yJLaFy7sGyaDcm_j5W=GoT zZu#mMmQJzv0EgJ^VC($4Lfb;4?q|aDpKGpwo|{3?@RsHLDdyWW+{s39jWT&$>z zn`%^hlFQ7Hs6!zjfHX8mZ0ylO;TMvMChWFj3z8{osVI_Q zQpE8l+OS%^+TpAoJrmWQ_OHe`G=yrmV!IW_y*a2WN185g6t5&#ED_pek4!i6jKr7Q z^mG?cH*wenYKICKtT}|5xwclPg?!@UgO*9NHNxjnL|2JQoNeCMh(ji}s+7_5o&mZF zb)$)!f+p&W8A=+7&jJ=#6Uu)>w?C}+`ZiLwV>^fWIByQYHY_%5XpKpIo=z*b&ySD$ zyRd24BdMw?o|9XAXc_+RL2?m_W@cuSydfL>?nuEHjSxkB7_59=r-^#WOYpQbdg?Hx z5?=%_QdH8Ers7_^UyvTSt`@|-I~+7LC;9;pyX`?HVY06;Fi)6Ssay&8t9)xKTbzNw zY$IMPqrOq&;u1$_SokIXdkhx4IdN4_Gb7~Njdgr~wIdveUhUh{Oy6Dyi0N3=#N2cr z#uJirLHZUX*z}-LQ08cbkJmztrwfp5X`XT<`qU`~PPXQv#PZ(`Xk8fuqCKKV46{J6 zIWp~i^Rc*&mQLsmuY9Mr4OWd*jmi_8+i1o43Wt%>k@ITYIy#uU`T;R3(~US2{KvqE z*R;&mF|wAcQ#YeIL`lI)Ip<$-2PAp6$dSK zPvbPnFP5_n=oVAMXumVl9`!70?gEg9%Z1aZ2F6sTW6#I6R<09|EXl#oDT28>B?>v0 zH1<)d-O;MDy4MQCji%qa#MHV9Ro!psit}$ieCi>|B<`~#k)C7Z<#?5;RXwjI2Gon6 z$7ygl8^(plvH}sA`(drM_T-(RrOm+v2l)qJ7LH{DL)7T$t|M4-y$33IC1BfEf$)wj_X|@u=$?-kjDletAOeKAhBIqqCU2Bq=nA4cLvyDa^I1z zdOsDXh|9@|l50)LRLYDJR_3ss;?Sz2+x)7G!N^W!*e59$j(CZ{HVNm`s_(`Ft+7urdToMr4v-`ls|( zABp|cnz@{3>UANbyq%`8MG6^hkzDd3zR^saSTUCAFPh@JTe9YF%R# z-V)6A)?jwXvp2%R0gZ87H%De(5H|be8$Lo-J`1vN_Gmso7geS~?PjMwbbCAmxcP)L8 z2pgsdCh~e$rDbV`r%utrL=!_e$Bq&$Q-s%mJqWr|d&({dVPpI;F<%mkugR<|TxnBr z>h9>YjB&!+h0Brq+Mf(3vY%sOTDFY}2x#!0!~1{YpR(YpwV2=qdq~S7Se;aNIw73Y zCM}gyp*w|6BQtJ-3Kz^LGUZphb#;e1FOTCsR`PB4UJ+AUurAHSCJ_bOUNW9v-X0k8 zhlGdE62ySg)KqLu>qn{{UQa7pm*A#CmD~n#K3D>S*%$`H(ca(lvWByv1TGJcp_;eZ z9F?vOn=8upj}5`P@n>V6=9&~>!y-AT^Ye}Mu%o_8MDW9;m+ihY$={5HB;FnNKE;{5 z@{E`=&2YUX=7m+X91~uP(`#p(N?0=BjY20>BCHVrhqZUdk(}~ufbc;}2NUq~1ZF`; zTunzu2bdCFjJ6J8dqfw3n1|2li0cFgoaohVUC<#|QvAJoJ^g~;FE1mFP95+eaIB*PC;t0)s7wDwk(r3F5--c?+cfP1*K77vp57(M@cL` ziJNLcN+g@NbUUdj$!NE}Us;LfEFHeHlu0CS`^ISq7P>Mis6l6&khvAOPvxv5($nOb z_A>FuH&=>|VzRRyUc2~3H-|K2L>i@HqZqJ5)afQs5x69G0eNSfAskIYcRS9TD~)D$ zcoQAkbmM9vE#tV^_aok9a=1Q$$j!yhl_EL*={c6S@|*Ms2Q#y$V%gV@YgBtY+U`(| z*v9~?p&U9k(6`M=K3a7NSFNcJgVah0|3>2|rLQ8j%_b|cL;0dRZi0mV%MYe5QL!4& zKwU)7cBBBz_f@~(vCpr}n~SMw=^!aFf$WblM4}tA*Vgnjly0=x0!7g|tYg8xij@4E zeC6E@5fPE!VHuhrZl9)df$t^WR2(A}f2UoKs@Ukdavr?9viFwv{u&>tiMrl+Fxe|# z{WKD77=#a`VKzo;qvaxA5m5Q2X<`y4G2amFx4a~6h9tdDtyif}-7Sw~7GBSpc+=-+ zeHuq4piI#0Uh?lXw(ylB(hlmnnXB17PR3f_Dd*F+;{!utJC1v_B8ASv=pn49dUSO&n zE)$X90cthbSz~f*mtMP>hcZyaAgu7^u8E0CuTF&ZcwX=mIJfN+@ZczQhcjJC19pUb z95stM5JksI@Ev;z#u*52!xsu_h;LLzk&1HrPZoeEcLQzusszi{zhnlT}F!IjWH zw|l8`nS!^KjY7;;FN0b%(1NSMqb$1AyuA2z@7dba%GH+x1skCY&Scjvs-5HlPbWJd z3~Mi4Zzd*g+i%nfrETd}LvA>>2!&)|N#yf|Sn{5V$Kh{OQpR4Dm)mxxm2^Ih>6R>LH=Ak^^$PSp?Sh=-)%mcR^vvBK-0`16CVWFTJKDS)lBs-Fn?2 zu5lT2%}LDnx5b?Jg`~=`CA_%gxm-e%i7fneK$(mT*`R&HP6^X}=M*BtXuxN5;a&D? zPa+~C>&P?;jTsZC+8na^eUgAC1;vS|B|PkQUY=|pd_x-DjwNyO7kGqe#MN~de`U!q zNhfu8h(gM>1&?iaxwSkeImE+VUWUe;s7=d?!X=zzRsrkBP{RtVpht~$v}nB|FIcDj zNI=|_(OD~Z5{0zy{6f`SF33Ee8J6t1kvNJX5s|&{NBYDK?tDSc8Iv855H8^=zyM&E z4EITq@&LzFDdOWYpyDToB3>5WoDC}zOj;{sQc(1Jn;nO+eo@mMJK40h)o-C@WMj&6 z#9<>)qrGU97i@FE8i5c2|7DHn9qj1%V&Zp0DBGCxCcHn1T}SH(>6b0|uIQM!x$*+x z;X5d=;j$+t+Z^=2d6a25`P?k@%})ASt8JT^?HAVMiX@B}ignm!B$?q>Un&%HXzHyf5+3LJPv(V+FJkV=fYf^Rj$qWWNPYlM$HyGDG=;>W-`QdEQL#~ zsCiVu!9X<{VWW?u_-VuutKJMQGnzY;yRNoaPoBPu3}5$_x^sG6p-bEK6>tB7y4(^k zWk!|~7-e>Y3%WW)yX-Bp6y{gDfec$=rEo$l*a+RV1Q~5Y?{<$gnz?=i1<#=@ea z1yUXDOc!an8*V~h`!!9Z?rYldR;ccI^MIeak2t3iZ#!c#hlsnZWCyLp^Yfk$-ea9+ zjhG=o$@Sf1$@E$1tqsa>leme>2wZ+eOEAm^jP@i(7czfM0y6U88Od(YHvjC`Thr(u zr%KP!Z&2?fR5bf46jLP&Bcs=2XTfO+T$SVmp220a)6O zP8xYz)zty*vi^)z36jAQ``vv!e=%)fjX&Nn)H&knG1`WIElBI(b+L{#2wATwn;Dgq zcU00x%9!tHZHOZQ+kah_YlwP+0IByAKJHt+z}K~)%KnvJ6OuVWaI>WxJ8^hz&KJHt zN+$<8f)g9<_>3!Ll0`yMUw7B)eydVDvm3&^64u~G!sVf+NrlwR3z9@PS0+u5XKBV~ z(ATmeD!Ho~;QW6yU;y$q%T zKMIYm1=(#ko}#*rO+Fb7Sy6>=>tcFw_mV%h0lFvO>(`_^FZl6f@?R1k%i}B1UM<6) z92n;cFsQ$3g%HKPo$F+I6@GnX=ysC~?``jS%GCOoPiXg-6!2u=C#mAb(8)&OZ6nx` zQ_Hr9-USoPXKe7vxSlSbr>3biCR9=-H#Na?R2DX49z3LoXEsl1c$9UZlWjm;KNICIC+npy#;=l9VN)|kLi6B%X)wGu(@&;V(D zeS!lMj7n4m zI@!i56?C`}A@O}>-&E`lPLi|r?aVL=5vC#o$#_u-rFO|{uNKg`b-=zivg6uBgJpfx)|j-BBR=vd8wm` zV(H43fm_pkX3nM(Djz#jcIzt&TLNYF*yZK}E)f&7#s zsP#E3&JADNdj{>&IDu@ffZ25n+wm{4i2596a&^^u1_pAlvpc8p@8RcOe@+fTUwEUq zZM=$hklhSB&jmQbkHtg3RB2q;Nxc0Ai=yCxG_-?OV!e;!^jL4Bafq4GFNR(2JdmH2 zkW%VSVECEJO|m$H7fxnFfO3JU75X!w#B{`DqjIY{yAt>KLlxJQv5sXx>16fWCcWm8 zn@-zJT5T4%Ps{ewl+xRdB=7bO?Md3%-H`Sp-a$VXSDI^cp$ocN8$EK?nKRKX*sSJ5 zj6s9HEkX$+;DyFkQb)0)p4TQR*7z=7Mpu&$Z9bd5;lF&~i!nn><+<~MmbO3;h)JRp zl3j5Z;{|0a7H#iMkQ@5J-ENdxcZxQJbZTQt7QdcYVXdgGW?`#~M0=oohq5xa$ZRI$ zysnB{c0_Wq+KHja%&k)-1I`bXWQ}6~t5n;fQ^}~Z4O}r~I8pL-BD<*1j^tz5?Lt7V zwR{IQa{M?Ykv5de%dlZhQ#$X?3TSKP+F~A6Yf6f;L`wc%*Vqt}N$i1l!*@vS%(~tX zsP3Rbx(kV*t8oH5I*0Mdv@SWU!na;RJu# z3%M-EN(^`d-(MXPmoN!fUi4Z`I;Q!8h0uMws5+dNu8WPl5Om(9GA$Y9v0U>y+DC?* ztG6LfEcyZLdEDN?rf@#zVTUZh`H~}E2!6UOW5s|XFRXYhu0NZ#2o-~e6Q~+-tWx7W zeof;!tDg1QOv323cWF4Uwal9x$&?>2YA-&HHx8{VZ1qv!uuk^E<`T$me%fk;=@2=%bS{tmQG{_Aq(&q{I`<5|PUN1jhRqPULV00n5!&eFZ z=7QR|O|mLsiQ}UgyWP-|yF9)Myqd7R>Cl>E9BL+}W4Z20q@Rqh%w?*5k9gefsk6|9 z=D6^Ygy9{ag`@V~Ztr94xo_M)+|71d2Z{a)ZC9TjNQXsl$io-gIWLjcXxF;5I6da+ z+-f$RgfB5Ed_Rur*BGI6!35ErBe!UCMTdyU@->T0-unr?P|6d*?2EG#{gsjevg<#= zw(2uG89hG)Qj}{yl+Yb7+r;zXc8FH~J)>@TxxpS$L`F1KhwFNYx1BalmvANz1%x99 zt?D$xp7B|DHBUgqDax&7#{LdpFea17=QlXo^lxwEv7n0DK~k%2g6_!_NbUE5(%kSy zb&cb5Uox!GTQd|3@8eJpum{+$$6Sy^e%HRN1~Z-cX3hLoa<#Bn%xk5ZlaGOncW`z` zO08FeFiCoZZrBqPPCpff+b)L|f{gz>2@Or^&2OUxUCbGNBS-(>DPB6Yae#Tvh+aY& z>+IrV0Vi-96+T05U$$DQ0^UCT2t*_nj=D{CF9pfDwumdsZ%T@AdHsAiCMhDq_2KsY zIhW+gpFaZ_NxvPEk;cv3Yhv2`TwI1)u5t4O8#FgCt4C~C0P75m19@f=AyiVY1`JlwCT8f>MAK;!HZTI;GKmIQWV;9Fj zman8WbfALGbNOE3ug{QUC3 z8rFRwzFjSjMPh(cd`~`JEj0bly(LmR{-yyD*TT31f4QWW|I7vTu#SJIq*7LO5y$g? zDtim4wzjQpm~&bxNGSyhEmneiaVU0Lf?IKdySqc6oC-8}k>FCKP`nTzSa1(g+}(-= zcl$Q&Iq$jmz5o5c@vV-Ik+I3%du92Y^O?_s*;|(9pE#x7oKCYf@mpP5KMZj-uvHJ- z)N;#khj>Vpst{vGuEK~RF2c5GIb_^8pw@Qzy)E=d0QUKjMG)QO2)jXfpC3E5!a-9; z9xCBg$1NNudOX+tqpcqPs7$lY0n%_LV$12PkNUZ_>g6t-iBFHMjvo|dudLwqu#+Av zo-hwCEarrHL`bzuhfAb?EJ^!0_XXZuRB}$gfqHpWuFPUnh&x`SWd(fv7+p78yDpqb zy>U$xuUo8D&v(5$citXR4jh=AsYg}ztNO1#{W>mA%@KEQ#gdG#sS<-gx6-VZ?)tx- zTy}G&D0#>9jYj`nW!AyFEy*V)PRYw&{mBMKN_`bu-4G;7>D4?CYWht5(|QSY@7c1q z-?9e+eW7APi88eK?aeQ!ghkh;S^e6o45CJ_Uzw5x!kU_zVLt{&*ONw$I|+`x*rsaU zY-*rZCpjPenz4HNs_w>T>s{FmX^=)HCom=tEc7}7& zG^H<$P^2JaE?O@weVT;oWiEMVZ7j8thZoYItBIdNB^$R{l-D8qEb%QxRQSC=$8Aq#v!OH#%{=Es9S< zuBm!3Q>ZypmiH{*!&*EcDOlP?K*nrAdR>?ZNcp;y_*IR4AJnRukX`Ll*-$adM6$q( z{TyeCu9CWYmth4O|LK_9(~#cfYPz z^;TdonEtB|e+@b_Z3AL&P^&06{i2|nPOuDEwFkr9j@9a=EU_Frfam%)fk#J8v1Y@D zp8H+nEut$df3AU26Fhx1M#xr*ODYWm82qih)Sa_rj@P}~X@vSl~ z_~Y#YXKcgopNwStdKLJdgh{=H>nnZC%(nCN4s)Gzy!S1L)nG=;XeFy_SbhXGPIiHR z$H4(Jvu8&;jyo8)Ew(@d;-=FXB`#1D2oh;$i9)Zr4XJN(6t7#0`xrOYp&%J{li$pi z9m#!kLJYLk%LUXv*>8{*`xdIujBmxnxViAj0ajsO59@52z1x;Sq^V(i9I~73)1(Tb z#!Ia#6AsI0jp;6Mg!C|Ec0@0^yjW*JAH|G64NOh%YwJE{6Qk}!AmYfv2cg&Lj&{7Xf`xAPn2Q?Q?LlDJV)H1 z3d+%QJW2Y3x&koT&YS5OEDJiiWcY)AZ)Yi;T>d(PC@jk}SodCg-sZMks><(YZxP(N zL|(W)ty`hN|LIdQ{P;Z{LUsuv=^~Wp`S@}DN)7I;Eqp!Myk`8Mpxf+PW>jN)MomY5 zcD*Lp*kPs)H7?~6!v;BPiu^5YYe&2aO91p&xUzV3a;BdqS4TnnLmhjSRLc)FxHH8> zNwJ>j9UtyFE)_5B_-k$20m}>?aAKZKUf$Uv_-cH;vAz52vHuC}K!*1uJluhEBnq~Q9qm5MAuk8% z4Q^VOA|Nce&x|eXd0=Ly#0vpO)6=3%rt>a>f6HqPp443X)bn^I*=E7^>9lCBm1*#B zN0eQDS=CuZaYq#R>L?DfueBUU`9#ybe=)DiaHc^nJo|HWLA*gsq|E{h1~&b@6DN{J zWmfZ<(`vF+X)uGWkJNY~Jb>>#N&LB+wnf;ATc*&kUuWCx{_GqiX3UBN1|yb@f;3t^ z4qX`v4HXphq)S-E&ZM^uX-zD3I8F59=yPgU?`9jf?N6cw8Sp|7$Y6?^kGeHNiuc?! zc`Y5rTbbpde%|j$5Eb=yk06({?fV(bd{F6N^W(hb*7Ec##?ECwm){(~#+lPM>j)XZ zl{`5!@}?v+b8Vp&u=6W`|KZ^k6%|Jhu6JAclc_H*n2y2X4g@b|G2*i$GyTB7ks>!1 z)Si8v2Zw=O{g_WlCMt6)gL8b_S$7g^>$nON|0L3N%bs*{^2Li6)iuv=s9u0Fm&m;n z1X2dS(rH{_3+X_BTkcEATf97_HZVwIBMY2NRCxw!-J3gmu9-PUW{jB?<=}KE-rFnX$em7 z&hHi>eDcWeNvA>edgIOCdOUlSI+4iYnL&}8 zUrVb*!Tquc^twD@Y_b&#=KHJhkGln?`55`?Clu+jNMg*A?%Mcc$qf=h?fr@+f0y}| zm8cz8SdjIttTrQK3UdTb(zIijA%(bT#j&NNxd9dz3bD%3TkJw)+dZZJDORxKb!&na ziP=+#Dn*T!s9<}UQJwWs#xRM}qj%I|kuPPK$Ey2TJ}peeA(+;RPFJv9qp0+%+G&U^ zbxO*g@s(&L^FVr%5qW}^;~A%})OxiU-v%VX@7y(FJCAP{W%ZewyPXl)8)&G1VtFWA zp(wvXzMbM&XZyzIO?eWG&)mL)TaxI>qk@h7f!nHj=0dry7C*n>dDKL|aa2VNnu&rN zuMbD0&z@cy6BT$Tl`2p$_m(Edj3at*SLoPvZmM#Bq_#HZw#S&MOGj!v3oMv^lPrPX_%*gx*&fi$&W#_Gb zJ$5ql_u(rHQ}=U0WdI52)5L^A6V$&%DE>^k$9NLF5}aRccWg_-|FJu0C3M&uVlh)| z)2``#+C{o9VaS`dEI7NlLbEc=QmU&7(~eyfymi?9JkCBz^K6vGv9w-O+lqHfpJq?i zf~LA{S}vKH7TrWx#VW95x34&3?_LLq=Y&CB6;0$4t)Yd@@o@WPS?Aay2t;o+{{t(& zMnF}qwt*49r6r@*F+^{=k9JsNg5LJ2V+F?&>!p0=ej9Iy4Ba^EI$Z$XtGx+39_ghi z6hqF?Y@KhG@AOm5@}5XEm#e)^>)zb*2xmkM$Wro6xxcj=KMfx=Ac%In&U(2z?t(QR zNyR+*iIxu2!>@zTink}X{c@#aLR1LJ{XNodvaD!KpnQ7KhsU3ib935i1)#@NTUp18 zlqp?awfpL_rgg-t8Mn0L3iZsw9pQtlOyF01UdGDGyMS-x9|TRPZlyM{OAYqoy?mZ{ z`~4;CqvAI`kF;|h3n|9l8{jxxFTyAV$1)7ZW3pdSaaR=yD0uJJ>Z=? zCWUypRztqk@C1rxw+1ZpIS>%?X<*p+=ygj&!K&t0i5GI0)7ok}BBQ0A@JJ$XDt#Q| z2^Eej|L_mXm_WaPstoN^d+uy=hHZ~pp@T%6+S8vSi|U`vaAYJs@62S)O=Yl+Yu>J} zciGQ_chpJj!@kye@KxH0!)-eE{dsXECiWBA(GoifS|jB?#KgHM+Gk2^QULitYU7MY8&bA1}n+^CQCtP(vpSw zqgqTlDe&`Th*WgtchH?J?uRYUy36AQL7kc^l{Q_Q`Q4f`;$H7M*&apKoYCt# z(Zq^`RqV-G+El1K*KM`ZRhxV2=lRE{X%1PMx8_2z^m}?Q)9!lpg@*Odhdqw|BTJCw zNa)?Hq|0;#JQrTD>B3jRq7FCB zc3Fagrv)q}^;{ud>gl35wIF64qdELgz=wKICzCDI7}QLQM;NK2J zc~Jj4k2`=AkK#rq4Xc;RavC)a*5rB~VMjwkiyUxD3i6nu6u>PmBDT+-X4&<*)H+Jl zu|Z)M@^~%}_^0=r|#oYCaWpFkx;`N%%&g*1mcE~fA$vg@Ng2=a|M1r8G@X9GaogJAXAEe2$ z-+n}~l^*f<@`F5A@{`+2GH{p~{&PR22?7sr_jT{bneqpE@B|5?%fggK6Gc|U@(@Sn3j9hX# z@*^m(4j($MHZ#2?$(X3d_81|nFo*q;SaKGrGbUE}V7GUh039MCpH)d&Bz7yCm(m#! zp5ASyR`WF7i9dUh&fAHq|F9Txu%5iRK1mp{^a2zaut;=!<`0RX3H%HA&7tM_UxqR% zNEp?cun!1=q=}TZcp3)b_c{j_1`Mmvbqe$HJs_RJ4;L?${4Bw6jgfS&?cGm*<{@~Pw-|ZeR=74pd?$BgFih_oBS;Yd$YuwA zl>WeFYW_D7{|{SjK9Npq#OsMhK<$94V+7nC3&#^FSobFfFaS`nXUpO4n5gZH0WnYMY#p(H~>;IG>nnnC)SejjyD!>IHoE zD({nzP`nw0YALs*xlrw{{%|?e`iueE5z@I)eCXb;RlPk8|NK#&>T=$N!tyhNa@sR_ ziJ7r`N8U!JMs6_;>qoZ=b(C8evL4&bCel0vbng}2%X=_ZPF2bHkCOD%4_&gKKZw+x_J&MZzR&bT__D#J+|MjI_BhV^=kNy+ncgHxaBj2Z{rpDn%A|`D6 z4#${nx{5}5K6-F#OY?m%pnGfg=0DtR#W(J@%Vcw+xGi@I@%a~J8zr|ZJmVL`ewWUY z!AQy8M=dizA#gRCN2&;(6)A#;;XIsZZdY({W=0py$1!fgNH)I8AlPDn*uK;F2gl1z zt$IIiXc64eS)dC{N0;!SZd3r^iBXijUz>iNGe5eXm*>XP0_gT-c5=rtx=h$4*S+yE zL-~oxF5&wbblh+Aij{E@eoqCN4Q4^#uPyeX61M*4Z~&_6t9TS?#Eaus+|@>(u)=`T z-?;kT@%5}`?7x^x(zIdPp9J8to%EjpjmIltJExehsCRCM618g z$lNnT?^NzKkKwq6UI4M0`G<#Uh_uw_^auWi|3LmSzh!%)XdIj#m=ZQW7cgrSd+ikg zgT;&aol$yD?SA3(>*RI3cRT~#o~kEWvewf7-4x~S{l#{<6(Ymb~uBrLr)_yL1P7e*Cb2e{&iI#PwqTXJX`HRTS z0%tiYkYprrfXpo8vxa93ISGOw6Hxm{v3E!>@~b^rB0}3P8G*yRkf)Cd$PH)ex2NBq z?{)WIioJ+%Ygvg2@=}{hVlU^;r&>3*KH6qSxB_G1((V6gjl=H5o>_EGL6s~(xhflpI%_pe%gln-80I%x_|fs?&E7kLtb*7Ft{2)bPsg!$*~+Wjb&{u>!s ztXMfYNqL4gRxl3KxqEe1II`g>;JVT+yj|}IcV!@PJinSb30k-Za)9IwGUTTOj638S-i?dz{ zni>{HCl^W}DHN>pnDwIjwwOzUpXlayKUw}V>7hABE(+E!apf-6vb2o%0!7)K0*;4) zhwS8S$6~BPU2^$@6*^%M=#fhj4st8s6^duFcg%mWWSC7x{i*X=7O`Cq zpDP%wqXk6=G}aIv@YV^IURO=eUdR=7R+?;R9#>!Nz37wx_h*|+V&{qg!OLQ&vLkUO zISF@&Myz>))pTt>Omn4vMlg72{VNmF+^*u@ny?4+h6}$&l?XWS zwk;;SkTn#r(?vNarbvlF9(yv!;}1PnGsmr^G@UhLG5IxSN*-zbr#}iuw^+9k@q>lH zIt;K|3ymu14U`rNhZJ0V%G}>| zs_e7^cTW849+K3TR2EdcJuAEJiWYNeAHz6Y-*fvJr&ni{bQbr+N2Vd*hAD7NoV2Ct3F=Wh<)USCXTR2Avby4mY3(aCgA)tFzhh&*zD|^ z9ev&{Ao0U*MR6@5fkD%`lI3U^Un7q4u;1D}c9k^IU?!0zKGuG^zToSs8tpiaD{?$Z z#I6U^MY5ux(&2^Cw=I%ag&h_WamsVIyB5skpl5|sVXznmU1x{fZ##ZcBY@eul^PwS2i`rMA2`c zHysjS!>smEnWbLCQD4Yyr)VBea-{RBFXxC>dbwMdH?w#8Kwd{qD?v5Zs?9?luNr7J z8aRF_VG#G*-BUCleh`=CM3LX&Al;h%B}6l3EK%fTf+SiXMq?5mWXO*`B#cP~TLB_uIXlKH`C;J%<`Y?V2)xSQH9w2m)Ji1cMw zFKEbX#;T9$M`gsh)1PDbHavvS)$Nitbz?boDvHXwFm9|OeTdRYYgSgh60_44v=5J- zY+C!?53i>zBWwn>d6i8oPUsfr0#McF@#7sGQssYvLr$jrKx}MygOTlZ#$o-3y7?o#>@QxN z^-EKyq<)$^=Qv)rsdJhyM9$b)J1n1`^w<5Onf~vQ*{rVQp<%dUI&zyd<>vwVnO3o3 z^8UnfcYS>-_*c9oCU2CpYS+<20fumxH6#Wod^AqK50-MhFuk8txv-q~JI@B2qM?pn zMDC7L?thK0@{0kZtiimxmQz))e%J@Ke2$t|;E)xtQjupTO?Ow@53Gi;Ux3aMB~F{b0AuN-5_&c^HW3k#gWBxKJRc1W z)SEa3V5qaOtlzZCBjCx{P*BFkk@c@Z-VpX@Shy*iAwap;Acf{pl?@9;Smtz2(pwrD zdtfJ=W1IOwVa5XueSkH^`}&s`k}U8(E^f%ZcE>F)n&+&*tJr|#f)*`zPoO}bFtCaE zF4aSw?Sp3$v$^mPC;hF1*^2e%P3*LT`y0pSe{tcC63ys*+fFGD-kgfA#~`I&#b?_+ zq-LF{ZfhZAy_Y$CnvZT^B;E4w?b`5TD_-iK?PB`u<_&BXn$YEeIao8{Qf z%kyw|XH5ZIRh}Pe4u>{!CMK0oSC`{;O0C^;mxi2|4$w9{{vrMaHABIHk&&4dUmAD0 zd(L5HP)wEOdYQFW+=E+EY7#g-}t-I~3=MEa{Sy+)6e0U_JsQE1PRjiqH)?B+zwD?UCItuKCxgPM!l5 zo0@&N{SyI+g{O2{;9`m?4u8~|y(E6Tc|isOd9+2PIiTwp^Y$0hR_%OHyC$BVNI*lL zqR=lVZ>6CmHh+>PP)2CKQ&>Y|+jnQ2BxX~XQ-~~H3fWV;6{{;{LH-Y*9_!xEKsS~V zQ`dMN2xU|M%pZNc+WrlZ%EWw%QLrgu*SXxkWqDB&|51*@ert;wErcm9*joGx;(&LMrLbWuETo8S*;<$!? zU7@jK8(u6dW%oOQq1UC~YOX7wsQNUb_WBGR@Wl0FnE?sa0eBv?v8 zIX+zWFS3uD2BrN4DaHCQ*DWkr)yH`PJg28~Wm_WO7O3Fod__1nKoWH4gYl-o(f{<(Ff>wPx zV_g!3vZak-p^!)Eid6{ra{9t7YIif4DWi9VCkGy%;HqlTE9(uSU53u;={qaX++1f* z0g&`-6fPN})a}xeVdPskyoG<2%HIyf``-98#e7ft<8K>7T9kr{FnnkDL0aMIxbjus zyi&0KPB)@cZEeZXWwhSK?$eWX!ufe1zno_~O#E#9%rU;l@Oq}}U00^cej4+XSy;}B zM4$g8ud}Mj!hx)(-{LB@+dwxXPMRW>)Axk8=e|b`A=r||6b=kFVi$7#>wMTGX>PqT zZ&reYRC@S?EZ%g5wzRZ#4l1Di-7BLl#10p8E~2;KvAs$l8;sqPugibxI#khfbC>pY z0yw2t`~^E?r`k0CV^aUjr!yS=zoya!XIrNq-~ZbtqMF{({%Sc(F&}c*e>d8Y-3Q=; z$^2U7vC+qRcU(aX^mRG2c&X@WS(qLCk$|YR+aI8?3+`24xiT_^8|-N*U0P52Zz?hO z1*h>@S}1HK$m`;Acz%@p5bfE~+twZbL}EyGUcZiry`3dk6Cq6<{9?cH$!ytKZ|vg$ zn2yd1_{+4wY-_F(F1*3~A7ZN5=kl|wrc0&)|CS#}>#P5fQ88TdS5M8W+)sNkOl9Kr z%e(NM>jtv95C)vH8f1Wsp`EI8Fi_0EOK{{JEh{;>UGjRUhY~SifB&rS>PCKk@9nrP zQz{nk?TEf!v9pVMktpcrfQ9;_DX60e&wh9QEI()Qi+t%Z$gF?!m7a^GeQ)!uZ^g%@+ z4~1#>J&*L6)e(F1+cA`CFcT`4i$&_u9vT}lJ;<(&xw&G`Tjkz^D!uMe1F!3_Z7Cpn zyH9X2y%CpfE!&nQ8S=Qbr6qiGU&Q}vD#@{q8L78)dSWXa^=lxHBLAOopbv0Gaey10 zcuXy`99X=8R!I?YD@(9C@|2ewu=plXUv#P|WW3vSkZLSW!G8Bm z!ukG$MaGzrb)VhDVc_M-sZ{&MBtWb~|FvCCo>9fs@}B6L)%K6|^}46Z<$VW!e@`{6 zKa=o(f|9Ukj4aLVyfL}sL#Mm@;wLi$Q(Zh@p0qLby_SOX{G*gcf3h|MrJ-~8X5Zz6 zTiCPDMK4fc#p={Ad=JccfF&cw(gSroQ(W&K;V6FobAqSH$*+D7lZ{&1^(t!1Q2w7+ zVhITSiU9?-%GIA*mJ|9Y}b?Ykd&uGsb=NY=2=d)bPyM*)59 z+=VwgD}Z$K;7@y!XVv$-yETNgkB^VJ>pRas>K0f=+CNV(SY)rdB~JV7<$}JfOk_-@ zQCrb~`Yhq(0(CA?RyI1uojk`M49c~7Da71LqfJ(|S6l9)f>WZ87TJ^Jj_A~{R!*urdGwRc2hLOirI9olcK>T zBNtJYEA1a9bkOr!Z`?m8EDWYXX~fL~4OAi$_J^veIba#l8uda>Qr1G=n+lBmn?uz8 z*Xhh`gurp8XV$B!_#5lWH+xw4_RW6wZPXV`=h9a*T%TXWl)Q zILz$^m#3`K!qzr>*~kcBVe!J?wr`Knvr<#P;E~B>XN*Xp$q*8MQ^V8UiE>jf&rc`Q5Xc<=^u-9|=7 z(WN325`W={O_lT}jwBfM+6iK_b~2~o`Q6XDQ&^=Uv|a7=qL`U`ukE4lcgAq3E5p;i z*_X719fgI{0T*0I;eR(?jhEk z&xf0E16IQyV-RI{jISp{f2WpKYBmuDq&nz!4xNaNOie1xsEtcPPc{ZvgZs>htW~pvxr@q?X6*hY+g?Y>K zep49WJ~(~1O29{?qJGhRlE9_Heix_iGz?y!CpJML?0U30j#w0q7_K|>?H#4QG8ivG zPry@YRvZB#S4&1^K&>e3sPeBK)^oL+YT6v|oSjCDbdyVEh`v7=TS4)iBRPmvJ^_A3 ztHIzxVVA*fP~Rg$G@{UcrXNFu)lmM3Yl0GZ!k>-LyRDArva>0m&ejVd@9BF-mU@z6 zNKZ_QtY10I5m?SZQh1HsUsqZ_*A-*dy|fx%|1C+Q*LTMRGeGM4zE5LXJoj^sX|XTQ zJlvpIP&fLxL#J`QMp|u`>(m(1+A|>p~RYQ=q;za8Cf( z@=B?nNE{;tT!M)2yows-{g`_nK0G<_FZRT1_7X`&&b~R{Ot{g~(wg}!m1Uy?7Oa!J zS;>Logjn9#-2)Bq5^otR7?EWIM97DuhSwMSeMP>G zP{l#AK!DPaVr%lR0r_Wt>)DlZEQhVKIM$yVwD?1FKl;ZjctxxgxRLsqi@suCy-VcpNz^fX`Z4P15I`k2zLEGRCf zeL6`=9-Bbq!*6a$q_yczC2s7`!A{e-cMu!LNA%+29pLQesVhJipEgyS zzt>9QqD1A;lTT-2-nnLmWwuZOS&T|AcY3TEjsW(T70IKr*?RK_OrI@H4 z)PD4gnCpd8tH$|FeGSp6lN)fmfjsdatI>F7GTm(F2Rn6akuX7dm7ad0B7yytv!v&A z+NnS#H+$ZPFES=m*X!;Mj8JEhWm-S<-CKDt{lKBz1x&{=2_194aI&s`=9LXEiC{MiA) z#;VJe+QpQ)F6#r|IgvL_?ib&-dQg+lFv`f6CnLBY_1g)yl>~bAE6NwXtE{%)Wi{-Q zm#uVD036DQgYWlmT5)u*&Zlo+AVPU)yN~}7q3z5GMg_P&T($BWCO}c9m&0%W^Wq>; zk$n3l&Nd;IQJE3F>P@C*m~ni3d{9r%Dr$P>n~d-HgSOj&#?{r;c{2so61Bjr!eq%t zXJ%w*$C^X<52ScC=oQHY9BK!~MJEJ)WjQ%D2lEuqmfON*Ic2+|=v-@!cyXm%CrZ0Z zHPHLENj{|opELnJ{Ug#jp?)(GMa_Kk%e~~$r@pRf__9xQJ?s^40DcfvuS|MGL)1#_ zD`p?5q|}*e)6C&(lOVy&aT{J;o&k@d?r{S~Zy6y~6+II^`wFMna$B{nGxzb^wgwJ? zf6!?Fj>SQ!$sB3XbP3O7Hz6T&6kW-?eh?YE^^@EH*3nJpva@Ywu5zRE5e3?f8vh0F zMl=0#bd+i=BI8?iKhcD#de)tf^3Q{Bf{6}DwyLS%S75tWa*Y6C+!h+ZDZ&`!rF>ee zHBL$JFOkI^965un!N3yL=@3U(Lr&i+QRknx(&N4S1OVBU(y@wgCKhCL+ART)!@}d~ zF?0RV#UexvakR?w1n_&5K_A(NDu$QTj)+KTp~}GIYS?31>7}yK>LvL$r6@B^fATLD zW}BUz%(?D&4L>24?3DrHNANq9IpXob94kke?y=hZj;`oUCVhm9E_*`#f?M_Nm&Aet z)G!dWGy1Xzxk|c%8B4Wa@jEVbdh5*D+c|CRSRDnujYTGTd7Xd#ACxPp5saYX^+O-j zt$=3QCJDzUKz4&j_j3g>xJCT>v@bX~czqpteTA$~5rt-#lNJV>UiG+$!0wH*xacGCzWnk~F?GwM3e+Le7i^wp_b$SI8_mbyRHP0HDRh;NyNR z1xo6d;N(u5m1K=pA@t*(wDY+Ik^ms4_oyJhRH2R;eTT-}-XITvFUiOD3d{)4`i>?K zUC0SA?!0%GXy??^jj<(>an@MoOn{D3?7tIgJC&EWd*r;Lp}WuK%%+$~vEhtiWvl1} z*YbH5@-_Yu*iwd%ZSB+gM*a(0B1>ymzO;v;GaP{23Ee>Mk}Sk4O^^}{Gf`S)7U|pM zw*#|6@g)5jAl)Im3xJ;Y-xB*<_(SQa)FF$)cfD81HQ%X>y;mR~pTcJnH__3o8p_F%BZ(B-v&YPML3QWrRTwRdGWAlm zSSi}Vlc>a#?X0xn?Bh_`>!FB%s+ESlTL2nqDM$}+=qxR1zyGBA%{^1&S!)%irOJT* z{td8Dw9+L)f}yv}#P+3)(e8VhKp4*#$n8!Q4IS;$nvB{4?j3BLSrVcF{%saH5}7Nr zzWU-R&B?6S(f0e%A%m`6$>6LpB&VU>{!b|#@4t+s+siK-qQF@ zSCa!>tv{~{LoSglXWt8K5DkvadbnLOGczWaUcH2R3)q9lrc)=zZ23Ze^TOngD=Wum zSf^tWLjJZE4Y!<#$@v1(^73r7JmV$|aZS_Th3qJjS&%WXv4zsC0Adr{b>|M_tmcl_ zyAj)U`@PWZ%iM|)3j~VvWcK}C0t!K=XD8j)7k$^Y$2sCcfEXbFx)o!OXzY9TcY@U~ zdwa*7G?iCKbFj?HIUQmo>%2LmX|S4hf6I9|_VKpsBSJs331CBYB+qb#3dy9lCz-6ycjCB90u&#T&o}0r>ncg}u*9 z=`>c0^$anbi~Qq;+Q_0QNxH1dIjF_UL0*uuMC*!461XL2d0D3?*V|h&6*yO@>a8V- zQQ7Mq*(LtrmIt7+@!|MBx>TO_&b@&)LE5H19y%FsVS;K>u>rI%4v+k=mICT|nZe+~ zUIE;Fq%bjvi@t|gz$)!yQxd}8DvY)jQf*=GteAO)7ZaG*G-XnwkSruDEabIz@?AI9 zo?iEAJ1v5r8N3v^-c5v7H`-`xR=eK=YK3dZ=nCYzIJnYP5 zudZq(SXUKxJGvkFhkr5`08X#k5PLygWKE=ykk11Kb;hP4(&ervZhJq?mv`Aat_t$n zNMv)RAXE&dEH;!XiDNUY%Qid4O&YPEG9}=EA?}Y%>FW+kY64@g`g)l(}J3y!gtyf?|9XMwl_ zKxlz#d!Vrb{(c%T&Z+l~5p|^`%cE&Y7e)IuNy8w7u_{ z{0D%0+oPcD580s_t!uLHgoYG|v_Gn14VKS?*3mcI&uDlQ8DHn_?~+#i5RL2e&Qf+B z8&w}Jc1f?CiKyF^qb_($`p6q(5(cTs2{kY=)ofGA7wW3M#WDVez1gO%p3T9 zwe+SR)u59um#EOe9@Km5`pG)|k0pUr0Z{cY15b`mi5}``evxdXQwD z+mvkN`#Qz%t}YGauk}0_E%|q2`Mj;&g-Gz5y?N`-HP5VPXjuz!2qWLpH=9qN zq`gRwNS;pEez<(N;zbU6*@cg#DVp=z7?D6}U`zEyLlp+o4(EBTR&2vMSz`rdHdHZm zCeG%Z_A~n-$DR~l;t>WZ?%2=uw#}zJbvzRY)iRT$0gYF@+3gyAdbh}t@khBMf1){l zGe`2>ImZPV#Yhf` z+TweF{0I|S+9f!rU&L^Zpi3#5UX2AK?0ULPa&o`=N+%lW*R-u`8!kU>tNd|X7@@G; zLxsm?YZN474JRQW#6PC`4NHphDu5ZVGu;_PM10qW)&RZZV;|JkmOW((Wnx~qM-JAV zmJeKu8Ep~d;#6OJ{%RW5-k6f^mPfL~8?i;>r0Nu5E4Te$o<*&%J~Kn23qLgk0YfqH zGf69c@}~xZD;-G}IqsljBc&yD_yI>5`J+%NCFh!H#lkDf4I&=?g7Q5uW}Q2SYmmik zX=QwURAap+9u1%vV5?w62WrG}^vKG&sH4k4OCtJJ>ChYlw@YmUQPulbfXOfu$kxBe z#5!)VpJF1k&c~A?|L{(H^Y&`wR2VlQBY-pf@iceTl-DUpDiS_b)Mm^XDxSrPDr(m^ z+*0jk=r>8thf#F$*T^#jB=g6a@P(`dShRLTnjnYID~LZ$D;hrSMB9kc9-=P@3Gcf85c29jOF7#lr;BhptAhA6bgtGM9F+CeWCH3g_5&OR9LKzhX0GqU3 zFQ;3)%oLnCdwE$?_|STsDz0z@ZqAF-nGg$xI*}wKC807!COf)@H%M1&M}Fj$*JwVG zRMSb!?N%YJ%z7)34JovE8Othv0gw~E;CsV8zT1*(huu0Ud>+T8c#ZL~ z)-ziL*6X=fZ3+7xb;-;FMr!k-q8k_j*T(m(H5`!(F6zQ0(Va1|dH1pe*OP%n2iabq zI1~QF0R)V()fjPJzf5z3yGsatM?XvMA$3v4)1M`R7PpqXttt4L?34RV}a*u|;L;-FFYvnvs zDP1SHB|)_?TX0sEpNrn{JRI-k^)2CAo04{jzC$$Z!vUqRi`wm5gp%acla;p0Z_PWN zV5ic;Ib(!K7P`H41+tSe4iR_6yzO5WCD2CMne)eegpIX?*6QIZFU@FG_Kallj>{p{ zD}z1^y{jDp$HKl2s~G64F)S2f(|cP7)v0nNeTqUdqdR~dh1G_f1k|absl!hA1aY)E zeYW(f@elAFF7K@oMeE-qYbu&Jya5bp6byza=#-ZaW&m-wBxn(nXrIS!`q}OwGQ5jA z$YC%#sCBL)!y|5fd;O&3IcR*p>=W`3ZpmLDshx?#;5uyKG&3%S587KtRizt`y!FCg z2oO4QZ;+!l+%cM-DH5Os@LSqe4a@D^9^?y_E_?3CPj#lFZR#r91vHJ-#-rgRQn7TC zsoc^X`FuYd1A|xPC~+b`B_J6R2oB8^kM`s~zAE6d9qrW%*-n4b(jM$#-}ewU#aF|6 zi|=H9I`gezd@AaV=?sDD<+cLWpSE~6SqXoaKgpHzGwmW2K|u3DZ3$4im%TN^cg4Pr z!_7@dWK}!rB~G7v>1hOMa9ZQsw<5=nhEr zX?}>S{1&%!b^#@ybi|7XwYq+D?8Milv}qI`Wv<^1jY^1H_?iCOF1y4%%AVDscAyl<_0 zwbK}ROE-G4V-UcE=>t~iOcZK$PGvRy{qQzL!DaJ^`dgU_0H9S!o)yC`&w+f^l2B?` zBAhtmbNIO_^Su8WvWlVs<3;%rPStmejppA%ed;PvEoWs=N?-G;Umv zyQG#WID_dETC>7}q21yvOO_ zUVCtmF_b*u$Ny2@!u#bCWZb-XtjyPW{jBSbpT>m<%ES;-T3Fpb=-MA;4}V1Hs9!_V zZ1oHjp{`XbV!l?L0{6(#HO5w1>f9=WuW~9vbhIZCdbI=E(P?#Fr`e@8ALUgA!!^v1 znI?k+lB{xeiazI5qqYF7sd!R<%Sjdo?Yfl5rdQ(C*|uIMTqZDHVV~!8)>X?!+Fn|B zM9MzL5aS_S5^{8W?J+kUd{qnyfujYpLBu1CUstTJVTb}X=m?cQ0OkDpY1lKp4G$GGws(0q}KWupb+xhUnGgAEjvYj8iH@sLN zy=DI9Ad`CSZoK6`5ul&F`h4&AfYX<~nKuM{|5}_h^mHn=UGMzs+`akxpZWBaGXB>0 z>#q|p4?Zxb8)E$(0RM-0^q)_47W3b}rTQbc4}H$@l@lq*eb9dsd8p3AI(8bIcQ^~) zgq6>JqosO~9k+h2&r+Y(&MRvC@3HlN9{A5E;L)&-jt1|Dc2{e!fu*q*%|0-GIyoP6JBj=GbffErcizx+z4uyW6`>;1H}^>)1G?quh4t7AY| z_fMG2U|Dn;CBcRBNQ$hA$|7(^&RnEzPygOL_E(&39+x`f&qxXHSSS!z|YXpUvF$U{9qif%K*N6<#lyY_15F3xSmC=!S*Tc>hJ!w z%a0w(pl;K@ur7byGWUXrRDj;8z-GN_Uomr<7TDCr`BI|a9s5Kibw_wa6p{Z6D6Lx$Z1k=f!qqvaL7z0-#^y zcz?IabGyNu*@>C{BBqoxYEdfX#oRt1jEEl@DD%GYp*7jogWs_l@Ou|`-Q2y2BS2{O z#?{P>HpR490FhLa`W&#-{(YbVkNq==aHQ>D2QP4qjPl=Vee?3r@Wvy=bt~ta-Aw9B ztIzdY7>t5sMt}kCUyIXliio$%ZC&!n zQoq?mKUi2-smMFezYcqUf6=KtMcC89jJ$U5=1Z3mz|4GY(B?eVF#`zx{cCB^;Pc*F zinM>;f^+`t3_>m*BL(P7iI)Dy12v{SChcj*Cg7x-xxj0g6gjoO8Fj@l(|Y|9wEO3w zS_FOjH)y)t5veRAA8Y^c@;dRX+fVV{UukV?3m+r;U)3eEE-5M5Ujbx?+^m7G z!gvK$0qmg(AU-X<)%eeoe}0;3X)3DyU%vvY67T<`yRWHRU$><)G<+StxlvY930(Bb H=-vMTf{8hv literal 0 HcmV?d00001 From 0859665c2424c9b6b96e76546400009adc2f6762 Mon Sep 17 00:00:00 2001 From: MFA-X-AI Date: Mon, 6 Apr 2026 15:04:03 +0900 Subject: [PATCH 2/9] Add Docusaurus demo docs site, fix pan/zoom snap-back, expose zoom/fit controls --- xircuits-graph-viewer/README.md | 48 +- xircuits-graph-viewer/docs/.gitignore | 20 + .../docs/docs/controlflow.mdx | 11 + xircuits-graph-viewer/docs/docs/intro.mdx | 20 + .../docs/docusaurus.config.js | 88 ++ xircuits-graph-viewer/docs/package.json | 46 + xircuits-graph-viewer/docs/sidebars.js | 35 + .../src/components/HomepageFeatures/index.js | 64 ++ .../HomepageFeatures/styles.module.css | 11 + .../docs/src/components/WorkflowViewer.js | 14 + .../src/components/WorkflowViewerInner.js | 145 +++ xircuits-graph-viewer/docs/src/css/custom.css | 30 + xircuits-graph-viewer/docs/src/pages/index.js | 43 + .../docs/src/pages/index.module.css | 23 + .../docs/src/pages/markdown-page.md | 7 + xircuits-graph-viewer/docs/static/.nojekyll | 0 .../docs/static/img/docusaurus.png | Bin 0 -> 5142 bytes .../docs/static/img/favicon.ico | Bin 0 -> 3626 bytes .../docs/static/img/logo.svg | 1 + .../workflows/ControlflowExample.xircuits | 902 ++++++++++++++++++ .../static/workflows/HelloXircuits.xircuits | 623 ++++++++++++ .../packages/core/src/interaction/panZoom.ts | 69 +- xircuits-graph-viewer/upload-demo/main.js | 28 +- 23 files changed, 2152 insertions(+), 76 deletions(-) create mode 100644 xircuits-graph-viewer/docs/.gitignore create mode 100644 xircuits-graph-viewer/docs/docs/controlflow.mdx create mode 100644 xircuits-graph-viewer/docs/docs/intro.mdx create mode 100644 xircuits-graph-viewer/docs/docusaurus.config.js create mode 100644 xircuits-graph-viewer/docs/package.json create mode 100644 xircuits-graph-viewer/docs/sidebars.js create mode 100644 xircuits-graph-viewer/docs/src/components/HomepageFeatures/index.js create mode 100644 xircuits-graph-viewer/docs/src/components/HomepageFeatures/styles.module.css create mode 100644 xircuits-graph-viewer/docs/src/components/WorkflowViewer.js create mode 100644 xircuits-graph-viewer/docs/src/components/WorkflowViewerInner.js create mode 100644 xircuits-graph-viewer/docs/src/css/custom.css create mode 100644 xircuits-graph-viewer/docs/src/pages/index.js create mode 100644 xircuits-graph-viewer/docs/src/pages/index.module.css create mode 100644 xircuits-graph-viewer/docs/src/pages/markdown-page.md create mode 100644 xircuits-graph-viewer/docs/static/.nojekyll create mode 100644 xircuits-graph-viewer/docs/static/img/docusaurus.png create mode 100644 xircuits-graph-viewer/docs/static/img/favicon.ico create mode 100644 xircuits-graph-viewer/docs/static/img/logo.svg create mode 100644 xircuits-graph-viewer/docs/static/workflows/ControlflowExample.xircuits create mode 100644 xircuits-graph-viewer/docs/static/workflows/HelloXircuits.xircuits diff --git a/xircuits-graph-viewer/README.md b/xircuits-graph-viewer/README.md index de80c424..8e99e53f 100644 --- a/xircuits-graph-viewer/README.md +++ b/xircuits-graph-viewer/README.md @@ -10,6 +10,7 @@ Pure SVG renderer for `.xircuits` workflow files. Parses the JSON format and pro |---------|-----|---------| | `xircuits-graph-core` | [![npm](https://img.shields.io/npm/v/xircuits-graph-core)](https://www.npmjs.com/package/xircuits-graph-core) | Parser + SVG renderer. Zero runtime deps. | | `xircuits-graph-react` | [![npm](https://img.shields.io/npm/v/xircuits-graph-react)](https://www.npmjs.com/package/xircuits-graph-react) | React components (interactive + SSR-safe). | +| `docusaurus-plugin-xircuits` | *coming soon* | Docusaurus plugin — drop-in `` for docs. | ## Quick Start @@ -95,26 +96,9 @@ const { destroy } = attachPanZoom(svg); ### Docusaurus -```mdx -import { XircuitsGraphStatic } from 'xircuits-graph-react'; - -# My Workflow - - -``` +A dedicated plugin is in progress (`docusaurus-plugin-xircuits`) that will provide a drop-in `` component with loading states, floating zoom controls, and automatic theme sync. -For interactive mode, wrap with `BrowserOnly`: - -```mdx -import BrowserOnly from '@docusaurus/BrowserOnly'; - - - {() => { - const { XircuitsGraph } = require('xircuits-graph-react'); - return ; - }} - -``` +In the meantime, see `docs/` for a working Docusaurus integration using the core + react packages directly. ## API @@ -163,11 +147,26 @@ cd packages/core && pnpm build # Run tests (24 tests) cd ../.. node_modules/.bin/vitest run +``` -# Generate a PNG preview (requires Google Chrome) -google-chrome --headless=new --no-sandbox \ - --screenshot=output.png --window-size=2700,1400 \ - /tmp/rendered.html +### Running the demos + +**Upload demo** (drag-and-drop .xircuits viewer): + +```bash +cd upload-demo +npm install +npm run dev +# Opens at http://localhost:5173 +``` + +**Docusaurus docs** (workflow documentation site): + +```bash +cd docs +npm install +npm start +# Opens at http://localhost:3000 ``` ### Project Structure @@ -185,7 +184,8 @@ xircuits-graph-viewer/ │ └── react/src/ # xircuits-graph-react │ ├── XircuitsGraph.tsx # Interactive (client-side) │ └── XircuitsGraphStatic.tsx # SSR-safe (string output) -├── demo/ # Vite + React demo app +├── upload-demo/ # Standalone drag-and-drop viewer +├── docs/ # Docusaurus documentation site ├── __tests__/ # Parser + render tests └── vitest.config.ts ``` diff --git a/xircuits-graph-viewer/docs/.gitignore b/xircuits-graph-viewer/docs/.gitignore new file mode 100644 index 00000000..b2d6de30 --- /dev/null +++ b/xircuits-graph-viewer/docs/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/xircuits-graph-viewer/docs/docs/controlflow.mdx b/xircuits-graph-viewer/docs/docs/controlflow.mdx new file mode 100644 index 00000000..05e31e1c --- /dev/null +++ b/xircuits-graph-viewer/docs/docs/controlflow.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 2 +--- + +# Controlflow Example + +This workflow demonstrates branching and loop control flow in Xircuits. + +import WorkflowViewer from '@site/src/components/WorkflowViewer'; + + diff --git a/xircuits-graph-viewer/docs/docs/intro.mdx b/xircuits-graph-viewer/docs/docs/intro.mdx new file mode 100644 index 00000000..807102f9 --- /dev/null +++ b/xircuits-graph-viewer/docs/docs/intro.mdx @@ -0,0 +1,20 @@ +--- +sidebar_position: 1 +slug: / +--- + +# Xircuits Workflow Viewer + +Xircuits workflows rendered as interactive SVG diagrams. Pan and zoom with your mouse. + +## Hello Xircuits + +The classic getting-started workflow — connects **Start → ConcatString → Print → Finish** with two literal string inputs. + +import WorkflowViewer from '@site/src/components/WorkflowViewer'; + + + +:::tip +Use your **scroll wheel** to zoom and **click-drag** to pan around the diagram. +::: diff --git a/xircuits-graph-viewer/docs/docusaurus.config.js b/xircuits-graph-viewer/docs/docusaurus.config.js new file mode 100644 index 00000000..0fc357b7 --- /dev/null +++ b/xircuits-graph-viewer/docs/docusaurus.config.js @@ -0,0 +1,88 @@ +import {themes as prismThemes} from 'prism-react-renderer'; + +/** @type {import('@docusaurus/types').Config} */ +const config = { + title: 'Xircuits', + tagline: 'Visual programming for Python', + favicon: 'img/favicon.ico', + + future: { v4: true }, + + url: 'https://xircuits.io', + baseUrl: '/', + + onBrokenLinks: 'throw', + + i18n: { defaultLocale: 'en', locales: ['en'] }, + + // Allow .xircuits JSON files to be imported + plugins: [ + function xircuitsPlugin() { + return { + name: 'xircuits-json-loader', + configureWebpack() { + return { + module: { + rules: [ + { + test: /\.xircuits$/, + type: 'json', + }, + ], + }, + }; + }, + }; + }, + ], + + presets: [ + [ + 'classic', + /** @type {import('@docusaurus/preset-classic').Options} */ + ({ + docs: { + sidebarPath: './sidebars.js', + }, + blog: false, + theme: { + customCss: './src/css/custom.css', + }, + }), + ], + ], + + themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + colorMode: { + respectPrefersColorScheme: true, + }, + navbar: { + title: 'Xircuits', + items: [ + { + type: 'docSidebar', + sidebarId: 'tutorialSidebar', + position: 'left', + label: 'Workflows', + }, + { + href: 'https://github.com/XpressAI/xircuits', + label: 'GitHub', + position: 'right', + }, + ], + }, + footer: { + style: 'dark', + copyright: `Copyright © ${new Date().getFullYear()} XpressAI. Built with Docusaurus.`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + }, + }), +}; + +export default config; diff --git a/xircuits-graph-viewer/docs/package.json b/xircuits-graph-viewer/docs/package.json new file mode 100644 index 00000000..87a2257c --- /dev/null +++ b/xircuits-graph-viewer/docs/package.json @@ -0,0 +1,46 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids" + }, + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/preset-classic": "3.9.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "xircuits-graph-core": "file:../packages/core", + "xircuits-graph-react": "file:../packages/react" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/types": "3.9.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=20.0" + } +} diff --git a/xircuits-graph-viewer/docs/sidebars.js b/xircuits-graph-viewer/docs/sidebars.js new file mode 100644 index 00000000..f77355c3 --- /dev/null +++ b/xircuits-graph-viewer/docs/sidebars.js @@ -0,0 +1,35 @@ +// @ts-check + +// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) + +/** + * Creating a sidebar enables you to: + - create an ordered group of docs + - render a sidebar for each doc of that group + - provide next/previous navigation + + The sidebars can be generated from the filesystem, or explicitly defined here. + + Create as many sidebars as you want. + + @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} + */ +const sidebars = { + // By default, Docusaurus generates a sidebar from the docs folder structure + tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], + + // But you can create a sidebar manually + /* + tutorialSidebar: [ + 'intro', + 'hello', + { + type: 'category', + label: 'Tutorial', + items: ['tutorial-basics/create-a-document'], + }, + ], + */ +}; + +export default sidebars; diff --git a/xircuits-graph-viewer/docs/src/components/HomepageFeatures/index.js b/xircuits-graph-viewer/docs/src/components/HomepageFeatures/index.js new file mode 100644 index 00000000..acc76219 --- /dev/null +++ b/xircuits-graph-viewer/docs/src/components/HomepageFeatures/index.js @@ -0,0 +1,64 @@ +import clsx from 'clsx'; +import Heading from '@theme/Heading'; +import styles from './styles.module.css'; + +const FeatureList = [ + { + title: 'Easy to Use', + Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, + description: ( + <> + Docusaurus was designed from the ground up to be easily installed and + used to get your website up and running quickly. + + ), + }, + { + title: 'Focus on What Matters', + Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, + description: ( + <> + Docusaurus lets you focus on your docs, and we'll do the chores. Go + ahead and move your docs into the docs directory. + + ), + }, + { + title: 'Powered by React', + Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, + description: ( + <> + Extend or customize your website layout by reusing React. Docusaurus can + be extended while reusing the same header and footer. + + ), + }, +]; + +function Feature({Svg, title, description}) { + return ( +

+
+ +
+
+ {title} +

{description}

+
+
+ ); +} + +export default function HomepageFeatures() { + return ( +
+
+
+ {FeatureList.map((props, idx) => ( + + ))} +
+
+
+ ); +} diff --git a/xircuits-graph-viewer/docs/src/components/HomepageFeatures/styles.module.css b/xircuits-graph-viewer/docs/src/components/HomepageFeatures/styles.module.css new file mode 100644 index 00000000..b248eb2e --- /dev/null +++ b/xircuits-graph-viewer/docs/src/components/HomepageFeatures/styles.module.css @@ -0,0 +1,11 @@ +.features { + display: flex; + align-items: center; + padding: 2rem 0; + width: 100%; +} + +.featureSvg { + height: 200px; + width: 200px; +} diff --git a/xircuits-graph-viewer/docs/src/components/WorkflowViewer.js b/xircuits-graph-viewer/docs/src/components/WorkflowViewer.js new file mode 100644 index 00000000..572272d0 --- /dev/null +++ b/xircuits-graph-viewer/docs/src/components/WorkflowViewer.js @@ -0,0 +1,14 @@ +import React from 'react'; +import BrowserOnly from '@docusaurus/BrowserOnly'; +import { useColorMode } from '@docusaurus/theme-common'; + +export default function WorkflowViewer({ src, height = 500 }) { + return ( + + {() => { + const Viewer = require('./WorkflowViewerInner').default; + return ; + }} + + ); +} diff --git a/xircuits-graph-viewer/docs/src/components/WorkflowViewerInner.js b/xircuits-graph-viewer/docs/src/components/WorkflowViewerInner.js new file mode 100644 index 00000000..160c4d1d --- /dev/null +++ b/xircuits-graph-viewer/docs/src/components/WorkflowViewerInner.js @@ -0,0 +1,145 @@ +import React, { useEffect, useRef, useState, useCallback } from 'react'; +import { parse, renderToElement, getCanvasStyle } from 'xircuits-graph-core'; +import { attachPanZoom } from 'xircuits-graph-core/interaction'; +import { useColorMode } from '@docusaurus/theme-common'; + +const ZoomInIcon = () => ( + + + +); +const ZoomOutIcon = () => ( + + + +); +const FitIcon = () => ( + + + + + +); + +export default function WorkflowViewerInner({ src, height = 500 }) { + const containerRef = useRef(null); + const panZoomRef = useRef(null); + const graphRef = useRef(null); + const { colorMode } = useColorMode(); + const theme = colorMode === 'dark' ? 'dark' : 'light'; + const [error, setError] = useState(null); + const [loading, setLoading] = useState(false); + const [loaded, setLoaded] = useState(false); + const [visible, setVisible] = useState(false); + const hideTimer = useRef(null); + + const showControls = useCallback(() => { + setVisible(true); + clearTimeout(hideTimer.current); + hideTimer.current = setTimeout(() => setVisible(false), 2000); + }, []); + + // Fetch once + useEffect(() => { + if (!src) return; + let cancelled = false; + setLoading(true); + setError(null); + + fetch(src) + .then(res => { + if (!res.ok) throw new Error(`Failed to load ${src}: ${res.status}`); + return res.json(); + }) + .then(json => { + if (!cancelled) { + graphRef.current = parse(json); + setLoaded(true); + setLoading(false); + } + }) + .catch(err => { if (!cancelled) { setError(err.message); setLoading(false); } }); + + return () => { cancelled = true; }; + }, [src]); + + // Render when graph or theme changes + useEffect(() => { + if (!containerRef.current || !graphRef.current) return; + + // Save current viewBox before re-render + const prevSvg = containerRef.current.querySelector('svg'); + const savedVB = prevSvg?.getAttribute('viewBox'); + + if (panZoomRef.current) { + panZoomRef.current.destroy(); + panZoomRef.current = null; + } + + const svg = renderToElement(graphRef.current, { theme, fitView: true, padding: 40 }); + svg.style.width = '100%'; + svg.style.height = '100%'; + + if (savedVB) svg.setAttribute('viewBox', savedVB); + + containerRef.current.querySelectorAll('svg').forEach(el => el.remove()); + containerRef.current.prepend(svg); + panZoomRef.current = attachPanZoom(svg); + }, [loaded, theme]); + + const bgStyle = getCanvasStyle(theme); + const parsedBg = Object.fromEntries( + bgStyle.split(';').filter(Boolean).map(s => { + const [k, ...v] = s.split(':'); + return [k.trim().replace(/-([a-z])/g, (_, c) => c.toUpperCase()), v.join(':').trim()]; + }) + ); + + const btnStyle = { + width: 32, height: 32, + border: 'none', borderRadius: 6, + background: 'rgba(0,0,0,0.55)', + color: 'white', + cursor: 'pointer', + backdropFilter: 'blur(8px)', + display: 'flex', alignItems: 'center', justifyContent: 'center', + }; + + return ( +
+
+ {error &&

{error}

} + {loading && ( +
+ + + + Loading workflow... + +
+ )} +
+ +
+ + + +
+
+ ); +} diff --git a/xircuits-graph-viewer/docs/src/css/custom.css b/xircuits-graph-viewer/docs/src/css/custom.css new file mode 100644 index 00000000..2bc6a4cf --- /dev/null +++ b/xircuits-graph-viewer/docs/src/css/custom.css @@ -0,0 +1,30 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + --ifm-color-primary: #2e8555; + --ifm-color-primary-dark: #29784c; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205d3b; + --ifm-color-primary-light: #33925d; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-lightest: #3cad6e; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +/* For readability concerns, you should choose a lighter palette in dark mode. */ +[data-theme='dark'] { + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #21af90; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +} diff --git a/xircuits-graph-viewer/docs/src/pages/index.js b/xircuits-graph-viewer/docs/src/pages/index.js new file mode 100644 index 00000000..846be01e --- /dev/null +++ b/xircuits-graph-viewer/docs/src/pages/index.js @@ -0,0 +1,43 @@ +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Layout from '@theme/Layout'; +import HomepageFeatures from '@site/src/components/HomepageFeatures'; + +import Heading from '@theme/Heading'; +import styles from './index.module.css'; + +function HomepageHeader() { + const {siteConfig} = useDocusaurusContext(); + return ( +
+
+ + {siteConfig.title} + +

{siteConfig.tagline}

+
+ + View Xircuits Workflows + +
+
+
+ ); +} + +export default function Home() { + const {siteConfig} = useDocusaurusContext(); + return ( + + +
+ +
+
+ ); +} diff --git a/xircuits-graph-viewer/docs/src/pages/index.module.css b/xircuits-graph-viewer/docs/src/pages/index.module.css new file mode 100644 index 00000000..9f71a5da --- /dev/null +++ b/xircuits-graph-viewer/docs/src/pages/index.module.css @@ -0,0 +1,23 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/xircuits-graph-viewer/docs/src/pages/markdown-page.md b/xircuits-graph-viewer/docs/src/pages/markdown-page.md new file mode 100644 index 00000000..9756c5b6 --- /dev/null +++ b/xircuits-graph-viewer/docs/src/pages/markdown-page.md @@ -0,0 +1,7 @@ +--- +title: Markdown page example +--- + +# Markdown page example + +You don't need React to write simple standalone pages. diff --git a/xircuits-graph-viewer/docs/static/.nojekyll b/xircuits-graph-viewer/docs/static/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/xircuits-graph-viewer/docs/static/img/docusaurus.png b/xircuits-graph-viewer/docs/static/img/docusaurus.png new file mode 100644 index 0000000000000000000000000000000000000000..f458149e3c8f53335f28fbc162ae67f55575c881 GIT binary patch literal 5142 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 F{0H{b<4^zq literal 0 HcmV?d00001 diff --git a/xircuits-graph-viewer/docs/static/img/favicon.ico b/xircuits-graph-viewer/docs/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c01d54bcd39a5f853428f3cd5aa0f383d963c484 GIT binary patch literal 3626 zcmb`Je@s(X6vrR`EK3%b%orErlDW({vnABqA zcfaS{d+xbU5JKp0*;0YOg+;Fl!eT)XRuapIwFLL`=imZCSon$`se`_<%@MB=M~KG+ z=EW^FL`w|Bo>*ktlaS^(fut!95`iG5u=SZ8nfDHO#GaTlH1-XG^;vsjUb^gWTVz0+ z^=WR1wv9-2oeR=_;fL0H7rNWqAzGtO(D;`~cX(RcN0w2v24Y8)6t`cS^_ghs`_ho? z{0ka~1Dgo8TfAP$r*ua?>$_V+kZ!-(TvEJ7O2f;Y#tezt$&R4 zLI}=-y@Z!grf*h3>}DUL{km4R>ya_I5Ag#{h_&?+HpKS!;$x3LC#CqUQ8&nM?X))Q zXAy2?`YL4FbC5CgJu(M&Q|>1st8XXLZ|5MgwgjP$m_2Vt0(J z&Gu7bOlkbGzGm2sh?X`){7w69Y$1#@P@7DF{ZE=4%T0NDS)iH`tiPSKpDNW)zmtn( zw;4$f>k)4$LBc>eBAaTZeCM2(iD+sHlj!qd z2GjRJ>f_Qes(+mnzdA^NH?^NB(^o-%Gmg$c8MNMq&`vm@9Ut;*&$xSD)PKH{wBCEC z4P9%NQ;n2s59ffMn8*5)5AAg4-93gBXBDX`A7S& zH-|%S3Wd%T79fk-e&l`{!?lve8_epXhE{d3Hn$Cg!t=-4D(t$cK~7f&4s?t7wr3ZP z*!SRQ-+tr|e1|hbc__J`k3S!rMy<0PHy&R`v#aJv?`Y?2{avK5sQz%=Us()jcNuZV z*$>auD4cEw>;t`+m>h?f?%VFJZj8D|Y1e_SjxG%J4{-AkFtT2+ZZS5UScS~%;dp!V>)7zi`w(xwSd*FS;Lml=f6hn#jq)2is4nkp+aTrV?)F6N z>DY#SU0IZ;*?Hu%tSj4edd~kYNHMFvS&5}#3-M;mBCOCZL3&;2obdG?qZ>rD|zC|Lu|sny76pn2xl|6sk~Hs{X9{8iBW zwiwgQt+@hi`FYMEhX2 \ No newline at end of file diff --git a/xircuits-graph-viewer/docs/static/workflows/ControlflowExample.xircuits b/xircuits-graph-viewer/docs/static/workflows/ControlflowExample.xircuits new file mode 100644 index 00000000..0ed24ede --- /dev/null +++ b/xircuits-graph-viewer/docs/static/workflows/ControlflowExample.xircuits @@ -0,0 +1,902 @@ +{ + "id": "bb487c34-1785-4bf1-b7cf-dd6ff80ac10d", + "offsetX": 123.88994214975773, + "offsetY": 238.283155021597, + "zoom": 82.96296505607548, + "gridSize": 0, + "layers": [ + { + "id": "827d8984-7e4b-4c82-8c77-bca1bca4538d", + "type": "diagram-links", + "isSvg": true, + "transformed": true, + "models": { + "8e14bedb-4925-45e0-9c16-008e36726d84": { + "id": "8e14bedb-4925-45e0-9c16-008e36726d84", + "type": "triangle-link", + "selected": false, + "source": "912ce164-3c9f-415e-b981-e334d0c1936a", + "sourcePort": "a1b94ed2-c63d-497f-9ebf-a16696db66c3", + "target": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "targetPort": "9aeb9ea8-af99-4528-a05d-df676958d7d7", + "points": [ + { + "id": "bd68e839-6432-431a-a524-959513eb0177", + "type": "point", + "x": -34.508, + "y": -46.233 + }, + { + "id": "3d9b1ce1-b439-409b-8f62-b171a6301fce", + "type": "point", + "x": 89.821, + "y": -38.466 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "02b61f41-cb12-4ae5-abc0-e795dfd311ff": { + "id": "02b61f41-cb12-4ae5-abc0-e795dfd311ff", + "type": "triangle-link", + "selected": false, + "source": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "sourcePort": "86ecf10e-6896-4963-93ec-bd4051686f97", + "target": "4acc1826-cb0f-4ad0-b498-8211eeb8b86b", + "targetPort": "f1bce6a3-a6d7-48de-91cd-57e74d76a600", + "points": [ + { + "id": "23ea006f-0287-498d-ab0c-4a91dfe6c037", + "type": "point", + "x": 263.605, + "y": -38.466 + }, + { + "id": "d1869104-643e-4289-9882-3b68677fa88c", + "type": "point", + "x": 514.381, + "y": -109.751 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "a073139c-99e8-44ca-884f-c25c5a6b47f8": { + "id": "a073139c-99e8-44ca-884f-c25c5a6b47f8", + "type": "triangle-link", + "selected": false, + "source": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "sourcePort": "a304e3f7-4951-4fc1-a3af-c98af87adce2", + "target": "a78e6da4-5bc8-49f5-8d03-353678fb130e", + "targetPort": "dba10cdb-c880-4752-9d51-64e509d735f1", + "points": [ + { + "id": "7abf5c2b-41d0-4273-94f4-0be558787150", + "type": "point", + "x": 263.605, + "y": -6.499 + }, + { + "id": "db510c07-f4c2-4ccf-95f9-b0704326c647", + "type": "point", + "x": 219.034, + "y": 133.432 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "165f2b52-b217-48ec-9a79-9b903dd8ede3": { + "id": "165f2b52-b217-48ec-9a79-9b903dd8ede3", + "type": "triangle-link", + "selected": false, + "source": "4acc1826-cb0f-4ad0-b498-8211eeb8b86b", + "sourcePort": "c7ea79b0-ce26-4e5a-bae3-12817dccc4d9", + "target": "248f9fce-76bd-494d-8080-7784f3aed238", + "targetPort": "c08bb8fa-bce4-444a-b1b6-aa58947a56ee", + "points": [ + { + "id": "a464b3a6-9f63-4663-bb53-34528b96d56c", + "type": "point", + "x": 606.267, + "y": -109.751 + }, + { + "id": "ebed74c4-6d01-4cc8-abd7-98b16c8a6d72", + "type": "point", + "x": 769.821, + "y": -83.895 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "52d7c6a0-b630-481f-ae54-13c302be4afa": { + "id": "52d7c6a0-b630-481f-ae54-13c302be4afa", + "type": "triangle-link", + "selected": false, + "source": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "sourcePort": "819341fd-b01a-4c99-b4b3-755c051d8ab9", + "target": "9691f88e-a4d4-481e-b911-b20f8757bb58", + "targetPort": "a0a3fcc7-1126-4a02-9d2f-c916949858fb", + "points": [ + { + "id": "627d7c84-8c46-49db-a1c8-a3e4eb98d4b1", + "type": "point", + "x": 263.605, + "y": -22.483 + }, + { + "id": "cf1c9962-b02a-426d-a844-87a9ae497831", + "type": "point", + "x": 462.807, + "y": 122.865 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "b5102f00-b881-4321-8edc-74085d1401c3": { + "id": "b5102f00-b881-4321-8edc-74085d1401c3", + "type": "parameter-link", + "selected": false, + "source": "972dea3c-2f6a-4a06-a9f6-1c5c78b83f67", + "sourcePort": "ebb1ed28-1e41-4789-bbef-48a98fae40f4", + "target": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "targetPort": "feac004e-83ff-49e4-a82b-937618fe62e3", + "points": [ + { + "id": "9d661224-6f6a-4f7b-8885-e6a1f8a2acfb", + "type": "point", + "x": -6.811, + "y": 30.122 + }, + { + "id": "475c1fba-e718-4556-a52c-30fed4b0b33a", + "type": "point", + "x": 89.821, + "y": -22.483 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "9ba321f6-69e5-457c-b939-5e68c24a4cb0": { + "id": "9ba321f6-69e5-457c-b939-5e68c24a4cb0", + "type": "parameter-link", + "selected": false, + "source": "408266c4-3f7f-46cc-87e7-9aa8d2c13b71", + "sourcePort": "bc57bc5f-032f-4bf0-985d-fd47bc26fd5e", + "target": "a78e6da4-5bc8-49f5-8d03-353678fb130e", + "targetPort": "67968fee-a315-4d02-a80e-10be786bd4f7", + "points": [ + { + "id": "1ddba09e-99ca-4f9e-9737-d2e2e947b6ee", + "type": "point", + "x": 139.543, + "y": 128.872 + }, + { + "id": "1e5dcf35-23cf-4b7f-8170-4663e7d2c263", + "type": "point", + "x": 219.034, + "y": 149.416 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "017d89bd-4611-4399-93bf-97bb6fb91179": { + "id": "017d89bd-4611-4399-93bf-97bb6fb91179", + "type": "parameter-link", + "selected": false, + "source": "d06b3ef8-2fb0-4aa0-8084-3aa44772083c", + "sourcePort": "a9a6ae1c-e8fa-43b9-bf16-d71d2487519d", + "target": "9691f88e-a4d4-481e-b911-b20f8757bb58", + "targetPort": "ce84d4f1-c073-4009-92b8-fc2ae7293e86", + "points": [ + { + "id": "91a0c1a5-2625-4d47-af3b-fefb290f697b", + "type": "point", + "x": 388.698, + "y": 246.024 + }, + { + "id": "e86ccd1d-e448-4913-bb2c-75d32f84be04", + "type": "point", + "x": 462.807, + "y": 138.848 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "a9aa5d24-f307-4558-959f-fafb42101011": { + "id": "a9aa5d24-f307-4558-959f-fafb42101011", + "type": "parameter-link", + "selected": false, + "source": "d344f75e-5ae6-4c13-b7ac-88a0f9e04c23", + "sourcePort": "49287324-16df-4968-a3cf-32d5d033d1b7", + "target": "4acc1826-cb0f-4ad0-b498-8211eeb8b86b", + "targetPort": "5891450f-19c0-48ea-b9ff-448c7289f483", + "points": [ + { + "id": "0f79ccbd-f056-4f09-be98-fe757842a89b", + "type": "point", + "x": 666.8, + "y": -8.362 + }, + { + "id": "fdb2142d-2115-488a-ae74-f0d370d47868", + "type": "point", + "x": 514.381, + "y": -93.767 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + } + } + }, + { + "id": "180123fb-e16a-41d4-a9f5-aebebcb99603", + "type": "diagram-nodes", + "isSvg": false, + "transformed": true, + "models": { + "912ce164-3c9f-415e-b981-e334d0c1936a": { + "id": "912ce164-3c9f-415e-b981-e334d0c1936a", + "type": "custom-node", + "selected": false, + "extras": { + "type": "Start" + }, + "x": -72.643, + "y": -78.041, + "ports": [ + { + "id": "a1b94ed2-c63d-497f-9ebf-a16696db66c3", + "type": "default", + "extras": {}, + "x": -42.002, + "y": -53.727, + "name": "out-0", + "alignment": "right", + "parentNode": "912ce164-3c9f-415e-b981-e334d0c1936a", + "links": [ + "8e14bedb-4925-45e0-9c16-008e36726d84" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Start", + "color": "rgb(255,102,102)", + "portsInOrder": [], + "portsOutOrder": [ + "a1b94ed2-c63d-497f-9ebf-a16696db66c3" + ] + }, + "248f9fce-76bd-494d-8080-7784f3aed238": { + "id": "248f9fce-76bd-494d-8080-7784f3aed238", + "type": "custom-node", + "selected": false, + "extras": { + "type": "Finish", + "borderColor": "rgb(0,192,255)" + }, + "x": 760.85, + "y": -115.697, + "ports": [ + { + "id": "c08bb8fa-bce4-444a-b1b6-aa58947a56ee", + "type": "default", + "extras": {}, + "x": 762.326, + "y": -91.389, + "name": "in-0", + "alignment": "left", + "parentNode": "248f9fce-76bd-494d-8080-7784f3aed238", + "links": [ + "165f2b52-b217-48ec-9a79-9b903dd8ede3" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Finish", + "color": "rgb(255,102,102)", + "portsInOrder": [ + "c08bb8fa-bce4-444a-b1b6-aa58947a56ee" + ], + "portsOutOrder": [] + }, + "972dea3c-2f6a-4a06-a9f6-1c5c78b83f67": { + "id": "972dea3c-2f6a-4a06-a9f6-1c5c78b83f67", + "type": "custom-node", + "selected": false, + "extras": { + "type": "boolean" + }, + "x": -65.778, + "y": -1.687, + "ports": [ + { + "id": "ebb1ed28-1e41-4789-bbef-48a98fae40f4", + "type": "default", + "extras": {}, + "x": -14.306, + "y": 22.627, + "name": "out-0", + "alignment": "right", + "parentNode": "972dea3c-2f6a-4a06-a9f6-1c5c78b83f67", + "links": [ + "b5102f00-b881-4321-8edc-74085d1401c3" + ], + "in": false, + "label": "True", + "varName": "True", + "portType": "", + "dataType": "" + } + ], + "name": "Literal True", + "color": "red", + "portsInOrder": [], + "portsOutOrder": [ + "ebb1ed28-1e41-4789-bbef-48a98fae40f4" + ] + }, + "81b23b24-1bf5-45d9-b955-c0f309a52d1f": { + "id": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_controlflow/branches.py", + "description": null, + "lineNo": [ + { + "lineno": 4, + "end_lineno": 20 + } + ], + "finishNodeId": "4acc1826-cb0f-4ad0-b498-8211eeb8b86b", + "isBranchNode": true + }, + "x": 80.852, + "y": -70.268, + "ports": [ + { + "id": "9aeb9ea8-af99-4528-a05d-df676958d7d7", + "type": "default", + "extras": {}, + "x": 82.326, + "y": -45.961, + "name": "in-0", + "alignment": "left", + "parentNode": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "links": [ + "8e14bedb-4925-45e0-9c16-008e36726d84" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "feac004e-83ff-49e4-a82b-937618fe62e3", + "type": "default", + "extras": {}, + "x": 82.326, + "y": -29.977, + "name": "parameter-boolean-condition", + "alignment": "left", + "parentNode": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "links": [ + "b5102f00-b881-4321-8edc-74085d1401c3" + ], + "in": true, + "label": "condition", + "varName": "condition", + "portType": "", + "dataType": "boolean" + }, + { + "id": "86ecf10e-6896-4963-93ec-bd4051686f97", + "type": "default", + "extras": {}, + "x": 256.111, + "y": -45.961, + "name": "out-0", + "alignment": "right", + "parentNode": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "links": [ + "02b61f41-cb12-4ae5-abc0-e795dfd311ff" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "819341fd-b01a-4c99-b4b3-755c051d8ab9", + "type": "default", + "extras": {}, + "x": 256.111, + "y": -29.977, + "name": "out-flow-when_true", + "alignment": "right", + "parentNode": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "links": [ + "52d7c6a0-b630-481f-ae54-13c302be4afa" + ], + "in": false, + "label": "when_true ▶", + "varName": "when_true ▶", + "portType": "", + "dataType": "" + }, + { + "id": "a304e3f7-4951-4fc1-a3af-c98af87adce2", + "type": "default", + "extras": {}, + "x": 256.111, + "y": -13.993, + "name": "out-flow-when_false", + "alignment": "right", + "parentNode": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "links": [ + "a073139c-99e8-44ca-884f-c25c5a6b47f8" + ], + "in": false, + "label": "when_false ▶", + "varName": "when_false ▶", + "portType": "", + "dataType": "" + } + ], + "name": "BranchComponent", + "color": "rgb(102,102,102)", + "portsInOrder": [ + "9aeb9ea8-af99-4528-a05d-df676958d7d7", + "feac004e-83ff-49e4-a82b-937618fe62e3" + ], + "portsOutOrder": [ + "86ecf10e-6896-4963-93ec-bd4051686f97", + "819341fd-b01a-4c99-b4b3-755c051d8ab9", + "a304e3f7-4951-4fc1-a3af-c98af87adce2" + ] + }, + "4acc1826-cb0f-4ad0-b498-8211eeb8b86b": { + "id": "4acc1826-cb0f-4ad0-b498-8211eeb8b86b", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_utils/utils.py", + "description": null, + "lineNo": [ + { + "lineno": 9, + "end_lineno": 13 + } + ], + "nextNode": "None" + }, + "x": 505.415, + "y": -141.559, + "ports": [ + { + "id": "f1bce6a3-a6d7-48de-91cd-57e74d76a600", + "type": "default", + "extras": {}, + "x": 506.887, + "y": -117.245, + "name": "in-0", + "alignment": "left", + "parentNode": "4acc1826-cb0f-4ad0-b498-8211eeb8b86b", + "links": [ + "02b61f41-cb12-4ae5-abc0-e795dfd311ff" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "5891450f-19c0-48ea-b9ff-448c7289f483", + "type": "default", + "extras": {}, + "x": 506.887, + "y": -101.262, + "name": "parameter-any-msg", + "alignment": "left", + "parentNode": "4acc1826-cb0f-4ad0-b498-8211eeb8b86b", + "links": [ + "a9aa5d24-f307-4558-959f-fafb42101011" + ], + "in": true, + "label": "msg", + "varName": "msg", + "portType": "", + "dataType": "any" + }, + { + "id": "c7ea79b0-ce26-4e5a-bae3-12817dccc4d9", + "type": "default", + "extras": {}, + "x": 598.773, + "y": -117.245, + "name": "out-0", + "alignment": "right", + "parentNode": "4acc1826-cb0f-4ad0-b498-8211eeb8b86b", + "links": [ + "165f2b52-b217-48ec-9a79-9b903dd8ede3" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Print", + "color": "rgb(255,102,102)", + "portsInOrder": [ + "f1bce6a3-a6d7-48de-91cd-57e74d76a600", + "5891450f-19c0-48ea-b9ff-448c7289f483" + ], + "portsOutOrder": [ + "c7ea79b0-ce26-4e5a-bae3-12817dccc4d9" + ] + }, + "a78e6da4-5bc8-49f5-8d03-353678fb130e": { + "id": "a78e6da4-5bc8-49f5-8d03-353678fb130e", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_utils/utils.py", + "description": null, + "lineNo": [ + { + "lineno": 9, + "end_lineno": 13 + } + ], + "sourceBranchId": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "portId": "a304e3f7-4951-4fc1-a3af-c98af87adce2", + "nextNode": "None" + }, + "x": 210.063, + "y": 101.636, + "ports": [ + { + "id": "dba10cdb-c880-4752-9d51-64e509d735f1", + "type": "default", + "extras": {}, + "x": 211.539, + "y": 125.937, + "name": "in-0", + "alignment": "left", + "parentNode": "a78e6da4-5bc8-49f5-8d03-353678fb130e", + "links": [ + "a073139c-99e8-44ca-884f-c25c5a6b47f8" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "67968fee-a315-4d02-a80e-10be786bd4f7", + "type": "default", + "extras": {}, + "x": 211.539, + "y": 141.921, + "name": "parameter-any-msg", + "alignment": "left", + "parentNode": "a78e6da4-5bc8-49f5-8d03-353678fb130e", + "links": [ + "9ba321f6-69e5-457c-b939-5e68c24a4cb0" + ], + "in": true, + "label": "msg", + "varName": "msg", + "portType": "", + "dataType": "any" + }, + { + "id": "626289b5-5d32-4117-bf2e-4231cc513d2d", + "type": "default", + "extras": {}, + "x": 303.426, + "y": 125.937, + "name": "out-0", + "alignment": "right", + "parentNode": "a78e6da4-5bc8-49f5-8d03-353678fb130e", + "links": [], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Print", + "color": "rgb(255,102,102)", + "portsInOrder": [ + "dba10cdb-c880-4752-9d51-64e509d735f1", + "67968fee-a315-4d02-a80e-10be786bd4f7" + ], + "portsOutOrder": [ + "626289b5-5d32-4117-bf2e-4231cc513d2d" + ] + }, + "9691f88e-a4d4-481e-b911-b20f8757bb58": { + "id": "9691f88e-a4d4-481e-b911-b20f8757bb58", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_utils/utils.py", + "description": null, + "lineNo": [ + { + "lineno": 9, + "end_lineno": 13 + } + ], + "borderColor": "rgb(0,192,255)", + "sourceBranchId": "81b23b24-1bf5-45d9-b955-c0f309a52d1f", + "portId": "819341fd-b01a-4c99-b4b3-755c051d8ab9", + "nextNode": "None" + }, + "x": 453.835, + "y": 91.073, + "ports": [ + { + "id": "a0a3fcc7-1126-4a02-9d2f-c916949858fb", + "type": "default", + "extras": {}, + "x": 455.312, + "y": 115.37, + "name": "in-0", + "alignment": "left", + "parentNode": "9691f88e-a4d4-481e-b911-b20f8757bb58", + "links": [ + "52d7c6a0-b630-481f-ae54-13c302be4afa" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "ce84d4f1-c073-4009-92b8-fc2ae7293e86", + "type": "default", + "extras": {}, + "x": 455.312, + "y": 131.354, + "name": "parameter-any-msg", + "alignment": "left", + "parentNode": "9691f88e-a4d4-481e-b911-b20f8757bb58", + "links": [ + "017d89bd-4611-4399-93bf-97bb6fb91179" + ], + "in": true, + "label": "msg", + "varName": "msg", + "portType": "", + "dataType": "any" + }, + { + "id": "de703d56-8f67-476a-bcc4-3ba44c09bb6a", + "type": "default", + "extras": {}, + "x": 547.199, + "y": 115.37, + "name": "out-0", + "alignment": "right", + "parentNode": "9691f88e-a4d4-481e-b911-b20f8757bb58", + "links": [], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Print", + "color": "rgb(255,102,102)", + "portsInOrder": [ + "a0a3fcc7-1126-4a02-9d2f-c916949858fb", + "ce84d4f1-c073-4009-92b8-fc2ae7293e86" + ], + "portsOutOrder": [ + "de703d56-8f67-476a-bcc4-3ba44c09bb6a" + ] + }, + "408266c4-3f7f-46cc-87e7-9aa8d2c13b71": { + "id": "408266c4-3f7f-46cc-87e7-9aa8d2c13b71", + "type": "custom-node", + "selected": false, + "extras": { + "type": "string" + }, + "x": -94.705, + "y": 97.074, + "ports": [ + { + "id": "bc57bc5f-032f-4bf0-985d-fd47bc26fd5e", + "type": "default", + "extras": {}, + "x": 132.049, + "y": 121.377, + "name": "out-0", + "alignment": "right", + "parentNode": "408266c4-3f7f-46cc-87e7-9aa8d2c13b71", + "links": [ + "9ba321f6-69e5-457c-b939-5e68c24a4cb0" + ], + "in": false, + "label": "This will be printed if the condition is false!", + "varName": "This will be printed if the condition is false!", + "portType": "", + "dataType": "" + } + ], + "name": "Literal String", + "color": "lightpink", + "portsInOrder": [], + "portsOutOrder": [ + "bc57bc5f-032f-4bf0-985d-fd47bc26fd5e" + ] + }, + "d06b3ef8-2fb0-4aa0-8084-3aa44772083c": { + "id": "d06b3ef8-2fb0-4aa0-8084-3aa44772083c", + "type": "custom-node", + "selected": false, + "extras": { + "type": "string" + }, + "x": 158.743, + "y": 214.229, + "ports": [ + { + "id": "a9a6ae1c-e8fa-43b9-bf16-d71d2487519d", + "type": "default", + "extras": {}, + "x": 381.204, + "y": 238.53, + "name": "out-0", + "alignment": "right", + "parentNode": "d06b3ef8-2fb0-4aa0-8084-3aa44772083c", + "links": [ + "017d89bd-4611-4399-93bf-97bb6fb91179" + ], + "in": false, + "label": "This will be printed if the condition is true!", + "varName": "This will be printed if the condition is true!", + "portType": "", + "dataType": "" + } + ], + "name": "Literal String", + "color": "lightpink", + "portsInOrder": [], + "portsOutOrder": [ + "a9a6ae1c-e8fa-43b9-bf16-d71d2487519d" + ] + }, + "d344f75e-5ae6-4c13-b7ac-88a0f9e04c23": { + "id": "d344f75e-5ae6-4c13-b7ac-88a0f9e04c23", + "type": "custom-node", + "selected": false, + "extras": { + "type": "string" + }, + "x": 393.325, + "y": -44.524, + "ports": [ + { + "id": "49287324-16df-4968-a3cf-32d5d033d1b7", + "type": "default", + "extras": {}, + "x": 659.306, + "y": -15.856, + "name": "out-0", + "alignment": "right", + "parentNode": "d344f75e-5ae6-4c13-b7ac-88a0f9e04c23", + "links": [ + "a9aa5d24-f307-4558-959f-fafb42101011" + ], + "in": false, + "label": "This will always be executed at the end of the branch!", + "varName": "This will always be executed at the end of the branch!", + "portType": "", + "dataType": "" + } + ], + "name": "Literal String", + "color": "lightpink", + "portsInOrder": [], + "portsOutOrder": [ + "49287324-16df-4968-a3cf-32d5d033d1b7" + ] + }, + "0ba1f2f6-5137-4387-bdfb-fdf351bc2d45": { + "id": "0ba1f2f6-5137-4387-bdfb-fdf351bc2d45", + "type": "custom-node", + "selected": true, + "extras": { + "type": "comment", + "commentInput": "For more controlflow examples,\ncheck out the controlflow library!" + }, + "x": 534.814, + "y": 213.023, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "4f316462-ca7b-401f-b019-d8e943c98e69": { + "id": "4f316462-ca7b-401f-b019-d8e943c98e69", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "A controlflow component is a node\nthat has multiple out ▶ ports." + }, + "x": 80.394, + "y": -201.62, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + } + } + } + ] +} \ No newline at end of file diff --git a/xircuits-graph-viewer/docs/static/workflows/HelloXircuits.xircuits b/xircuits-graph-viewer/docs/static/workflows/HelloXircuits.xircuits new file mode 100644 index 00000000..4a2aa53e --- /dev/null +++ b/xircuits-graph-viewer/docs/static/workflows/HelloXircuits.xircuits @@ -0,0 +1,623 @@ +{ + "id": "11b9d835-f7c3-4b78-a927-bec01ae39956", + "offsetX": 138.70289808530393, + "offsetY": 112.11086262472926, + "zoom": 62.96296034657244, + "gridSize": 0, + "layers": [ + { + "id": "e8c7e3ab-cc6d-4d15-8c15-25b3b24cacd0", + "type": "diagram-links", + "isSvg": true, + "transformed": true, + "models": { + "0c51cfd5-b730-488b-a722-a7a93528866e": { + "id": "0c51cfd5-b730-488b-a722-a7a93528866e", + "type": "triangle-link", + "selected": false, + "source": "15df3e50-91c2-47a1-9c48-59f040abc728", + "sourcePort": "1bfb241e-2860-4cd8-887c-ace64dc6b9da", + "target": "16949768-609b-4f49-9637-1362acd39ebe", + "targetPort": "40888689-6dc0-4d53-bdbf-f74cd85f7e47", + "points": [ + { + "id": "0ddd19f6-a0da-440f-a802-3932fb342c9a", + "type": "point", + "x": 193.281, + "y": 118.015 + }, + { + "id": "22ff1dfd-b7f5-4ce9-b642-296b831d0fdf", + "type": "point", + "x": 353.929, + "y": 196.811 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "901eb298-883a-4803-9fca-d3ed4f926688": { + "id": "901eb298-883a-4803-9fca-d3ed4f926688", + "type": "triangle-link", + "selected": false, + "source": "16949768-609b-4f49-9637-1362acd39ebe", + "sourcePort": "13ff60b4-096f-43ac-9f8d-fd7eb6c68b00", + "target": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "targetPort": "e4118ad4-6463-45d0-acfe-278473f33171", + "points": [ + { + "id": "c3b6116d-aaf4-459e-9c1d-2eac10f71110", + "type": "point", + "x": 454.253, + "y": 196.811 + }, + { + "id": "7640dc8e-dddc-4cd2-ac4f-e800452a3f2b", + "type": "point", + "x": 708.119, + "y": 276.568 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "11ae19ab-0615-4e3f-ba1d-6dea826154b3": { + "id": "11ae19ab-0615-4e3f-ba1d-6dea826154b3", + "type": "triangle-link", + "selected": false, + "source": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "sourcePort": "8d80f536-fec5-41ca-a82a-23972097d32f", + "target": "4f6b8a78-d1a9-4510-b31e-131531a3ce23", + "targetPort": "738f2d81-79ca-414f-a6c3-43ebcdc825b4", + "points": [ + { + "id": "e8436c2a-9c79-41f5-ae34-5c6c90852abe", + "type": "point", + "x": 800.006, + "y": 276.568 + }, + { + "id": "f692f0e3-1d03-4ebf-9e2f-c5eaa5c2152b", + "type": "point", + "x": 927.448, + "y": 408.385 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "9d08656b-7508-4eae-a449-f50a3a125289": { + "id": "9d08656b-7508-4eae-a449-f50a3a125289", + "type": "parameter-link", + "selected": false, + "source": "7affbe5e-678b-4a5c-ad27-c5c4a12fc733", + "sourcePort": "bef4edd7-d310-463f-8ac3-dba1fb71e80e", + "target": "16949768-609b-4f49-9637-1362acd39ebe", + "targetPort": "d487a5cd-ffe5-4fba-800f-4651634f1ff5", + "points": [ + { + "id": "16128708-cec8-4c5c-aa18-eccc1d8aae67", + "type": "point", + "x": 201.892, + "y": 495.92 + }, + { + "id": "c6baf25d-ff3d-40c2-b43e-0430d3a05514", + "type": "point", + "x": 353.929, + "y": 228.779 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "14625014-44cf-4966-b34f-7b5d2023afe6": { + "id": "14625014-44cf-4966-b34f-7b5d2023afe6", + "type": "parameter-link", + "selected": false, + "source": "16949768-609b-4f49-9637-1362acd39ebe", + "sourcePort": "625956f7-cee1-4476-a9e7-ea34af1805d2", + "target": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "targetPort": "57336bb8-dbbf-48d2-88ac-2de9f15d6df6", + "points": [ + { + "id": "b92a9e9d-47ca-45df-b50b-2725a1077ab2", + "type": "point", + "x": 454.253, + "y": 212.795 + }, + { + "id": "1d373617-9c69-4839-aea5-ec027d58b4d3", + "type": "point", + "x": 708.119, + "y": 292.552 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + }, + "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f": { + "id": "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f", + "type": "parameter-link", + "selected": false, + "source": "bd066e96-970a-4477-86c7-fdc2dc88c4a1", + "sourcePort": "d9cf851b-f1de-4ab8-9244-9e8b24399ffd", + "target": "16949768-609b-4f49-9637-1362acd39ebe", + "targetPort": "14fbc718-0f8f-4c0b-bc47-4ac837d39b27", + "points": [ + { + "id": "86e6c64b-d0b2-40e3-b746-dc56b9c2e56b", + "type": "point", + "x": 200.295, + "y": 422.066 + }, + { + "id": "fd5a730e-8422-4d27-95fb-b954065393ca", + "type": "point", + "x": 353.929, + "y": 212.795 + } + ], + "labels": [], + "width": 3, + "color": "gray", + "curvyness": 50, + "selectedColor": "rgb(0,192,255)" + } + } + }, + { + "id": "b1e2c329-efb4-4370-8927-38e61e23c5d2", + "type": "diagram-nodes", + "isSvg": false, + "transformed": true, + "models": { + "15df3e50-91c2-47a1-9c48-59f040abc728": { + "id": "15df3e50-91c2-47a1-9c48-59f040abc728", + "type": "custom-node", + "selected": false, + "extras": { + "type": "Start", + "borderColor": "rgb(0,192,255)" + }, + "x": 155.159, + "y": 86.223, + "ports": [ + { + "id": "1bfb241e-2860-4cd8-887c-ace64dc6b9da", + "type": "default", + "extras": {}, + "x": 185.787, + "y": 110.521, + "name": "out-0", + "alignment": "right", + "parentNode": "15df3e50-91c2-47a1-9c48-59f040abc728", + "links": [ + "0c51cfd5-b730-488b-a722-a7a93528866e" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Start", + "color": "rgb(255,102,102)", + "portsInOrder": [], + "portsOutOrder": [ + "1bfb241e-2860-4cd8-887c-ace64dc6b9da" + ] + }, + "4f6b8a78-d1a9-4510-b31e-131531a3ce23": { + "id": "4f6b8a78-d1a9-4510-b31e-131531a3ce23", + "type": "custom-node", + "selected": false, + "extras": { + "type": "Finish", + "borderColor": "rgb(0,192,255)" + }, + "x": 918.478, + "y": 376.596, + "ports": [ + { + "id": "738f2d81-79ca-414f-a6c3-43ebcdc825b4", + "type": "default", + "extras": {}, + "x": 919.954, + "y": 400.891, + "name": "in-0", + "alignment": "left", + "parentNode": "4f6b8a78-d1a9-4510-b31e-131531a3ce23", + "links": [ + "11ae19ab-0615-4e3f-ba1d-6dea826154b3" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Finish", + "color": "rgb(255,102,102)", + "portsInOrder": [ + "738f2d81-79ca-414f-a6c3-43ebcdc825b4" + ], + "portsOutOrder": [] + }, + "7affbe5e-678b-4a5c-ad27-c5c4a12fc733": { + "id": "7affbe5e-678b-4a5c-ad27-c5c4a12fc733", + "type": "custom-node", + "selected": false, + "extras": { + "type": "string" + }, + "x": 133.861, + "y": 464.122, + "ports": [ + { + "id": "bef4edd7-d310-463f-8ac3-dba1fb71e80e", + "type": "default", + "extras": {}, + "x": 194.398, + "y": 488.426, + "name": "out-0", + "alignment": "right", + "parentNode": "7affbe5e-678b-4a5c-ad27-c5c4a12fc733", + "links": [ + "9d08656b-7508-4eae-a449-f50a3a125289" + ], + "in": false, + "label": "Xircuits!", + "varName": "Xircuits!", + "portType": "", + "dataType": "" + } + ], + "name": "Literal String", + "color": "lightpink", + "portsInOrder": [], + "portsOutOrder": [ + "bef4edd7-d310-463f-8ac3-dba1fb71e80e" + ] + }, + "bd066e96-970a-4477-86c7-fdc2dc88c4a1": { + "id": "bd066e96-970a-4477-86c7-fdc2dc88c4a1", + "type": "custom-node", + "selected": false, + "extras": { + "type": "string" + }, + "x": 134.61, + "y": 390.271, + "ports": [ + { + "id": "d9cf851b-f1de-4ab8-9244-9e8b24399ffd", + "type": "default", + "extras": {}, + "x": 192.801, + "y": 414.572, + "name": "out-0", + "alignment": "right", + "parentNode": "bd066e96-970a-4477-86c7-fdc2dc88c4a1", + "links": [ + "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f" + ], + "in": false, + "label": "Hello ", + "varName": "Hello ", + "portType": "", + "dataType": "" + } + ], + "name": "Literal String", + "color": "lightpink", + "portsInOrder": [], + "portsOutOrder": [ + "d9cf851b-f1de-4ab8-9244-9e8b24399ffd" + ] + }, + "16949768-609b-4f49-9637-1362acd39ebe": { + "id": "16949768-609b-4f49-9637-1362acd39ebe", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_utils/utils.py", + "description": null, + "lineNo": [ + { + "lineno": 16, + "end_lineno": 22 + } + ] + }, + "x": 344.958, + "y": 165.014, + "ports": [ + { + "id": "40888689-6dc0-4d53-bdbf-f74cd85f7e47", + "type": "default", + "extras": {}, + "x": 346.435, + "y": 189.317, + "name": "in-0", + "alignment": "left", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "0c51cfd5-b730-488b-a722-a7a93528866e" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "14fbc718-0f8f-4c0b-bc47-4ac837d39b27", + "type": "default", + "extras": {}, + "x": 346.435, + "y": 205.301, + "name": "parameter-string-a", + "alignment": "left", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "fd5f44a5-80b1-4b70-9e05-a6922ed2b49f" + ], + "in": true, + "label": "a", + "varName": "a", + "portType": "", + "dataType": "string" + }, + { + "id": "d487a5cd-ffe5-4fba-800f-4651634f1ff5", + "type": "default", + "extras": {}, + "x": 346.435, + "y": 221.285, + "name": "parameter-string-b", + "alignment": "left", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "9d08656b-7508-4eae-a449-f50a3a125289" + ], + "in": true, + "label": "b", + "varName": "b", + "portType": "", + "dataType": "string" + }, + { + "id": "13ff60b4-096f-43ac-9f8d-fd7eb6c68b00", + "type": "default", + "extras": {}, + "x": 446.759, + "y": 189.317, + "name": "out-0", + "alignment": "right", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "901eb298-883a-4803-9fca-d3ed4f926688" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "625956f7-cee1-4476-a9e7-ea34af1805d2", + "type": "default", + "extras": {}, + "x": 446.759, + "y": 205.301, + "name": "parameter-out-string-out", + "alignment": "right", + "parentNode": "16949768-609b-4f49-9637-1362acd39ebe", + "links": [ + "14625014-44cf-4966-b34f-7b5d2023afe6" + ], + "in": false, + "label": "out", + "varName": "out", + "portType": "", + "dataType": "" + } + ], + "name": "ConcatString", + "color": "rgb(153,51,204)", + "portsInOrder": [ + "40888689-6dc0-4d53-bdbf-f74cd85f7e47", + "14fbc718-0f8f-4c0b-bc47-4ac837d39b27", + "d487a5cd-ffe5-4fba-800f-4651634f1ff5" + ], + "portsOutOrder": [ + "13ff60b4-096f-43ac-9f8d-fd7eb6c68b00", + "625956f7-cee1-4476-a9e7-ea34af1805d2" + ] + }, + "c67603e4-dfda-4c58-b6ab-0952eba75254": { + "id": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "type": "custom-node", + "selected": false, + "extras": { + "type": "debug", + "path": "xai_components/xai_utils/utils.py", + "description": null, + "lineNo": [ + { + "lineno": 9, + "end_lineno": 13 + } + ] + }, + "x": 699.144, + "y": 244.771, + "ports": [ + { + "id": "e4118ad4-6463-45d0-acfe-278473f33171", + "type": "default", + "extras": {}, + "x": 700.625, + "y": 269.074, + "name": "in-0", + "alignment": "left", + "parentNode": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "links": [ + "901eb298-883a-4803-9fca-d3ed4f926688" + ], + "in": true, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + }, + { + "id": "57336bb8-dbbf-48d2-88ac-2de9f15d6df6", + "type": "default", + "extras": {}, + "x": 700.625, + "y": 285.058, + "name": "parameter-any-msg", + "alignment": "left", + "parentNode": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "links": [ + "14625014-44cf-4966-b34f-7b5d2023afe6" + ], + "in": true, + "label": "msg", + "varName": "msg", + "portType": "", + "dataType": "any" + }, + { + "id": "8d80f536-fec5-41ca-a82a-23972097d32f", + "type": "default", + "extras": {}, + "x": 792.512, + "y": 269.074, + "name": "out-0", + "alignment": "right", + "parentNode": "c67603e4-dfda-4c58-b6ab-0952eba75254", + "links": [ + "11ae19ab-0615-4e3f-ba1d-6dea826154b3" + ], + "in": false, + "label": "▶", + "varName": "▶", + "portType": "", + "dataType": "" + } + ], + "name": "Print", + "color": "rgb(102,51,102)", + "portsInOrder": [ + "e4118ad4-6463-45d0-acfe-278473f33171", + "57336bb8-dbbf-48d2-88ac-2de9f15d6df6" + ], + "portsOutOrder": [ + "8d80f536-fec5-41ca-a82a-23972097d32f" + ] + }, + "35a75ed7-cd63-45d0-83a8-82b6f2a1e295": { + "id": "35a75ed7-cd63-45d0-83a8-82b6f2a1e295", + "type": "custom-node", + "selected": true, + "extras": { + "type": "comment", + "commentInput": "[1] Xircuits workflows are designed around \n the concept of linking nodes and configuring \n them with specific parameters." + }, + "x": -2.913, + "y": -76.821, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "d64c2fc8-73a6-4f7e-a406-f491c2ce2bce": { + "id": "d64c2fc8-73a6-4f7e-a406-f491c2ce2bce", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[2] The blue flowing link connecting ▶ ports\n represent the sequence of execution." + }, + "x": 339.679, + "y": 51.942, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "ef86f386-48c9-456c-9b3c-7af11c9c4575": { + "id": "ef86f386-48c9-456c-9b3c-7af11c9c4575", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[4] You can also pass parameters \n from one component node to another." + }, + "x": 381.006, + "y": 339.556, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "f2c978ce-51d3-4327-a01b-2490500dffb4": { + "id": "f2c978ce-51d3-4327-a01b-2490500dffb4", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[3] Literals are one way of supplying parameters\n to your component node.\n You can double click literals to edit their value." + }, + "x": -143.813, + "y": 231.319, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + }, + "d4c2e2ce-f0dd-4104-9355-df2c96d0aa84": { + "id": "d4c2e2ce-f0dd-4104-9355-df2c96d0aa84", + "type": "custom-node", + "selected": false, + "extras": { + "type": "comment", + "commentInput": "[5] Once you're done, you can compile \n and execute the workflow." + }, + "x": 824.994, + "y": 456.905, + "ports": [], + "name": "Comment:", + "color": "rgb(255,255,255)", + "portsInOrder": [], + "portsOutOrder": [] + } + } + } + ] +} \ No newline at end of file diff --git a/xircuits-graph-viewer/packages/core/src/interaction/panZoom.ts b/xircuits-graph-viewer/packages/core/src/interaction/panZoom.ts index 123d1e35..6362376a 100644 --- a/xircuits-graph-viewer/packages/core/src/interaction/panZoom.ts +++ b/xircuits-graph-viewer/packages/core/src/interaction/panZoom.ts @@ -4,31 +4,32 @@ export interface PanZoomOptions { onViewportChange?: (viewport: { x: number; y: number; zoom: number }) => void; } +export interface PanZoomInstance { + destroy: () => void; + zoomBy: (factor: number) => void; + fitView: () => void; +} + export function attachPanZoom( svg: SVGSVGElement, options: PanZoomOptions = {}, -): { destroy: () => void } { +): PanZoomInstance { const { minZoom = 0.1, maxZoom = 4, onViewportChange } = options; - let viewBox = parseViewBox(svg); + const initialViewBox = readViewBox(); let isPanning = false; let startX = 0; let startY = 0; - let startVBX = 0; - let startVBY = 0; + let panStartVB = { x: 0, y: 0, w: 0, h: 0 }; - function parseViewBox(el: SVGSVGElement) { - const vb = el.getAttribute('viewBox')?.split(/\s+/).map(Number) || [0, 0, 800, 600]; + function readViewBox() { + const vb = svg.getAttribute('viewBox')?.split(/\s+/).map(Number) || [0, 0, 800, 600]; return { x: vb[0], y: vb[1], w: vb[2], h: vb[3] }; } - function updateViewBox() { - svg.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`); - onViewportChange?.({ - x: viewBox.x, - y: viewBox.y, - zoom: svg.clientWidth / viewBox.w, - }); + function writeViewBox(vb: { x: number; y: number; w: number; h: number }) { + svg.setAttribute('viewBox', `${vb.x} ${vb.y} ${vb.w} ${vb.h}`); + onViewportChange?.({ x: vb.x, y: vb.y, zoom: svg.clientWidth / vb.w }); } function onWheel(e: WheelEvent) { @@ -36,22 +37,24 @@ export function attachPanZoom( const rect = svg.getBoundingClientRect(); const mx = (e.clientX - rect.left) / rect.width; const my = (e.clientY - rect.top) / rect.height; - const factor = e.deltaY > 0 ? 1.1 : 0.9; - const newW = viewBox.w * factor; - const newH = viewBox.h * factor; + applyZoom(factor, mx, my); + } - // Enforce zoom limits - const currentZoom = svg.clientWidth / viewBox.w; + function applyZoom(factor: number, anchorX = 0.5, anchorY = 0.5) { + const vb = readViewBox(); + const newW = vb.w * factor; + const newH = vb.h * factor; + + const currentZoom = svg.clientWidth / vb.w; const newZoom = svg.clientWidth / newW; if (newZoom < minZoom || newZoom > maxZoom) return; - viewBox.x += (viewBox.w - newW) * mx; - viewBox.y += (viewBox.h - newH) * my; - viewBox.w = newW; - viewBox.h = newH; - - updateViewBox(); + vb.x += (vb.w - newW) * anchorX; + vb.y += (vb.h - newH) * anchorY; + vb.w = newW; + vb.h = newH; + writeViewBox(vb); } function onPointerDown(e: PointerEvent) { @@ -59,8 +62,7 @@ export function attachPanZoom( isPanning = true; startX = e.clientX; startY = e.clientY; - startVBX = viewBox.x; - startVBY = viewBox.y; + panStartVB = readViewBox(); svg.setPointerCapture(e.pointerId); svg.style.cursor = 'grabbing'; } @@ -68,11 +70,10 @@ export function attachPanZoom( function onPointerMove(e: PointerEvent) { if (!isPanning) return; const rect = svg.getBoundingClientRect(); - const dx = (e.clientX - startX) / rect.width * viewBox.w; - const dy = (e.clientY - startY) / rect.height * viewBox.h; - viewBox.x = startVBX - dx; - viewBox.y = startVBY - dy; - updateViewBox(); + const vb = panStartVB; + const dx = (e.clientX - startX) / rect.width * vb.w; + const dy = (e.clientY - startY) / rect.height * vb.h; + writeViewBox({ x: vb.x - dx, y: vb.y - dy, w: vb.w, h: vb.h }); } function onPointerUp(e: PointerEvent) { @@ -95,5 +96,11 @@ export function attachPanZoom( svg.removeEventListener('pointermove', onPointerMove); svg.removeEventListener('pointerup', onPointerUp); }, + zoomBy(factor: number) { + applyZoom(factor); + }, + fitView() { + writeViewBox(initialViewBox); + }, }; } diff --git a/xircuits-graph-viewer/upload-demo/main.js b/xircuits-graph-viewer/upload-demo/main.js index d1815a4b..767412ad 100644 --- a/xircuits-graph-viewer/upload-demo/main.js +++ b/xircuits-graph-viewer/upload-demo/main.js @@ -16,8 +16,7 @@ const fitBtn = document.getElementById('fit'); const controls = document.getElementById('controls'); // Store the current SVG element and viewBox for zoom/fit -let currentSvg = null; -let originalViewBox = null; +let panZoom = null; function renderGraph(json, name) { currentJson = json; @@ -30,9 +29,9 @@ function renderGraph(json, name) { return; } - if (cleanupPanZoom) { - cleanupPanZoom(); - cleanupPanZoom = null; + if (panZoom) { + panZoom.destroy(); + panZoom = null; } const svg = renderToElement(graph, { @@ -41,38 +40,25 @@ function renderGraph(json, name) { padding: 50, }); - // Apply container background (dot grid) viewer.style.cssText = getCanvasStyle(currentTheme); viewer.innerHTML = ''; viewer.appendChild(svg); - // Make SVG fill the container svg.style.width = '100%'; svg.style.height = '100%'; - currentSvg = svg; - originalViewBox = svg.getAttribute('viewBox'); - - cleanupPanZoom = attachPanZoom(svg).destroy; + panZoom = attachPanZoom(svg); controls.style.display = 'flex'; if (name) filenameEl.textContent = name; } function zoomBy(factor) { - if (!currentSvg) return; - const vb = currentSvg.getAttribute('viewBox').split(/\s+/).map(Number); - const cx = vb[0] + vb[2] / 2; - const cy = vb[1] + vb[3] / 2; - const newW = vb[2] * factor; - const newH = vb[3] * factor; - currentSvg.setAttribute('viewBox', - `${cx - newW / 2} ${cy - newH / 2} ${newW} ${newH}`); + panZoom?.zoomBy(factor); } function fitView() { - if (!currentSvg || !originalViewBox) return; - currentSvg.setAttribute('viewBox', originalViewBox); + panZoom?.fitView(); } function handleFile(file) { From 36ad854526672b5da43a88660bc2b1d2c7b08ac7 Mon Sep 17 00:00:00 2001 From: MFA-X-AI Date: Tue, 7 Apr 2026 14:04:08 +0900 Subject: [PATCH 3/9] rename packages to @xpressai/xircuits-viewer and @xpressai/xircuits-viewer-react --- xircuits-graph-viewer/README.md | 26 +++++++++---------- xircuits-graph-viewer/demo/package.json | 4 +-- xircuits-graph-viewer/demo/src/App.tsx | 2 +- .../src/components/WorkflowViewerInner.js | 4 +-- .../packages/core/package.json | 2 +- .../packages/react/package.json | 4 +-- .../packages/react/src/XircuitsGraph.tsx | 6 ++--- .../react/src/XircuitsGraphStatic.tsx | 2 +- xircuits-graph-viewer/upload-demo/main.js | 4 +-- .../upload-demo/package.json | 2 +- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/xircuits-graph-viewer/README.md b/xircuits-graph-viewer/README.md index 8e99e53f..ad32b914 100644 --- a/xircuits-graph-viewer/README.md +++ b/xircuits-graph-viewer/README.md @@ -8,8 +8,8 @@ Pure SVG renderer for `.xircuits` workflow files. Parses the JSON format and pro | Package | npm | Purpose | |---------|-----|---------| -| `xircuits-graph-core` | [![npm](https://img.shields.io/npm/v/xircuits-graph-core)](https://www.npmjs.com/package/xircuits-graph-core) | Parser + SVG renderer. Zero runtime deps. | -| `xircuits-graph-react` | [![npm](https://img.shields.io/npm/v/xircuits-graph-react)](https://www.npmjs.com/package/xircuits-graph-react) | React components (interactive + SSR-safe). | +| `@xpressai/xircuits-viewer` | [![npm](https://img.shields.io/npm/v/@xpressai/xircuits-viewer)](https://www.npmjs.com/package/@xpressai/xircuits-viewer) | Parser + SVG renderer. Zero runtime deps. | +| `@xpressai/xircuits-viewer-react` | [![npm](https://img.shields.io/npm/v/@xpressai/xircuits-viewer-react)](https://www.npmjs.com/package/@xpressai/xircuits-viewer-react) | React components (interactive + SSR-safe). | | `docusaurus-plugin-xircuits` | *coming soon* | Docusaurus plugin — drop-in `` for docs. | ## Quick Start @@ -17,13 +17,13 @@ Pure SVG renderer for `.xircuits` workflow files. Parses the JSON format and pro ### React ```bash -npm install xircuits-graph-core xircuits-graph-react +npm install @xpressai/xircuits-viewer @xpressai/xircuits-viewer-react ``` **Point it at a `.xircuits` file** — that's it: ```tsx -import { XircuitsGraph } from 'xircuits-graph-react'; +import { XircuitsGraph } from '@xpressai/xircuits-viewer-react'; // src accepts any URL: uploaded file path, API endpoint, static asset, etc. @@ -44,7 +44,7 @@ With options: **Static rendering** (SSR-safe, no client JS needed): ```tsx -import { XircuitsGraphStatic } from 'xircuits-graph-react'; +import { XircuitsGraphStatic } from '@xpressai/xircuits-viewer-react'; ``` @@ -62,13 +62,13 @@ import workflow from './MyWorkflow.xircuits'; Works with Svelte, Vue, plain HTML, Node.js — anything. ```bash -npm install xircuits-graph-core +npm install @xpressai/xircuits-viewer ``` **From a URL** (browser): ```js -import { renderFromUrl } from 'xircuits-graph-core'; +import { renderFromUrl } from '@xpressai/xircuits-viewer'; const svg = await renderFromUrl('/workflows/MyWorkflow.xircuits', { theme: 'dark' }); document.getElementById('viewer').innerHTML = svg; @@ -77,7 +77,7 @@ document.getElementById('viewer').innerHTML = svg; **From JSON data**: ```js -import { renderXircuits } from 'xircuits-graph-core'; +import { renderXircuits } from '@xpressai/xircuits-viewer'; const svg = renderXircuits(workflowJson, { theme: 'dark' }); ``` @@ -85,8 +85,8 @@ const svg = renderXircuits(workflowJson, { theme: 'dark' }); **With pan/zoom**: ```js -import { parse, renderToElement } from 'xircuits-graph-core'; -import { attachPanZoom } from 'xircuits-graph-core/interaction'; +import { parse, renderToElement } from '@xpressai/xircuits-viewer'; +import { attachPanZoom } from '@xpressai/xircuits-viewer/interaction'; const res = await fetch('/workflows/MyWorkflow.xircuits'); const svg = renderToElement(parse(await res.json()), { theme: 'dark' }); @@ -174,14 +174,14 @@ npm start ``` xircuits-graph-viewer/ ├── packages/ -│ ├── core/src/ # xircuits-graph-core (zero runtime deps) +│ ├── core/src/ # @xpressai/xircuits-viewer (zero runtime deps) │ │ ├── types.ts # XGraph, XNode, XEdge, XPort │ │ ├── parser/ # .xircuits JSON → XGraph │ │ ├── layout/ # Node metrics, viewBox computation │ │ ├── render/ # SVG generation (nodes, ports, edges, defs) │ │ ├── svg/ # Builder utilities, bezier curves │ │ └── interaction/ # Pan/zoom (browser-only) -│ └── react/src/ # xircuits-graph-react +│ └── react/src/ # @xpressai/xircuits-viewer-react │ ├── XircuitsGraph.tsx # Interactive (client-side) │ └── XircuitsGraphStatic.tsx # SSR-safe (string output) ├── upload-demo/ # Standalone drag-and-drop viewer @@ -198,7 +198,7 @@ cd packages/core && pnpm build cd ../react && pnpm build # Update workspace:* → actual version in react/package.json -# "xircuits-graph-core": "workspace:*" → "xircuits-graph-core": "^0.1.0" +# "@xpressai/xircuits-viewer": "workspace:*" → "@xpressai/xircuits-viewer": "^0.1.0" # Publish (core first, react depends on it) cd ../core && npm publish --access public diff --git a/xircuits-graph-viewer/demo/package.json b/xircuits-graph-viewer/demo/package.json index 1bf6b135..6e471a60 100644 --- a/xircuits-graph-viewer/demo/package.json +++ b/xircuits-graph-viewer/demo/package.json @@ -9,8 +9,8 @@ "dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1", - "xircuits-graph-core": "workspace:*", - "xircuits-graph-react": "workspace:*" + "@xpressai/xircuits-viewer": "workspace:*", + "@xpressai/xircuits-viewer-react": "workspace:*" }, "devDependencies": { "@types/react": "^18.3.12", diff --git a/xircuits-graph-viewer/demo/src/App.tsx b/xircuits-graph-viewer/demo/src/App.tsx index 18e818a0..c52a4442 100644 --- a/xircuits-graph-viewer/demo/src/App.tsx +++ b/xircuits-graph-viewer/demo/src/App.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { parse, renderToString } from 'xircuits-graph-core'; +import { parse, renderToString } from '@xpressai/xircuits-viewer'; import helloXircuits from './fixtures/HelloXircuits.xircuits'; export function App() { diff --git a/xircuits-graph-viewer/docs/src/components/WorkflowViewerInner.js b/xircuits-graph-viewer/docs/src/components/WorkflowViewerInner.js index 160c4d1d..78c6a6e5 100644 --- a/xircuits-graph-viewer/docs/src/components/WorkflowViewerInner.js +++ b/xircuits-graph-viewer/docs/src/components/WorkflowViewerInner.js @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useState, useCallback } from 'react'; -import { parse, renderToElement, getCanvasStyle } from 'xircuits-graph-core'; -import { attachPanZoom } from 'xircuits-graph-core/interaction'; +import { parse, renderToElement, getCanvasStyle } from '@xpressai/xircuits-viewer'; +import { attachPanZoom } from '@xpressai/xircuits-viewer/interaction'; import { useColorMode } from '@docusaurus/theme-common'; const ZoomInIcon = () => ( diff --git a/xircuits-graph-viewer/packages/core/package.json b/xircuits-graph-viewer/packages/core/package.json index 55c5f821..5aa95a49 100644 --- a/xircuits-graph-viewer/packages/core/package.json +++ b/xircuits-graph-viewer/packages/core/package.json @@ -1,5 +1,5 @@ { - "name": "xircuits-graph-core", + "name": "@xpressai/xircuits-viewer", "version": "0.1.0", "type": "module", "main": "./dist/index.js", diff --git a/xircuits-graph-viewer/packages/react/package.json b/xircuits-graph-viewer/packages/react/package.json index 74d8cf7e..f6f80bfb 100644 --- a/xircuits-graph-viewer/packages/react/package.json +++ b/xircuits-graph-viewer/packages/react/package.json @@ -1,5 +1,5 @@ { - "name": "xircuits-graph-react", + "name": "@xpressai/xircuits-viewer-react", "version": "0.1.0", "type": "module", "main": "./dist/index.js", @@ -19,7 +19,7 @@ "react": ">=18" }, "dependencies": { - "xircuits-graph-core": "workspace:*" + "@xpressai/xircuits-viewer": "workspace:*" }, "devDependencies": { "react": "^18.3.1", diff --git a/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx b/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx index 9ada6db4..43068161 100644 --- a/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx +++ b/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useRef, useState } from 'react'; -import { parse, renderToElement } from 'xircuits-graph-core'; -import { attachPanZoom } from 'xircuits-graph-core/interaction'; -import type { XNode, XEdge } from 'xircuits-graph-core'; +import { parse, renderToElement } from '@xpressai/xircuits-viewer'; +import { attachPanZoom } from '@xpressai/xircuits-viewer/interaction'; +import type { XNode, XEdge } from '@xpressai/xircuits-viewer'; export interface XircuitsGraphProps { /** URL or path to a .xircuits file. Fetched at mount time. */ diff --git a/xircuits-graph-viewer/packages/react/src/XircuitsGraphStatic.tsx b/xircuits-graph-viewer/packages/react/src/XircuitsGraphStatic.tsx index bac816d3..e5f11773 100644 --- a/xircuits-graph-viewer/packages/react/src/XircuitsGraphStatic.tsx +++ b/xircuits-graph-viewer/packages/react/src/XircuitsGraphStatic.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { parse, renderToString } from 'xircuits-graph-core'; +import { parse, renderToString } from '@xpressai/xircuits-viewer'; export interface XircuitsGraphStaticProps { /** URL or path to a .xircuits file. Fetched at mount time. */ diff --git a/xircuits-graph-viewer/upload-demo/main.js b/xircuits-graph-viewer/upload-demo/main.js index 767412ad..61a6bf61 100644 --- a/xircuits-graph-viewer/upload-demo/main.js +++ b/xircuits-graph-viewer/upload-demo/main.js @@ -1,5 +1,5 @@ -import { parse, renderToElement, getCanvasStyle } from 'xircuits-graph-core'; -import { attachPanZoom } from 'xircuits-graph-core/interaction'; +import { parse, renderToElement, getCanvasStyle } from '@xpressai/xircuits-viewer'; +import { attachPanZoom } from '@xpressai/xircuits-viewer/interaction'; let currentTheme = 'dark'; let currentJson = null; diff --git a/xircuits-graph-viewer/upload-demo/package.json b/xircuits-graph-viewer/upload-demo/package.json index a7cce80e..156d6c8a 100644 --- a/xircuits-graph-viewer/upload-demo/package.json +++ b/xircuits-graph-viewer/upload-demo/package.json @@ -7,7 +7,7 @@ "build": "vite build" }, "dependencies": { - "xircuits-graph-core": "file:../packages/core" + "@xpressai/xircuits-viewer": "file:../packages/core" }, "devDependencies": { "vite": "^6.3.1" From f438a8903c29dbf9d5d2c07e0f3c1c15f6db6d22 Mon Sep 17 00:00:00 2001 From: MFA-X-AI Date: Tue, 7 Apr 2026 14:19:51 +0900 Subject: [PATCH 4/9] Add package READMEs, publish script, bump to v0.1.1 --- xircuits-graph-viewer/packages/core/README.md | 86 +++++++++++++++++++ .../packages/core/package.json | 2 +- .../packages/react/README.md | 75 ++++++++++++++++ .../packages/react/package.json | 2 +- xircuits-graph-viewer/publish.sh | 31 +++++++ 5 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 xircuits-graph-viewer/packages/core/README.md create mode 100644 xircuits-graph-viewer/packages/react/README.md create mode 100755 xircuits-graph-viewer/publish.sh diff --git a/xircuits-graph-viewer/packages/core/README.md b/xircuits-graph-viewer/packages/core/README.md new file mode 100644 index 00000000..a16f5c75 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/README.md @@ -0,0 +1,86 @@ +# @xpressai/xircuits-viewer + +Pure SVG renderer for `.xircuits` workflow files. Zero runtime dependencies. Parses the JSON format and produces self-contained SVG that visually matches the Xircuits editor. + +![HelloXircuits rendered](https://raw.githubusercontent.com/XpressAI/xircuits/master/xircuits-graph-viewer/xircuits-hello.png) + +## Install + +```bash +npm install @xpressai/xircuits-viewer +``` + +## Usage + +### From a URL (browser) + +```js +import { renderFromUrl } from '@xpressai/xircuits-viewer'; + +const svg = await renderFromUrl('/workflows/MyWorkflow.xircuits', { theme: 'dark' }); +document.getElementById('viewer').innerHTML = svg; +``` + +### From JSON data + +```js +import { renderXircuits } from '@xpressai/xircuits-viewer'; + +const svg = renderXircuits(workflowJson, { theme: 'dark' }); +``` + +### With pan/zoom + +```js +import { parse, renderToElement } from '@xpressai/xircuits-viewer'; +import { attachPanZoom } from '@xpressai/xircuits-viewer/interaction'; + +const res = await fetch('/workflows/MyWorkflow.xircuits'); +const svg = renderToElement(parse(await res.json()), { theme: 'dark' }); +document.body.appendChild(svg); +const { destroy, zoomBy, fitView } = attachPanZoom(svg); +``` + +### Container background + +The SVG renders just the graph content. Apply the Xircuits dot-grid background on your container: + +```js +import { getCanvasStyle } from '@xpressai/xircuits-viewer'; + +container.style.cssText = getCanvasStyle('dark'); +``` + +## API + +| Function | Description | +|----------|-------------| +| `renderFromUrl(url, options?)` | Fetch a `.xircuits` URL and return SVG string | +| `renderXircuits(json, options?)` | Parse JSON + render to SVG string | +| `parse(json)` | Parse `.xircuits` JSON into `XGraph` | +| `renderToString(graph, options?)` | Render `XGraph` to SVG string | +| `renderToElement(graph, options?)` | Render `XGraph` to DOM `SVGSVGElement` | +| `validate(json)` | Validate without parsing | +| `getCanvasStyle(theme?)` | CSS string for the dot-grid container background | +| `attachPanZoom(svg, options?)` | Add pan/zoom, returns `{ destroy, zoomBy, fitView }` | + +### RenderOptions + +```ts +{ + theme?: 'dark' | 'light'; + width?: number; + height?: number; + padding?: number; + fitView?: boolean; + className?: string; +} +``` + +## React + +See [`@xpressai/xircuits-viewer-react`](https://www.npmjs.com/package/@xpressai/xircuits-viewer-react) for React components. + +## License + +MIT diff --git a/xircuits-graph-viewer/packages/core/package.json b/xircuits-graph-viewer/packages/core/package.json index 5aa95a49..abfe3480 100644 --- a/xircuits-graph-viewer/packages/core/package.json +++ b/xircuits-graph-viewer/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@xpressai/xircuits-viewer", - "version": "0.1.0", + "version": "0.1.1", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/xircuits-graph-viewer/packages/react/README.md b/xircuits-graph-viewer/packages/react/README.md new file mode 100644 index 00000000..cc401d4c --- /dev/null +++ b/xircuits-graph-viewer/packages/react/README.md @@ -0,0 +1,75 @@ +# @xpressai/xircuits-viewer-react + +React components for rendering `.xircuits` workflow files. Built on [`@xpressai/xircuits-viewer`](https://www.npmjs.com/package/@xpressai/xircuits-viewer). + +![HelloXircuits rendered](https://raw.githubusercontent.com/XpressAI/xircuits/master/xircuits-graph-viewer/xircuits-hello.png) + +## Install + +```bash +npm install @xpressai/xircuits-viewer @xpressai/xircuits-viewer-react +``` + +## Usage + +### Interactive (with pan/zoom) + +```tsx +import { XircuitsGraph } from '@xpressai/xircuits-viewer-react'; + +// Point it at a .xircuits file — that's it + +``` + +With options: + +```tsx + console.log(node.name)} +/> +``` + +### Static (SSR-safe) + +```tsx +import { XircuitsGraphStatic } from '@xpressai/xircuits-viewer-react'; + + +``` + +### Pre-loaded data + +```tsx +import workflow from './MyWorkflow.xircuits'; + + +``` + +## Props + +### XircuitsGraph + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `src` | `string` | — | URL to a `.xircuits` file | +| `data` | `object` | — | Pre-loaded JSON (takes precedence over `src`) | +| `theme` | `'dark' \| 'light'` | `'dark'` | Color theme | +| `interactive` | `boolean` | `true` | Enable pan/zoom | +| `height` | `number \| string` | `400` | Container height | +| `width` | `number \| string` | `'100%'` | Container width | +| `padding` | `number` | `40` | Viewport padding | +| `onNodeClick` | `(node) => void` | — | Node click handler | +| `onEdgeClick` | `(edge) => void` | — | Edge click handler | +| `onError` | `(error) => void` | — | Error handler | + +### XircuitsGraphStatic + +Same props as above, minus `interactive`, `onNodeClick`, `onEdgeClick`. + +## License + +MIT diff --git a/xircuits-graph-viewer/packages/react/package.json b/xircuits-graph-viewer/packages/react/package.json index f6f80bfb..3734c58e 100644 --- a/xircuits-graph-viewer/packages/react/package.json +++ b/xircuits-graph-viewer/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@xpressai/xircuits-viewer-react", - "version": "0.1.0", + "version": "0.1.1", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/xircuits-graph-viewer/publish.sh b/xircuits-graph-viewer/publish.sh new file mode 100755 index 00000000..1c53c9fe --- /dev/null +++ b/xircuits-graph-viewer/publish.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e + +DIR="$(cd "$(dirname "$0")" && pwd)" + +echo "==> Building core..." +cd "$DIR/packages/core" +npx tsc + +echo "==> Building react..." +cd "$DIR/packages/react" +npx tsc + +echo "==> Publishing @xpressai/xircuits-viewer..." +cd "$DIR/packages/core" +npm publish --access public + +# Get core version for react dependency +VERSION=$(node -p "require('./package.json').version") + +echo "==> Publishing @xpressai/xircuits-viewer-react..." +cd "$DIR/packages/react" + +# Swap workspace:* → real version +sed -i "s/\"@xpressai\/xircuits-viewer\": \"workspace:\*\"/\"@xpressai\/xircuits-viewer\": \"^$VERSION\"/" package.json +npm publish --access public + +# Revert for local dev +sed -i "s/\"@xpressai\/xircuits-viewer\": \"^\$VERSION\"/\"@xpressai\/xircuits-viewer\": \"workspace:*\"/" package.json + +echo "==> Done! Published v$VERSION" From c19e857c72bf316361d108d762b1b89afde1a423 Mon Sep 17 00:00:00 2001 From: MFA-X-AI Date: Tue, 7 Apr 2026 14:27:08 +0900 Subject: [PATCH 5/9] Add CI workflow for viewer tests --- .github/workflows/run-viewer-tests.yml | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/run-viewer-tests.yml diff --git a/.github/workflows/run-viewer-tests.yml b/.github/workflows/run-viewer-tests.yml new file mode 100644 index 00000000..46da2b15 --- /dev/null +++ b/.github/workflows/run-viewer-tests.yml @@ -0,0 +1,43 @@ +name: Run Viewer Tests + +on: + push: + branches: [ master ] + paths: + - 'xircuits-graph-viewer/**' + pull_request: + branches: [ "*" ] + paths: + - 'xircuits-graph-viewer/**' + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Install dependencies + working-directory: xircuits-graph-viewer + run: pnpm install + + - name: Build core + working-directory: xircuits-graph-viewer/packages/core + run: pnpm build + + - name: Run tests + working-directory: xircuits-graph-viewer + run: node_modules/.bin/vitest run From 2d69c6719bd238460d6181aa8351cbc77115c616 Mon Sep 17 00:00:00 2001 From: MFA-X-AI Date: Mon, 20 Apr 2026 19:22:33 +0900 Subject: [PATCH 6/9] Add .xircuits minifier, zoom/background controls, bump to v0.2.0 --- .../__tests__/minify.test.ts | 166 ++++++++++ xircuits-graph-viewer/packages/core/README.md | 29 ++ .../packages/core/package.json | 12 +- .../packages/core/src/index.ts | 4 + .../packages/core/src/minifier/cli.ts | 136 ++++++++ .../packages/core/src/minifier/index.ts | 294 ++++++++++++++++++ .../packages/react/README.md | 3 + .../packages/react/package.json | 2 +- .../packages/react/src/XircuitsGraph.tsx | 82 ++++- xircuits-graph-viewer/publish.sh | 6 +- 10 files changed, 721 insertions(+), 13 deletions(-) create mode 100644 xircuits-graph-viewer/__tests__/minify.test.ts create mode 100644 xircuits-graph-viewer/packages/core/src/minifier/cli.ts create mode 100644 xircuits-graph-viewer/packages/core/src/minifier/index.ts diff --git a/xircuits-graph-viewer/__tests__/minify.test.ts b/xircuits-graph-viewer/__tests__/minify.test.ts new file mode 100644 index 00000000..bb7b9c05 --- /dev/null +++ b/xircuits-graph-viewer/__tests__/minify.test.ts @@ -0,0 +1,166 @@ +import { describe, it, expect } from 'vitest'; +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { parse } from '../packages/core/src/parser/parse.js'; +import { + minify, + minifyWithStats, +} from '../packages/core/src/minifier/index.js'; + +const fixtureDir = resolve(__dirname, 'fixtures'); + +function loadFixture(name: string): unknown { + return JSON.parse(readFileSync(resolve(fixtureDir, name), 'utf-8')); +} + +function collectIds(obj: unknown, out: Set = new Set()): Set { + if (obj && typeof obj === 'object') { + if (!Array.isArray(obj)) { + const o = obj as Record; + if (typeof o.id === 'string') out.add(o.id); + for (const v of Object.values(o)) collectIds(v, out); + } else { + for (const v of obj) collectIds(v, out); + } + } + return out; +} + +describe('minify (safe mode)', () => { + const input = loadFixture('HelloXircuits.xircuits'); + + it('produces valid .xircuits JSON that parse() accepts', () => { + const out = minify(input); + const reparsed = JSON.parse(out); + expect(() => parse(reparsed)).not.toThrow(); + }); + + it('preserves every original ID byte-for-byte', () => { + const out = minify(input); + const reparsed = JSON.parse(out); + const originalIds = collectIds(input); + const outputIds = collectIds(reparsed); + for (const id of originalIds) { + expect(outputIds.has(id)).toBe(true); + } + }); + + it('strips selected and locked keys throughout', () => { + const out = minify(input); + expect(out).not.toMatch(/"selected":/); + expect(out).not.toMatch(/"locked":/); + }); + + it('rounds coordinates to the requested precision', () => { + const out = minify(input, { precision: 0 }); + const reparsed = JSON.parse(out) as Record; + const layers = reparsed.layers as Array>; + const nodeLayer = layers.find(l => l.type === 'diagram-nodes')!; + for (const node of Object.values(nodeLayer.models as Record>)) { + expect(Number.isInteger(node.x)).toBe(true); + expect(Number.isInteger(node.y)).toBe(true); + } + }); + + it('honors non-zero precision', () => { + const out = minify(input, { precision: 1 }); + const reparsed = JSON.parse(out) as Record; + const layers = reparsed.layers as Array>; + const nodeLayer = layers.find(l => l.type === 'diagram-nodes')!; + for (const node of Object.values(nodeLayer.models as Record>)) { + const x = node.x as number; + expect(Math.abs(x * 10 - Math.round(x * 10))).toBeLessThan(1e-9); + } + }); + + it('reports consistent stats', () => { + const { output, stats } = minifyWithStats(input); + expect(stats.outputBytes).toBe(new TextEncoder().encode(output).length); + expect(stats.mode).toBe('safe'); + expect(stats.nodes).toBeGreaterThan(0); + expect(stats.edges).toBeGreaterThan(0); + expect(stats.ports).toBeGreaterThan(0); + }); +}); + +describe('minify (aggressive mode)', () => { + const input = loadFixture('HelloXircuits.xircuits'); + + it('produces valid .xircuits JSON that parse() accepts', () => { + const out = minify(input, { aggressive: true }); + const reparsed = JSON.parse(out); + expect(() => parse(reparsed)).not.toThrow(); + }); + + it('replaces every original ID with a short form', () => { + const out = minify(input, { aggressive: true }); + const reparsed = JSON.parse(out); + const originalIds = collectIds(input); + const outputIds = collectIds(reparsed); + for (const id of originalIds) { + expect(outputIds.has(id)).toBe(false); + } + for (const id of outputIds) { + expect(id === 'g' || /^[nep]\d+$/.test(id)).toBe(true); + } + }); + + it('still resolves every link endpoint to a real node + port', () => { + const out = minify(input, { aggressive: true }); + const graph = parse(JSON.parse(out)); + const nodeIds = new Set(graph.nodes.map(n => n.id)); + const portIds = new Set(graph.nodes.flatMap(n => [...n.portsIn, ...n.portsOut]).map(p => p.id)); + + for (const edge of graph.edges) { + expect(nodeIds.has(edge.sourceNodeId)).toBe(true); + expect(nodeIds.has(edge.targetNodeId)).toBe(true); + expect(portIds.has(edge.sourcePortId)).toBe(true); + expect(portIds.has(edge.targetPortId)).toBe(true); + } + }); + + it('preserves port ordering after rename', () => { + const src = input as Record; + const origLayers = src.layers as Array>; + const origNodeLayer = origLayers.find(l => l.type === 'diagram-nodes')!; + const origModels = origNodeLayer.models as Record>; + + const out = minify(input, { aggressive: true }); + const reparsed = JSON.parse(out) as Record; + const newLayers = reparsed.layers as Array>; + const newNodeLayer = newLayers.find(l => l.type === 'diagram-nodes')!; + const newModels = newNodeLayer.models as Record>; + + const origNodes = Object.values(origModels); + const newNodes = Object.values(newModels); + expect(newNodes.length).toBe(origNodes.length); + + for (let i = 0; i < origNodes.length; i++) { + const origInCount = (origNodes[i].portsInOrder as string[]).length; + const origOutCount = (origNodes[i].portsOutOrder as string[]).length; + expect((newNodes[i].portsInOrder as string[]).length).toBe(origInCount); + expect((newNodes[i].portsOutOrder as string[]).length).toBe(origOutCount); + } + }); + + it('strips viewer-unused fields', () => { + const out = minify(input, { aggressive: true }); + expect(out).not.toMatch(/"curvyness":/); + expect(out).not.toMatch(/"selectedColor":/); + expect(out).not.toMatch(/"isSvg":/); + expect(out).not.toMatch(/"transformed":/); + expect(out).not.toMatch(/"alignment":/); + expect(out).not.toMatch(/"parentNode":/); + }); + + it('beats safe mode on size', () => { + const safe = minify(input, { aggressive: false }); + const aggr = minify(input, { aggressive: true }); + expect(aggr.length).toBeLessThan(safe.length); + }); + + it('tags stats as aggressive', () => { + const { stats } = minifyWithStats(input, { aggressive: true }); + expect(stats.mode).toBe('aggressive'); + }); +}); diff --git a/xircuits-graph-viewer/packages/core/README.md b/xircuits-graph-viewer/packages/core/README.md index a16f5c75..1a1d0369 100644 --- a/xircuits-graph-viewer/packages/core/README.md +++ b/xircuits-graph-viewer/packages/core/README.md @@ -51,6 +51,33 @@ import { getCanvasStyle } from '@xpressai/xircuits-viewer'; container.style.cssText = getCanvasStyle('dark'); ``` +## Minifier + +`.xircuits` files from the Xircuits editor carry full UUIDs and high-precision coordinates that the viewer doesn't need. A bundled minifier cuts file size 57–85% so workflows load faster over the network. + +### CLI + +```bash +# Safe mode (best-effort compatible with the JupyterLab editor) +npx xircuits-minify MyWorkflow.xircuits + +# Viewer-only; shortens UUIDs and strips cosmetic fields +npx xircuits-minify MyWorkflow.xircuits --aggressive + +# Tune coordinate precision (default 0 = integer pixels) +npx xircuits-minify MyWorkflow.xircuits --precision 1 +``` + +### Library + +```js +import { minify, minifyWithStats } from '@xpressai/xircuits-viewer'; + +const compact = minify(workflowJson, { aggressive: true }); +const { output, stats } = minifyWithStats(workflowJson); +// stats: { inputBytes, outputBytes, ratio, nodes, edges, ports, mode, precision } +``` + ## API | Function | Description | @@ -63,6 +90,8 @@ container.style.cssText = getCanvasStyle('dark'); | `validate(json)` | Validate without parsing | | `getCanvasStyle(theme?)` | CSS string for the dot-grid container background | | `attachPanZoom(svg, options?)` | Add pan/zoom, returns `{ destroy, zoomBy, fitView }` | +| `minify(json, options?)` | Minify a `.xircuits` JSON, returns compact string | +| `minifyWithStats(json, options?)` | Same, plus size/counts stats | ### RenderOptions diff --git a/xircuits-graph-viewer/packages/core/package.json b/xircuits-graph-viewer/packages/core/package.json index abfe3480..cf23acb8 100644 --- a/xircuits-graph-viewer/packages/core/package.json +++ b/xircuits-graph-viewer/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@xpressai/xircuits-viewer", - "version": "0.1.1", + "version": "0.2.0", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -14,12 +14,18 @@ "import": "./dist/interaction/panZoom.js" } }, - "files": ["dist"], + "bin": { + "xircuits-minify": "./dist/minifier/cli.js" + }, + "files": [ + "dist" + ], "scripts": { - "build": "tsc", + "build": "tsc && chmod +x ./dist/minifier/cli.js", "dev": "tsc --watch" }, "devDependencies": { + "@types/node": "^25.6.0", "typescript": "^5.8.3" } } diff --git a/xircuits-graph-viewer/packages/core/src/index.ts b/xircuits-graph-viewer/packages/core/src/index.ts index 309ec7c1..abe05ddc 100644 --- a/xircuits-graph-viewer/packages/core/src/index.ts +++ b/xircuits-graph-viewer/packages/core/src/index.ts @@ -23,6 +23,10 @@ export { computeViewBox } from './layout/viewBox.js'; // Renderer export { renderToString, renderToElement } from './render/renderGraph.js'; +// Minifier +export { minify, minifyWithStats } from './minifier/index.js'; +export type { MinifyOptions, MinifyStats } from './minifier/index.js'; + // Convenience: one-shot parse + render export { renderXircuits } from './render/renderGraph.js'; diff --git a/xircuits-graph-viewer/packages/core/src/minifier/cli.ts b/xircuits-graph-viewer/packages/core/src/minifier/cli.ts new file mode 100644 index 00000000..5f34b9b0 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/minifier/cli.ts @@ -0,0 +1,136 @@ +#!/usr/bin/env node +import { readFileSync, writeFileSync } from 'node:fs'; +import { basename, dirname, extname, join } from 'node:path'; +import { validate } from '../parser/validate.js'; +import { minifyWithStats } from './index.js'; + +function formatBytes(n: number): string { + if (n < 1024) return `${n} B`; + if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`; + return `${(n / 1024 / 1024).toFixed(2)} MB`; +} + +function printUsage() { + process.stderr.write( + [ + 'Usage: xircuits-minify [-o ] [--precision N] [--aggressive]', + '', + 'Options:', + ' -o, --output Output path (default: .min.xircuits)', + ' --precision N Coordinate decimal places (default: 0)', + ' --aggressive Shorten IDs and strip viewer-unused fields (viewer-only)', + ' -h, --help Show this help', + '', + ].join('\n') + ); +} + +interface Args { + input?: string; + output?: string; + precision: number; + aggressive: boolean; + help: boolean; +} + +function parseArgs(argv: string[]): Args { + const args: Args = { precision: 0, aggressive: false, help: false }; + for (let i = 0; i < argv.length; i++) { + const a = argv[i]; + if (a === '-h' || a === '--help') { + args.help = true; + } else if (a === '-o' || a === '--output') { + args.output = argv[++i]; + } else if (a === '--precision') { + args.precision = Number(argv[++i]); + if (!Number.isFinite(args.precision) || args.precision < 0) { + throw new Error(`Invalid --precision value: must be a non-negative number`); + } + } else if (a === '--aggressive') { + args.aggressive = true; + } else if (a.startsWith('-')) { + throw new Error(`Unknown flag: ${a}`); + } else if (!args.input) { + args.input = a; + } else { + throw new Error(`Unexpected positional argument: ${a}`); + } + } + return args; +} + +function defaultOutput(input: string): string { + const ext = extname(input); + const base = basename(input, ext); + return join(dirname(input), `${base}.min${ext || '.xircuits'}`); +} + +function main() { + let args: Args; + try { + args = parseArgs(process.argv.slice(2)); + } catch (e) { + process.stderr.write(`Error: ${(e as Error).message}\n\n`); + printUsage(); + process.exit(1); + } + + if (args.help || !args.input) { + printUsage(); + process.exit(args.help ? 0 : 1); + } + + const inputPath = args.input; + const outputPath = args.output ?? defaultOutput(inputPath); + + let raw: string; + try { + raw = readFileSync(inputPath, 'utf8'); + } catch (e) { + process.stderr.write(`Error reading ${inputPath}: ${(e as Error).message}\n`); + process.exit(1); + } + + let json: unknown; + try { + json = JSON.parse(raw); + } catch (e) { + process.stderr.write(`Error parsing ${inputPath}: ${(e as Error).message}\n`); + process.exit(1); + } + + const { valid, errors } = validate(json); + if (!valid) { + process.stderr.write(`Invalid .xircuits file: ${errors.join(', ')}\n`); + process.exit(1); + } + + const { output, stats } = minifyWithStats(json, { + precision: args.precision, + aggressive: args.aggressive, + }); + + writeFileSync(outputPath, output, 'utf8'); + + const onDiskInputBytes = Buffer.byteLength(raw, 'utf8'); + const savings = onDiskInputBytes - stats.outputBytes; + const pct = onDiskInputBytes === 0 ? 0 : (1 - stats.outputBytes / onDiskInputBytes) * 100; + const inName = basename(inputPath); + const outName = basename(outputPath); + const pad = Math.max(inName.length, outName.length); + + process.stderr.write( + [ + `Input: ${inName.padEnd(pad)} ${formatBytes(onDiskInputBytes)}`, + `Output: ${outName.padEnd(pad)} ${formatBytes(stats.outputBytes)}`, + `Savings: ${formatBytes(savings)} (${pct.toFixed(1)}% reduction)`, + '', + `Mode: ${stats.mode}`, + `Nodes: ${stats.nodes} Edges: ${stats.edges} Ports: ${stats.ports}`, + `Precision: ${stats.precision} decimals`, + '', + ].join('\n') + ); +} + +main(); diff --git a/xircuits-graph-viewer/packages/core/src/minifier/index.ts b/xircuits-graph-viewer/packages/core/src/minifier/index.ts new file mode 100644 index 00000000..26ba1e8e --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/minifier/index.ts @@ -0,0 +1,294 @@ +export interface MinifyOptions { + precision?: number; + aggressive?: boolean; +} + +export interface MinifyStats { + inputBytes: number; + outputBytes: number; + ratio: number; + nodes: number; + edges: number; + ports: number; + mode: 'safe' | 'aggressive'; + precision: number; +} + +const TRANSIENT_KEYS = new Set(['selected', 'locked']); + +const EXTRAS_ALLOWLIST = new Set([ + 'type', + 'path', + 'lineNo', + 'commentInput', +]); + +type Json = unknown; + +function roundTo(n: number, precision: number): number { + if (!Number.isFinite(n)) return n; + const f = Math.pow(10, precision); + return Math.round(n * f) / f; +} + +function stripTransient(value: Json): Json { + if (value === null || value === undefined) return undefined; + if (Array.isArray(value)) { + return value.map(stripTransient).filter(v => v !== undefined); + } + if (typeof value === 'object') { + const out: Record = {}; + for (const [k, v] of Object.entries(value as Record)) { + if (TRANSIENT_KEYS.has(k)) continue; + const cleaned = stripTransient(v); + if (cleaned !== undefined) out[k] = cleaned; + } + return out; + } + return value; +} + +function roundCoordsInPlace(graph: Record, precision: number) { + if (typeof graph.offsetX === 'number') graph.offsetX = roundTo(graph.offsetX, precision); + if (typeof graph.offsetY === 'number') graph.offsetY = roundTo(graph.offsetY, precision); + + const layers = graph.layers as Array> | undefined; + if (!Array.isArray(layers)) return; + + for (const layer of layers) { + const models = layer.models as Record> | undefined; + if (!models) continue; + + for (const model of Object.values(models)) { + if (typeof model.x === 'number') model.x = roundTo(model.x as number, precision); + if (typeof model.y === 'number') model.y = roundTo(model.y as number, precision); + + const ports = model.ports as Array> | undefined; + if (Array.isArray(ports)) { + for (const port of ports) { + if (typeof port.x === 'number') port.x = roundTo(port.x as number, precision); + if (typeof port.y === 'number') port.y = roundTo(port.y as number, precision); + } + } + + const points = model.points as Array> | undefined; + if (Array.isArray(points)) { + for (const p of points) { + if (typeof p.x === 'number') p.x = roundTo(p.x as number, precision); + if (typeof p.y === 'number') p.y = roundTo(p.y as number, precision); + } + } + } + } +} + +function collectCounts(graph: Record): { nodes: number; edges: number; ports: number } { + let nodes = 0; + let edges = 0; + let ports = 0; + const layers = graph.layers as Array> | undefined; + if (!Array.isArray(layers)) return { nodes, edges, ports }; + + for (const layer of layers) { + const models = layer.models as Record> | undefined; + if (!models) continue; + if (layer.type === 'diagram-nodes') { + for (const node of Object.values(models)) { + nodes++; + const nodePorts = node.ports as unknown[] | undefined; + if (Array.isArray(nodePorts)) ports += nodePorts.length; + } + } else if (layer.type === 'diagram-links') { + edges += Object.keys(models).length; + } + } + return { nodes, edges, ports }; +} + +function applyAggressive(graph: Record) { + const nodeMap = new Map(); + const portMap = new Map(); + const edgeMap = new Map(); + + const layers = graph.layers as Array> | undefined; + if (!Array.isArray(layers)) return; + + const nodeLayer = layers.find(l => l.type === 'diagram-nodes'); + const linkLayer = layers.find(l => l.type === 'diagram-links'); + + if (nodeLayer) { + const models = nodeLayer.models as Record>; + let ni = 0; + let pi = 0; + for (const node of Object.values(models)) { + const oldNodeId = node.id as string; + nodeMap.set(oldNodeId, `n${ni++}`); + const ports = node.ports as Array> | undefined; + if (Array.isArray(ports)) { + for (const port of ports) { + portMap.set(port.id as string, `p${pi++}`); + } + } + } + } + + if (linkLayer) { + const models = linkLayer.models as Record>; + let ei = 0; + for (const link of Object.values(models)) { + edgeMap.set(link.id as string, `e${ei++}`); + } + } + + if (typeof graph.id === 'string') graph.id = 'g'; + + const rewriteLayer = (layer: Record) => { + delete layer.id; + delete layer.isSvg; + delete layer.transformed; + delete layer.extras; + + const models = layer.models as Record>; + const newModels: Record> = {}; + + if (layer.type === 'diagram-nodes') { + for (const node of Object.values(models)) { + const newId = nodeMap.get(node.id as string)!; + node.id = newId; + + delete node.selectedColor; + delete node.width; + delete node.height; + delete node.type; + + const extras = node.extras as Record | undefined; + if (extras) { + const filteredExtras: Record = {}; + for (const [k, v] of Object.entries(extras)) { + if (EXTRAS_ALLOWLIST.has(k)) filteredExtras[k] = v; + } + if (Object.keys(filteredExtras).length > 0) { + node.extras = filteredExtras; + } else { + delete node.extras; + } + } + + const ports = node.ports as Array> | undefined; + if (Array.isArray(ports)) { + for (const port of ports) { + port.id = portMap.get(port.id as string)!; + delete port.alignment; + delete port.maximumLinks; + delete port.parentNode; + delete port.portType; + delete port.type; + + const pextras = port.extras as Record | undefined; + if (!pextras || Object.keys(pextras).length === 0) { + delete port.extras; + } + + const links = port.links as string[] | undefined; + if (Array.isArray(links)) { + port.links = links + .map(id => edgeMap.get(id)) + .filter((id): id is string => typeof id === 'string'); + } + } + } + + const portsInOrder = node.portsInOrder as string[] | undefined; + if (Array.isArray(portsInOrder)) { + node.portsInOrder = portsInOrder + .map(id => portMap.get(id)) + .filter((id): id is string => typeof id === 'string'); + } + const portsOutOrder = node.portsOutOrder as string[] | undefined; + if (Array.isArray(portsOutOrder)) { + node.portsOutOrder = portsOutOrder + .map(id => portMap.get(id)) + .filter((id): id is string => typeof id === 'string'); + } + + newModels[newId] = node; + } + } else if (layer.type === 'diagram-links') { + for (const link of Object.values(models)) { + const newId = edgeMap.get(link.id as string)!; + link.id = newId; + + delete link.width; + delete link.curvyness; + delete link.selectedColor; + delete link.labels; + delete link.extras; + + if (typeof link.source === 'string') link.source = nodeMap.get(link.source) ?? link.source; + if (typeof link.target === 'string') link.target = nodeMap.get(link.target) ?? link.target; + if (typeof link.sourcePort === 'string') link.sourcePort = portMap.get(link.sourcePort) ?? link.sourcePort; + if (typeof link.targetPort === 'string') link.targetPort = portMap.get(link.targetPort) ?? link.targetPort; + + const points = link.points as Array> | undefined; + if (Array.isArray(points)) { + for (const p of points) { + delete p.id; + delete p.type; + } + } + + newModels[newId] = link; + } + } + + layer.models = newModels; + }; + + delete graph.gridSize; + + for (const layer of layers) rewriteLayer(layer); +} + +function utf8Bytes(s: string): number { + return new TextEncoder().encode(s).length; +} + +export function minify(input: unknown, opts: MinifyOptions = {}): string { + return minifyWithStats(input, opts).output; +} + +export function minifyWithStats( + input: unknown, + opts: MinifyOptions = {} +): { output: string; stats: MinifyStats } { + const precision = opts.precision ?? 0; + const aggressive = opts.aggressive ?? false; + + const inputStr = JSON.stringify(input); + const inputBytes = utf8Bytes(inputStr); + + const cloned = JSON.parse(inputStr); + const stripped = stripTransient(cloned) as Record; + + const counts = collectCounts(stripped); + + roundCoordsInPlace(stripped, precision); + + if (aggressive) applyAggressive(stripped); + + const output = JSON.stringify(stripped); + const outputBytes = utf8Bytes(output); + + const stats: MinifyStats = { + inputBytes, + outputBytes, + ratio: inputBytes === 0 ? 0 : 1 - outputBytes / inputBytes, + nodes: counts.nodes, + edges: counts.edges, + ports: counts.ports, + mode: aggressive ? 'aggressive' : 'safe', + precision, + }; + + return { output, stats }; +} diff --git a/xircuits-graph-viewer/packages/react/README.md b/xircuits-graph-viewer/packages/react/README.md index cc401d4c..35842d5f 100644 --- a/xircuits-graph-viewer/packages/react/README.md +++ b/xircuits-graph-viewer/packages/react/README.md @@ -58,7 +58,10 @@ import workflow from './MyWorkflow.xircuits'; | `src` | `string` | — | URL to a `.xircuits` file | | `data` | `object` | — | Pre-loaded JSON (takes precedence over `src`) | | `theme` | `'dark' \| 'light'` | `'dark'` | Color theme | +| `showCanvasBackground` | `boolean` | `true` | Render the Xircuits dot-grid background on the container | | `interactive` | `boolean` | `true` | Enable pan/zoom | +| `showControls` | `boolean` | same as `interactive` | Show zoom +/−/fit buttons in the corner | +| `fitView` | `boolean` | `true` | Auto-fit the graph on first render | | `height` | `number \| string` | `400` | Container height | | `width` | `number \| string` | `'100%'` | Container width | | `padding` | `number` | `40` | Viewport padding | diff --git a/xircuits-graph-viewer/packages/react/package.json b/xircuits-graph-viewer/packages/react/package.json index 3734c58e..016b0044 100644 --- a/xircuits-graph-viewer/packages/react/package.json +++ b/xircuits-graph-viewer/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@xpressai/xircuits-viewer-react", - "version": "0.1.1", + "version": "0.2.0", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx b/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx index 43068161..e58f97c6 100644 --- a/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx +++ b/xircuits-graph-viewer/packages/react/src/XircuitsGraph.tsx @@ -1,15 +1,45 @@ import React, { useEffect, useRef, useState } from 'react'; -import { parse, renderToElement } from '@xpressai/xircuits-viewer'; +import { parse, renderToElement, getCanvasStyle } from '@xpressai/xircuits-viewer'; import { attachPanZoom } from '@xpressai/xircuits-viewer/interaction'; +import type { PanZoomInstance } from '@xpressai/xircuits-viewer/interaction'; import type { XNode, XEdge } from '@xpressai/xircuits-viewer'; +function parseCanvasStyle(theme: 'dark' | 'light'): React.CSSProperties { + return Object.fromEntries( + getCanvasStyle(theme).split(';').map(s => { + const [k, ...v] = s.split(':'); + return [k.trim().replace(/-([a-z])/g, (_, c: string) => c.toUpperCase()), v.join(':').trim()]; + }) + ); +} + +const controlBtnStyle: React.CSSProperties = { + width: 28, + height: 28, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + background: 'rgba(255,255,255,0.12)', + border: '1px solid rgba(255,255,255,0.2)', + borderRadius: 4, + color: '#fff', + cursor: 'pointer', + fontSize: 16, + lineHeight: 1, + padding: 0, +}; + export interface XircuitsGraphProps { /** URL or path to a .xircuits file. Fetched at mount time. */ src?: string; /** Pre-loaded .xircuits JSON data. Takes precedence over src. */ data?: object; theme?: 'dark' | 'light'; + /** Show the dotted-grid canvas background. Defaults to true. */ + showCanvasBackground?: boolean; interactive?: boolean; + /** Show zoom +/−/fit controls. Defaults to true when interactive. */ + showControls?: boolean; fitView?: boolean; width?: number | string; height?: number | string; @@ -25,7 +55,9 @@ export function XircuitsGraph({ src, data, theme = 'dark', + showCanvasBackground = true, interactive = true, + showControls, fitView = true, width = '100%', height = 400, @@ -37,9 +69,12 @@ export function XircuitsGraph({ onError, }: XircuitsGraphProps) { const containerRef = useRef(null); + const panZoomRef = useRef(null); const [fetchedData, setFetchedData] = useState(null); const [error, setError] = useState(null); + const displayControls = showControls ?? interactive; + // Fetch from src when no data is provided useEffect(() => { if (data || !src) return; @@ -70,12 +105,15 @@ export function XircuitsGraph({ const graph = parse(resolvedData); const svg = renderToElement(graph, { theme, fitView, padding }); - containerRef.current.innerHTML = ''; + containerRef.current.querySelectorAll('svg').forEach(el => el.remove()); containerRef.current.appendChild(svg); + panZoomRef.current = null; let cleanup: (() => void) | undefined; if (interactive) { - cleanup = attachPanZoom(svg).destroy; + const pz = attachPanZoom(svg); + panZoomRef.current = pz; + cleanup = pz.destroy; } const handleClick = (e: Event) => { @@ -104,22 +142,54 @@ export function XircuitsGraph({ return () => { cleanup?.(); + panZoomRef.current = null; svg.removeEventListener('click', handleClick); }; }, [resolvedData, theme, interactive, fitView, padding]); + const canvasCss = showCanvasBackground ? parseCanvasStyle(theme) : {}; + return (
- {error &&
{error}
} - {!resolvedData && !error && src &&
Loading...
} +
+ {error &&
{error}
} + {!resolvedData && !error && src &&
Loading...
} +
+ {displayControls && ( +
+ + + +
+ )}
); } diff --git a/xircuits-graph-viewer/publish.sh b/xircuits-graph-viewer/publish.sh index 1c53c9fe..4c50de54 100755 --- a/xircuits-graph-viewer/publish.sh +++ b/xircuits-graph-viewer/publish.sh @@ -5,11 +5,11 @@ DIR="$(cd "$(dirname "$0")" && pwd)" echo "==> Building core..." cd "$DIR/packages/core" -npx tsc +npm run build echo "==> Building react..." cd "$DIR/packages/react" -npx tsc +npm run build echo "==> Publishing @xpressai/xircuits-viewer..." cd "$DIR/packages/core" @@ -26,6 +26,6 @@ sed -i "s/\"@xpressai\/xircuits-viewer\": \"workspace:\*\"/\"@xpressai\/xircuits npm publish --access public # Revert for local dev -sed -i "s/\"@xpressai\/xircuits-viewer\": \"^\$VERSION\"/\"@xpressai\/xircuits-viewer\": \"workspace:*\"/" package.json +sed -i "s/\"@xpressai\/xircuits-viewer\": \"^$VERSION\"/\"@xpressai\/xircuits-viewer\": \"workspace:*\"/" package.json echo "==> Done! Published v$VERSION" From 419a285176e1bbc19aaee3f5be4ed7ca511f7055 Mon Sep 17 00:00:00 2001 From: MFA-X-AI Date: Wed, 22 Apr 2026 18:52:00 +0900 Subject: [PATCH 7/9] Add live Python component preview: parsePythonComponent in core, in react, CodeMirror-powered homepage demo, graph prop on --- xircuits-graph-viewer/README.md | 12 +- .../__tests__/parsePythonComponent.test.ts | 155 + xircuits-graph-viewer/docs/package-lock.json | 16070 ++++++++++++++++ xircuits-graph-viewer/docs/package.json | 6 +- .../docs/src/components/HomeLivePreview.js | 13 + .../src/components/HomeLivePreviewInner.js | 200 + xircuits-graph-viewer/docs/src/pages/index.js | 2 + xircuits-graph-viewer/packages/core/README.md | 24 + .../packages/core/src/index.ts | 2 + .../packages/core/src/parsePythonComponent.ts | 212 + .../packages/react/README.md | 66 + .../packages/react/src/ComponentPreview.tsx | 133 + .../packages/react/src/XircuitsGraph.tsx | 60 +- .../packages/react/src/index.ts | 6 + 14 files changed, 16945 insertions(+), 16 deletions(-) create mode 100644 xircuits-graph-viewer/__tests__/parsePythonComponent.test.ts create mode 100644 xircuits-graph-viewer/docs/package-lock.json create mode 100644 xircuits-graph-viewer/docs/src/components/HomeLivePreview.js create mode 100644 xircuits-graph-viewer/docs/src/components/HomeLivePreviewInner.js create mode 100644 xircuits-graph-viewer/packages/core/src/parsePythonComponent.ts create mode 100644 xircuits-graph-viewer/packages/react/src/ComponentPreview.tsx diff --git a/xircuits-graph-viewer/README.md b/xircuits-graph-viewer/README.md index ad32b914..87329a77 100644 --- a/xircuits-graph-viewer/README.md +++ b/xircuits-graph-viewer/README.md @@ -57,6 +57,14 @@ import workflow from './MyWorkflow.xircuits'; ``` +**Live component preview** — render a single xircuits component from its Python source. The drop-in version needs two lines; bring your own editor (CodeMirror, Monaco, etc.) via the `editor` prop. See [the react package README](./packages/react/README.md#live-component-preview-python--node) for examples. + +```tsx +import { ComponentPreview } from '@xpressai/xircuits-viewer-react'; + + +``` + ### Core (framework-agnostic) Works with Svelte, Vue, plain HTML, Node.js — anything. @@ -109,6 +117,7 @@ In the meantime, see `docs/` for a working Docusaurus integration using the core | `renderFromUrl(url, options?)` | Fetch a `.xircuits` URL and return SVG string. Browser only. | | `renderXircuits(json, options?)` | One-shot: parse JSON + render to SVG string. | | `parse(json)` | Parse `.xircuits` JSON into `XGraph`. | +| `parsePythonComponent(src, options?)` | Parse Python component source into `{ graph, error, warnings }`. | | `renderToString(graph, options?)` | Render `XGraph` to SVG string. Works in Node.js and browsers. | | `renderToElement(graph, options?)` | Render `XGraph` to DOM `SVGSVGElement`. Browser only. | | `validate(json)` | Validate a `.xircuits` file without parsing. | @@ -118,8 +127,9 @@ In the meantime, see `docs/` for a working Docusaurus integration using the core | Component | Props | Description | |-----------|-------|-------------| -| `` | `src` or `data`, `theme`, `interactive`, `height`, ... | Interactive viewer with pan/zoom. | +| `` | `src` \| `data` \| `graph`, `theme`, `interactive`, `height`, ... | Interactive viewer with pan/zoom. | | `` | `src` or `data`, `theme`, `height`, ... | Static SVG output, SSR-safe. | +| `` | `value`, `onChange`, `editor?`, `theme`, ... | Live preview of a single xircuits component from Python source. | ### `RenderOptions` diff --git a/xircuits-graph-viewer/__tests__/parsePythonComponent.test.ts b/xircuits-graph-viewer/__tests__/parsePythonComponent.test.ts new file mode 100644 index 00000000..47603eb3 --- /dev/null +++ b/xircuits-graph-viewer/__tests__/parsePythonComponent.test.ts @@ -0,0 +1,155 @@ +import { describe, it, expect } from 'vitest'; +import { parsePythonComponent } from '../packages/core/src/parsePythonComponent.js'; + +describe('parsePythonComponent', () => { + it('returns an error on empty input', () => { + const r = parsePythonComponent(''); + expect(r.graph).toBeNull(); + expect(r.error).toBeTruthy(); + }); + + it('returns an error when no class is present', () => { + const r = parsePythonComponent('# just a comment\nx = 1\n'); + expect(r.graph).toBeNull(); + expect(r.error).toMatch(/class/i); + }); + + it('parses class name and default color when decorator missing', () => { + const r = parsePythonComponent(`class MyComp(Component):\n pass\n`); + expect(r.graph).not.toBeNull(); + expect(r.graph!.nodes[0].name).toBe('MyComp'); + expect(r.graph!.nodes[0].color).toBe('rgb(153,51,204)'); + expect(r.warnings.some(w => /decorator/i.test(w))).toBe(true); + }); + + it('extracts color from @xai_component decorator', () => { + const src = ` +@xai_component(color="green") +class Greeter(Component): + pass +`; + const r = parsePythonComponent(src); + expect(r.graph!.nodes[0].color).toBe('green'); + }); + + it('extracts InArg, InCompArg, OutArg, and BaseComponent ports', () => { + const src = ` +@xai_component(color="blue") +class Demo(Component): + name: InArg[str] + count: InCompArg[int] + out: OutArg[float] + body: BaseComponent +`; + const r = parsePythonComponent(src); + const node = r.graph!.nodes[0]; + + // Input params: name, count (plus auto flow-in ▶) + const paramIn = node.portsIn.filter(p => p.kind === 'parameter'); + expect(paramIn.map(p => p.varName)).toEqual(['name', 'count']); + expect(paramIn[0].dataType).toBe('string'); // str → string + expect(paramIn[1].dataType).toBe('int'); + + // Output params: out (plus auto flow-out ▶ and body flow) + const paramOut = node.portsOut.filter(p => p.kind === 'parameter'); + expect(paramOut.map(p => p.varName)).toEqual(['out']); + expect(paramOut[0].dataType).toBe('float'); + + // Flow ports: auto in ▶, auto out ▶, body (BaseComponent treated as flow-out) + expect(node.portsIn.some(p => p.kind === 'flow' && p.label === '▶')).toBe(true); + const outFlows = node.portsOut.filter(p => p.kind === 'flow'); + expect(outFlows.map(p => p.varName)).toEqual(['out-0', 'body']); + }); + + it('ignores docstring lines when scanning fields', () => { + const src = ` +@xai_component +class Demo(Component): + """This is a docstring. + + message: OutArg[str] + """ + real_in: InArg[str] +`; + const r = parsePythonComponent(src); + const names = r.graph!.nodes[0].portsIn + .filter(p => p.kind === 'parameter').map(p => p.varName); + expect(names).toEqual(['real_in']); + expect(r.graph!.nodes[0].portsOut.some(p => p.varName === 'message')).toBe(false); + }); + + it('stops scanning at def execute()', () => { + const src = ` +@xai_component +class Demo(Component): + real_in: InArg[str] + + def execute(self, ctx): + phantom: InArg[int] +`; + const r = parsePythonComponent(src); + const names = r.graph!.nodes[0].portsIn + .filter(p => p.kind === 'parameter').map(p => p.varName); + expect(names).toEqual(['real_in']); + }); + + it('handles missing generic type as null dataType', () => { + const src = ` +@xai_component +class Demo(Component): + body: BaseComponent +`; + const r = parsePythonComponent(src); + const body = r.graph!.nodes[0].portsOut.find(p => p.varName === 'body'); + expect(body).toBeDefined(); + expect(body!.dataType).toBeNull(); + }); + + it('normalises Python types to xircuits type names', () => { + const src = ` +@xai_component +class Demo(Component): + s: InArg[str] + b: InArg[bool] + lst: InArg[List[str]] + d: InArg[dict] + out: OutArg[Any] +`; + const r = parsePythonComponent(src); + const types = Object.fromEntries( + [...r.graph!.nodes[0].portsIn, ...r.graph!.nodes[0].portsOut] + .filter(p => p.kind === 'parameter') + .map(p => [p.varName, p.dataType]) + ); + expect(types).toMatchObject({ + s: 'string', + b: 'boolean', + lst: 'list', + d: 'dict', + out: 'any', + }); + }); + + it('can skip flow-in/flow-out injection via options', () => { + const src = ` +class Demo(Component): + pass +`; + const r = parsePythonComponent(src, { includeFlowIn: false, includeFlowOut: false }); + const node = r.graph!.nodes[0]; + expect(node.portsIn).toEqual([]); + expect(node.portsOut).toEqual([]); + }); + + it('tolerates non-xircuits python without crashing', () => { + const src = ` +def hello(): + return "world" + +print(hello()) +`; + const r = parsePythonComponent(src); + expect(r.graph).toBeNull(); + expect(r.error).toBeTruthy(); + }); +}); diff --git a/xircuits-graph-viewer/docs/package-lock.json b/xircuits-graph-viewer/docs/package-lock.json new file mode 100644 index 00000000..655113dc --- /dev/null +++ b/xircuits-graph-viewer/docs/package-lock.json @@ -0,0 +1,16070 @@ +{ + "name": "docs", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "docs", + "version": "0.0.0", + "dependencies": { + "@codemirror/lang-python": "^6.1.6", + "@docusaurus/core": "3.9.2", + "@docusaurus/preset-classic": "3.9.2", + "@mdx-js/react": "^3.0.0", + "@uiw/react-codemirror": "^4.23.7", + "@xpressai/xircuits-viewer": "file:../packages/core", + "@xpressai/xircuits-viewer-react": "file:../packages/react", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/types": "3.9.2" + }, + "engines": { + "node": ">=20.0" + } + }, + "../packages/core": { + "name": "@xpressai/xircuits-viewer", + "version": "0.2.0", + "bin": { + "xircuits-minify": "dist/minifier/cli.js" + }, + "devDependencies": { + "@types/node": "^25.6.0", + "typescript": "^5.8.3" + } + }, + "../packages/react": { + "name": "@xpressai/xircuits-viewer-react", + "version": "0.2.0", + "dependencies": { + "@xpressai/xircuits-viewer": "workspace:*" + }, + "devDependencies": { + "@types/react": "^18.3.12", + "react": "^18.3.1", + "typescript": "^5.8.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@algolia/abtesting": { + "version": "1.16.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.19.2", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", + "@algolia/autocomplete-shared": "1.19.2" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.19.2", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.19.2" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.19.2", + "license": "MIT", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.50.1", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "license": "MIT" + }, + "node_modules/@algolia/ingestion": { + "version": "1.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.8", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.28.0", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-syntax-jsx": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.29.2", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.28.6", + "@babel/plugin-syntax-import-attributes": "^7.28.6", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.29.0", + "@babel/plugin-transform-async-to-generator": "^7.28.6", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.6", + "@babel/plugin-transform-class-properties": "^7.28.6", + "@babel/plugin-transform-class-static-block": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-computed-properties": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-dotall-regex": "^7.28.6", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.6", + "@babel/plugin-transform-exponentiation-operator": "^7.28.6", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.28.6", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.28.6", + "@babel/plugin-transform-modules-systemjs": "^7.29.0", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", + "@babel/plugin-transform-numeric-separator": "^7.28.6", + "@babel/plugin-transform-object-rest-spread": "^7.28.6", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.28.6", + "@babel/plugin-transform-optional-chaining": "^7.28.6", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.29.0", + "@babel/plugin-transform-regexp-modifiers": "^7.28.6", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.28.6", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.28.6", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.2", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8", + "core-js-compat": "^3.48.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.28.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-transform-react-display-name": "^7.28.0", + "@babel/plugin-transform-react-jsx": "^7.27.1", + "@babel/plugin-transform-react-jsx-development": "^7.27.1", + "@babel/plugin-transform-react-pure-annotations": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.28.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.29.2", + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.48.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@codemirror/autocomplete": { + "version": "6.20.1", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.10.3", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-python": { + "version": "6.2.1", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.3.2", + "@codemirror/language": "^6.8.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/python": "^1.1.4" + } + }, + "node_modules/@codemirror/language": { + "version": "6.12.3", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.5.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.9.5", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.35.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.7.0", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.37.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.6.0", + "license": "MIT", + "dependencies": { + "@marijn/find-cluster-break": "^1.0.0" + } + }, + "node_modules/@codemirror/theme-one-dark": { + "version": "6.1.3", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@codemirror/view": { + "version": "6.41.1", + "license": "MIT", + "dependencies": { + "@codemirror/state": "^6.6.0", + "crelt": "^1.0.6", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@csstools/cascade-layer-name-parser": { + "version": "2.0.5", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/postcss-alpha-function": { + "version": "1.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "5.0.2", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "4.0.12", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-function-display-p3-linear": { + "version": "1.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-function": { + "version": "3.0.12", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": { + "version": "1.0.2", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-content-alt-text": { + "version": "2.0.8", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-contrast-color-function": { + "version": "2.0.12", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-exponential-functions": { + "version": "2.0.9", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "4.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gamut-mapping": { + "version": "2.0.11", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gradients-interpolation-method": { + "version": "5.0.12", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "4.0.12", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "4.0.4", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-initial": { + "version": "2.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "5.0.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-light-dark-function": { + "version": "2.0.11", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-float-and-clear": { + "version": "3.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overflow": { + "version": "2.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overscroll-behavior": { + "version": "2.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-resize": { + "version": "3.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-viewport-units": { + "version": "3.0.4", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-minmax": { + "version": "2.0.9", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { + "version": "3.0.5", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "4.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "4.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "4.0.12", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-position-area-property": { + "version": "1.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "4.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-property-rule-prelude-list": { + "version": "1.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-random-function": { + "version": "2.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-relative-color-syntax": { + "version": "3.0.12", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class": { + "version": "4.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-sign-functions": { + "version": "1.1.4", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "4.0.9", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-syntax-descriptor-syntax-production": { + "version": "1.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-system-ui-font-family": { + "version": "1.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "4.0.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "4.0.9", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "4.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/utilities": { + "version": "2.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docsearch/core": { + "version": "4.6.2", + "license": "MIT", + "peerDependencies": { + "@types/react": ">= 16.8.0 < 20.0.0", + "react": ">= 16.8.0 < 20.0.0", + "react-dom": ">= 16.8.0 < 20.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@docsearch/css": { + "version": "4.6.2", + "license": "MIT" + }, + "node_modules/@docsearch/react": { + "version": "4.6.2", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-core": "1.19.2", + "@docsearch/core": "4.6.2", + "@docsearch/css": "4.6.2" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 20.0.0", + "react": ">= 16.8.0 < 20.0.0", + "react-dom": ">= 16.8.0 < 20.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@docusaurus/babel": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.25.9", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.25.9", + "@babel/runtime": "^7.25.9", + "@babel/runtime-corejs3": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "babel-plugin-dynamic-import-node": "^2.3.3", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/bundler": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@docusaurus/babel": "3.9.2", + "@docusaurus/cssnano-preset": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "babel-loader": "^9.2.1", + "clean-css": "^5.3.3", + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.11.0", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "file-loader": "^6.2.0", + "html-minifier-terser": "^7.2.0", + "mini-css-extract-plugin": "^2.9.2", + "null-loader": "^4.0.1", + "postcss": "^8.5.4", + "postcss-loader": "^7.3.4", + "postcss-preset-env": "^10.2.1", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "webpack": "^5.95.0", + "webpackbar": "^6.0.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/faster": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/babel": "3.9.2", + "@docusaurus/bundler": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "core-js": "^3.31.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "execa": "5.1.1", + "fs-extra": "^11.1.1", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.6.0", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "open": "^8.4.0", + "p-map": "^4.0.0", + "prompts": "^2.4.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.6", + "tinypool": "^1.0.2", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "webpack": "^5.95.0", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-dev-server": "^5.2.2", + "webpack-merge": "^6.0.1" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.5.4", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/logger": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^2.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.9.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "cheerio": "1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "schema-dts": "^1.1.2", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "schema-dts": "^1.1.2", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-pages": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-css-cascade-layers": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-debug": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^2.3.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-svgr": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@svgr/core": "8.1.0", + "@svgr/webpack": "^8.1.0", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/preset-classic": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/plugin-content-blog": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/plugin-content-pages": "3.9.2", + "@docusaurus/plugin-css-cascade-layers": "3.9.2", + "@docusaurus/plugin-debug": "3.9.2", + "@docusaurus/plugin-google-analytics": "3.9.2", + "@docusaurus/plugin-google-gtag": "3.9.2", + "@docusaurus/plugin-google-tag-manager": "3.9.2", + "@docusaurus/plugin-sitemap": "3.9.2", + "@docusaurus/plugin-svgr": "3.9.2", + "@docusaurus/theme-classic": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-search-algolia": "3.9.2", + "@docusaurus/types": "3.9.2" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-classic": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/plugin-content-blog": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/plugin-content-pages": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-translations": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "infima": "0.2.0-alpha.45", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.5.4", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-common": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docsearch/react": "^3.9.0 || ^4.1.0", + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-translations": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "algoliasearch": "^5.37.0", + "algoliasearch-helper": "^3.26.0", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-translations": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/types": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/mdast": "^4.0.2", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.95.0", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/types/node_modules/webpack-merge": { + "version": "5.10.0", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docusaurus/utils": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "escape-string-regexp": "^4.0.0", + "execa": "5.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "p-queue": "^6.6.2", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/utils-common": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/utils-validation": { + "version": "3.9.2", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/buffers": { + "version": "17.67.0", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.57.1", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.57.1", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.57.1", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-print": "4.57.1", + "@jsonjoy.com/fs-snapshot": "4.57.1", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.57.1", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.57.1", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.57.1", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.1" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.57.1", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.57.1", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.57.1", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.67.0", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.67.0", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.67.0", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.67.0", + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0", + "@jsonjoy.com/json-pointer": "17.67.0", + "@jsonjoy.com/util": "17.67.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.67.0", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/util": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "license": "MIT" + }, + "node_modules/@lezer/common": { + "version": "1.5.2", + "license": "MIT" + }, + "node_modules/@lezer/highlight": { + "version": "1.2.3", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.3.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.10", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/python": { + "version": "1.1.18", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@marijn/find-cluster-break": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@peculiar/asn1-cms": { + "version": "2.6.1", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "@peculiar/asn1-x509-attr": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-csr": { + "version": "2.6.1", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-ecc": { + "version": "2.6.1", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pfx": { + "version": "2.6.1", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.1", + "@peculiar/asn1-pkcs8": "^2.6.1", + "@peculiar/asn1-rsa": "^2.6.1", + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.6.1", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.6.1", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.1", + "@peculiar/asn1-pfx": "^2.6.1", + "@peculiar/asn1-pkcs8": "^2.6.1", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "@peculiar/asn1-x509-attr": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-rsa": { + "version": "2.6.1", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.6.0", + "license": "MIT", + "dependencies": { + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509": { + "version": "2.6.1", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.6.1", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.3", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-csr": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.0", + "@peculiar/asn1-pkcs9": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "license": "MIT" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "license": "BSD-3-Clause" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.10", + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.25", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "^1" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.8", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "license": "MIT" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "license": "MIT" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.17", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.5.2", + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/prismjs": { + "version": "1.26.6", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.15.0", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.14", + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.11", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "license": "MIT" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.10", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "license": "MIT" + }, + "node_modules/@uiw/codemirror-extensions-basic-setup": { + "version": "4.25.9", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@codemirror/autocomplete": ">=6.0.0", + "@codemirror/commands": ">=6.0.0", + "@codemirror/language": ">=6.0.0", + "@codemirror/lint": ">=6.0.0", + "@codemirror/search": ">=6.0.0", + "@codemirror/state": ">=6.0.0", + "@codemirror/view": ">=6.0.0" + } + }, + "node_modules/@uiw/react-codemirror": { + "version": "4.25.9", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.6", + "@codemirror/commands": "^6.1.0", + "@codemirror/state": "^6.1.1", + "@codemirror/theme-one-dark": "^6.0.0", + "@uiw/codemirror-extensions-basic-setup": "4.25.9", + "codemirror": "^6.0.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.11.0", + "@codemirror/state": ">=6.0.0", + "@codemirror/theme-one-dark": ">=6.0.0", + "@codemirror/view": ">=6.0.0", + "codemirror": ">=6.0.0", + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "license": "ISC" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xpressai/xircuits-viewer": { + "resolved": "../packages/core", + "link": true + }, + "node_modules/@xpressai/xircuits-viewer-react": { + "resolved": "../packages/react", + "link": true + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "license": "Apache-2.0" + }, + "node_modules/accepts": { + "version": "1.3.8", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "5.50.1", + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.16.1", + "@algolia/client-abtesting": "5.50.1", + "@algolia/client-analytics": "5.50.1", + "@algolia/client-common": "5.50.1", + "@algolia/client-insights": "5.50.1", + "@algolia/client-personalization": "5.50.1", + "@algolia/client-query-suggestions": "5.50.1", + "@algolia/client-search": "5.50.1", + "@algolia/ingestion": "1.50.1", + "@algolia/monitoring": "1.50.1", + "@algolia/recommend": "5.50.1", + "@algolia/requester-browser-xhr": "5.50.1", + "@algolia/requester-fetch": "5.50.1", + "@algolia/requester-node-http": "5.50.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.28.1", + "license": "MIT", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1js": { + "version": "3.0.7", + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.27", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1", + "caniuse-lite": "^1.0.30001774", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "license": "MIT", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "license": "MIT", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.15", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "license": "MIT" + }, + "node_modules/big.js": { + "version": "5.2.2", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.4", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "6.2.1", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.13", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bytestreamjs": { + "version": "2.0.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001785", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/codemirror": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "license": "MIT" + }, + "node_modules/combine-promises": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "license": "ISC" + }, + "node_modules/compressible": { + "version": "2.0.18", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compressible/node_modules/mime-db": { + "version": "1.54.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "license": "ISC" + }, + "node_modules/configstore": { + "version": "6.0.0", + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "3.4.2", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.49.0", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.49.0", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/crelt": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-blank-pseudo": { + "version": "7.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.3.1", + "license": "ISC", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-has-pseudo": { + "version": "7.0.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-has-pseudo/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "10.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssdb": { + "version": "8.8.0", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ], + "license": "MIT-0" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.2.3", + "license": "MIT" + }, + "node_modules/debounce": { + "version": "1.2.1", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/detect-port": { + "version": "1.6.1", + "license": "MIT", + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.331", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/emoticon": { + "version": "4.1.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.20.1", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.5.0", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.22.1", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/content-disposition": { + "version": "0.5.4", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.13", + "license": "MIT" + }, + "node_modules/express/node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/feed": { + "version": "4.2.2", + "license": "MIT", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.14.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "license": "MIT", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "license": "ISC" + }, + "node_modules/get-proto": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "license": "BSD-2-Clause" + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.6.1", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "license": "ISC" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.2", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/history": { + "version": "4.10.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.6", + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.9", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "2.0.2", + "license": "MIT", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infima": { + "version": "0.2.0-alpha.45", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/ini": { + "version": "2.0.0", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "license": "MIT" + }, + "node_modules/invariant": { + "version": "2.2.4", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.3.0", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "license": "MIT", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.3.1", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "6.1.0", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/latest-version": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launch-editor": { + "version": "2.13.2", + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.3" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.1", + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.57.1", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-fsa": "4.57.1", + "@jsonjoy.com/fs-node": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-to-fsa": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-print": "4.57.1", + "@jsonjoy.com/fs-snapshot": "4.57.1", + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", + "tslib": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.33.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "license": "MIT", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.10.2", + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.5", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.4", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-emoji": { + "version": "2.2.0", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.37", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.1.1", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/null-loader": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/null-loader/node_modules/ajv": { + "version": "6.14.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/null-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/null-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/null-loader/node_modules/schema-utils": { + "version": "3.3.0", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "license": "MIT", + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "license": "ISC" + }, + "node_modules/parse5": { + "version": "7.3.0", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "license": "(WTFPL OR MIT)" + }, + "node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkijs": { + "version": "3.4.0", + "license": "BSD-3-Clause", + "dependencies": { + "@noble/hashes": "1.4.0", + "asn1js": "^3.0.6", + "bytestreamjs": "^2.0.1", + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "7.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "7.0.12", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "10.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "10.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-colormin": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-custom-media": { + "version": "11.0.6", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-properties": { + "version": "14.0.6", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "8.0.5", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "9.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "6.0.4", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "10.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-focus-within": { + "version": "9.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "6.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-image-set-function": { + "version": "7.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-lab-function": { + "version": "7.0.12", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.4", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-logical": { + "version": "8.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-merge-idents": { + "version": "6.0.3", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.5", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "license": "MIT", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nesting": { + "version": "13.0.2", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-resolve-nested": "^3.1.0", + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": { + "version": "3.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "3.0.0", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "6.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "license": "MIT", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "10.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-preset-env": { + "version": "10.6.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-alpha-function": "^1.0.1", + "@csstools/postcss-cascade-layers": "^5.0.2", + "@csstools/postcss-color-function": "^4.0.12", + "@csstools/postcss-color-function-display-p3-linear": "^1.0.1", + "@csstools/postcss-color-mix-function": "^3.0.12", + "@csstools/postcss-color-mix-variadic-function-arguments": "^1.0.2", + "@csstools/postcss-content-alt-text": "^2.0.8", + "@csstools/postcss-contrast-color-function": "^2.0.12", + "@csstools/postcss-exponential-functions": "^2.0.9", + "@csstools/postcss-font-format-keywords": "^4.0.0", + "@csstools/postcss-gamut-mapping": "^2.0.11", + "@csstools/postcss-gradients-interpolation-method": "^5.0.12", + "@csstools/postcss-hwb-function": "^4.0.12", + "@csstools/postcss-ic-unit": "^4.0.4", + "@csstools/postcss-initial": "^2.0.1", + "@csstools/postcss-is-pseudo-class": "^5.0.3", + "@csstools/postcss-light-dark-function": "^2.0.11", + "@csstools/postcss-logical-float-and-clear": "^3.0.0", + "@csstools/postcss-logical-overflow": "^2.0.0", + "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", + "@csstools/postcss-logical-resize": "^3.0.0", + "@csstools/postcss-logical-viewport-units": "^3.0.4", + "@csstools/postcss-media-minmax": "^2.0.9", + "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.5", + "@csstools/postcss-nested-calc": "^4.0.0", + "@csstools/postcss-normalize-display-values": "^4.0.1", + "@csstools/postcss-oklab-function": "^4.0.12", + "@csstools/postcss-position-area-property": "^1.0.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/postcss-property-rule-prelude-list": "^1.0.0", + "@csstools/postcss-random-function": "^2.0.1", + "@csstools/postcss-relative-color-syntax": "^3.0.12", + "@csstools/postcss-scope-pseudo-class": "^4.0.1", + "@csstools/postcss-sign-functions": "^1.1.4", + "@csstools/postcss-stepped-value-functions": "^4.0.9", + "@csstools/postcss-syntax-descriptor-syntax-production": "^1.0.1", + "@csstools/postcss-system-ui-font-family": "^1.0.0", + "@csstools/postcss-text-decoration-shorthand": "^4.0.3", + "@csstools/postcss-trigonometric-functions": "^4.0.9", + "@csstools/postcss-unset-value": "^4.0.0", + "autoprefixer": "^10.4.23", + "browserslist": "^4.28.1", + "css-blank-pseudo": "^7.0.1", + "css-has-pseudo": "^7.0.3", + "css-prefers-color-scheme": "^10.0.0", + "cssdb": "^8.6.0", + "postcss-attribute-case-insensitive": "^7.0.1", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^7.0.12", + "postcss-color-hex-alpha": "^10.0.0", + "postcss-color-rebeccapurple": "^10.0.0", + "postcss-custom-media": "^11.0.6", + "postcss-custom-properties": "^14.0.6", + "postcss-custom-selectors": "^8.0.5", + "postcss-dir-pseudo-class": "^9.0.1", + "postcss-double-position-gradients": "^6.0.4", + "postcss-focus-visible": "^10.0.1", + "postcss-focus-within": "^9.0.1", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^6.0.0", + "postcss-image-set-function": "^7.0.0", + "postcss-lab-function": "^7.0.12", + "postcss-logical": "^8.1.0", + "postcss-nesting": "^13.0.2", + "postcss-opacity-percentage": "^3.0.0", + "postcss-overflow-shorthand": "^6.0.0", + "postcss-page-break": "^3.0.4", + "postcss-place": "^10.0.0", + "postcss-pseudo-class-any-link": "^10.0.1", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^8.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "10.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "6.0.3", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "8.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sort-media-queries": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "sort-css-media-queries": "2.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.23" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.3", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/postcss-zindex": { + "version": "6.0.2", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "license": "ISC" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "3.3.0", + "license": "MIT", + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.5", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/qs": { + "version": "6.14.2", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "19.2.4", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.4", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "license": "MIT" + }, + "node_modules/react-helmet-async": { + "name": "@slorber/react-helmet-async", + "version": "1.3.0", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "license": "MIT" + }, + "node_modules/react-json-view-lite": { + "version": "2.5.0", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-loadable": { + "name": "@docusaurus/react-loadable", + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "@types/react": "*" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.3" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "react-loadable": "*", + "webpack": ">=4.41.1 || 5.x" + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-config": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router": ">=5" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "license": "Apache-2.0" + }, + "node_modules/regenerate": { + "version": "1.4.2", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^3.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.1", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-directive": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-emoji": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "6.1.0", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "engines": { + "node": "*" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.11", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "license": "MIT" + }, + "node_modules/responselike": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rtlcss": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.6.0", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "license": "MIT" + }, + "node_modules/schema-dts": { + "version": "1.1.5", + "license": "Apache-2.0" + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/search-insights": { + "version": "2.17.3", + "license": "MIT", + "peer": true + }, + "node_modules/section-matter": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "@peculiar/x509": "^1.14.2", + "pkijs": "^3.3.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/send": { + "version": "0.19.2", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/send/node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-handler": { + "version": "6.1.7", + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.5", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/path-to-regexp": { + "version": "3.3.0", + "license": "MIT" + }, + "node_modules/serve-index": { + "version": "1.9.2", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.8.0", + "mime-types": "~2.1.35", + "parseurl": "~1.3.3" + }, + "engines": { + "node": ">= 0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.8.1", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.16.3", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "license": "ISC" + }, + "node_modules/sirv": { + "version": "2.0.4", + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "license": "MIT" + }, + "node_modules/sitemap": { + "version": "7.1.3", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "license": "MIT" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sort-css-media-queries": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">= 6.3.0" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "license": "BSD-3-Clause" + }, + "node_modules/srcset": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.10.0", + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-mod": { + "version": "4.1.3", + "license": "MIT" + }, + "node_modules/style-to-js": { + "version": "1.1.21", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/stylehacks": { + "version": "6.1.1", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "license": "MIT" + }, + "node_modules/svgo": { + "version": "3.3.3", + "license": "MIT", + "dependencies": { + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/tapable": { + "version": "2.3.2", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.46.1", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.4.0", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "license": "MIT" + }, + "node_modules/thingies": { + "version": "2.6.0", + "license": "MIT", + "engines": { + "node": ">=10.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.1.1", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tree-dump": { + "version": "1.1.0", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "license": "0BSD" + }, + "node_modules/tsyringe": { + "version": "4.10.0", + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "2.19.0", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-notifier": { + "version": "6.0.2", + "license": "BSD-2-Clause", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.6.2", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-loader": { + "version": "4.1.1", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.14.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/url-loader/node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/utila": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "license": "MIT" + }, + "node_modules/watchpack": { + "version": "2.5.1", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpack": { + "version": "5.105.4", + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.16.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.20.0", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.3.1", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.17", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.4" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.2", + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.5", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.43.1", + "mime-types": "^3.0.1", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.54.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/webpack-dev-middleware/node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.2.3", + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.25", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.8.1", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.22.1", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.9", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^5.5.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/open": { + "version": "10.2.0", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.20.0", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.4", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpackbar": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "consola": "^3.2.3", + "figures": "^3.2.0", + "markdown-table": "^2.0.0", + "pretty-time": "^1.1.0", + "std-env": "^3.7.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/webpackbar/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/webpackbar/node_modules/markdown-table": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpackbar/node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpackbar/node_modules/wrap-ansi": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wsl-utils/node_modules/is-wsl": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "license": "MIT", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/xircuits-graph-viewer/docs/package.json b/xircuits-graph-viewer/docs/package.json index 87a2257c..c67d4801 100644 --- a/xircuits-graph-viewer/docs/package.json +++ b/xircuits-graph-viewer/docs/package.json @@ -21,8 +21,10 @@ "prism-react-renderer": "^2.3.0", "react": "^19.0.0", "react-dom": "^19.0.0", - "xircuits-graph-core": "file:../packages/core", - "xircuits-graph-react": "file:../packages/react" + "@xpressai/xircuits-viewer": "file:../packages/core", + "@xpressai/xircuits-viewer-react": "file:../packages/react", + "@uiw/react-codemirror": "^4.23.7", + "@codemirror/lang-python": "^6.1.6" }, "devDependencies": { "@docusaurus/module-type-aliases": "3.9.2", diff --git a/xircuits-graph-viewer/docs/src/components/HomeLivePreview.js b/xircuits-graph-viewer/docs/src/components/HomeLivePreview.js new file mode 100644 index 00000000..2e4deef5 --- /dev/null +++ b/xircuits-graph-viewer/docs/src/components/HomeLivePreview.js @@ -0,0 +1,13 @@ +import React from 'react'; +import BrowserOnly from '@docusaurus/BrowserOnly'; + +export default function HomeLivePreview() { + return ( + }> + {() => { + const Inner = require('./HomeLivePreviewInner').default; + return ; + }} + + ); +} diff --git a/xircuits-graph-viewer/docs/src/components/HomeLivePreviewInner.js b/xircuits-graph-viewer/docs/src/components/HomeLivePreviewInner.js new file mode 100644 index 00000000..3692a737 --- /dev/null +++ b/xircuits-graph-viewer/docs/src/components/HomeLivePreviewInner.js @@ -0,0 +1,200 @@ +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { XircuitsGraph, parsePythonComponent } from '@xpressai/xircuits-viewer-react'; +import CodeMirror from '@uiw/react-codemirror'; +import { python } from '@codemirror/lang-python'; +import { useColorMode } from '@docusaurus/theme-common'; + +const STARTER = `@xai_component(color="blue") +class GreetUser(Component): + """Greets a user by name.""" + + name: InArg[str] + times: InCompArg[int] + greeting: InArg[str] + + message: OutArg[str] + + body: BaseComponent + + def execute(self, ctx) -> None: + self.message.value = f"Hello, {self.name.value}!" +`; + +const DEBOUNCE_MS = 150; + +function EditorChrome({ theme }) { + const isDark = theme === 'dark'; + return ( +
+
+ + + +
+
+ + greet_user.py +
+
+ ); +} + +export default function HomeLivePreviewInner() { + const [code, setCode] = useState(STARTER); + const [debounced, setDebounced] = useState(STARTER); + const { colorMode } = useColorMode(); + const theme = colorMode === 'dark' ? 'dark' : 'light'; + const isDark = theme === 'dark'; + + useEffect(() => { + const id = setTimeout(() => setDebounced(code), DEBOUNCE_MS); + return () => clearTimeout(id); + }, [code]); + + const parsed = useMemo(() => parsePythonComponent(debounced), [debounced]); + const lastGoodRef = useRef(parsed.graph); + if (parsed.graph) lastGoodRef.current = parsed.graph; + const graph = lastGoodRef.current; + + const panelStyle = { + borderRadius: 14, + overflow: 'hidden', + border: isDark ? '1px solid #26262e' : '1px solid #e0e0e8', + background: isDark ? '#0d0d14' : '#ffffff', + boxShadow: isDark + ? '0 20px 40px -20px rgba(0, 0, 0, 0.6)' + : '0 10px 30px -15px rgba(0, 0, 0, 0.15)', + display: 'flex', + flexDirection: 'column', + minHeight: 0, + }; + + return ( +
+
+
+

+ Write Python, see the node. +

+

+ A xircuits component is just a Python class. Edit the code on the left; + the node preview on the right updates as you type. +

+
+ +
+ {/* Editor card */} +
+ +
+ +
+
+ + {/* Viewer card */} +
+
+ {graph && ( + + )} +
+
+
+
+ + +
+ ); +} diff --git a/xircuits-graph-viewer/docs/src/pages/index.js b/xircuits-graph-viewer/docs/src/pages/index.js index 846be01e..911f462c 100644 --- a/xircuits-graph-viewer/docs/src/pages/index.js +++ b/xircuits-graph-viewer/docs/src/pages/index.js @@ -3,6 +3,7 @@ import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Layout from '@theme/Layout'; import HomepageFeatures from '@site/src/components/HomepageFeatures'; +import HomeLivePreview from '@site/src/components/HomeLivePreview'; import Heading from '@theme/Heading'; import styles from './index.module.css'; @@ -36,6 +37,7 @@ export default function Home() { description="Description will go into a meta tag in ">
+
diff --git a/xircuits-graph-viewer/packages/core/README.md b/xircuits-graph-viewer/packages/core/README.md index 1a1d0369..f6f7b4bc 100644 --- a/xircuits-graph-viewer/packages/core/README.md +++ b/xircuits-graph-viewer/packages/core/README.md @@ -41,6 +41,29 @@ document.body.appendChild(svg); const { destroy, zoomBy, fitView } = attachPanZoom(svg); ``` +### Python component → node + +Turn a single `@xai_component`-decorated Python class into an `XGraph` with one node — useful for live previews, docs playgrounds, or tooling that consumes component source. + +```js +import { parsePythonComponent, renderToString } from '@xpressai/xircuits-viewer'; + +const { graph, error, warnings } = parsePythonComponent(` +@xai_component(color="blue") +class GreetUser(Component): + name: InArg[str] + message: OutArg[str] +`); + +if (graph) { + const svg = renderToString(graph, { theme: 'dark' }); +} +``` + +Recognises the decorator (`color`), `InArg`/`InCompArg`/`OutArg`/`BaseComponent` fields, and docstrings (ignored). Python types are normalised (`str` → `string`, `bool` → `boolean`, `List[...]` → `list`) so port icons match those in real `.xircuits` workflows. + +Regex-based and lightweight — it's designed for live-preview ergonomics, not arbitrary Python. Parses the first `@xai_component` class it finds. + ### Container background The SVG renders just the graph content. Apply the Xircuits dot-grid background on your container: @@ -85,6 +108,7 @@ const { output, stats } = minifyWithStats(workflowJson); | `renderFromUrl(url, options?)` | Fetch a `.xircuits` URL and return SVG string | | `renderXircuits(json, options?)` | Parse JSON + render to SVG string | | `parse(json)` | Parse `.xircuits` JSON into `XGraph` | +| `parsePythonComponent(source, options?)` | Parse Python component source into `{ graph, error, warnings }` | | `renderToString(graph, options?)` | Render `XGraph` to SVG string | | `renderToElement(graph, options?)` | Render `XGraph` to DOM `SVGSVGElement` | | `validate(json)` | Validate without parsing | diff --git a/xircuits-graph-viewer/packages/core/src/index.ts b/xircuits-graph-viewer/packages/core/src/index.ts index abe05ddc..a982d5d2 100644 --- a/xircuits-graph-viewer/packages/core/src/index.ts +++ b/xircuits-graph-viewer/packages/core/src/index.ts @@ -15,6 +15,8 @@ export type { // Parser export { parse } from './parser/parse.js'; export { validate } from './parser/validate.js'; +export { parsePythonComponent } from './parsePythonComponent.js'; +export type { ParseResult, ParsePythonOptions } from './parsePythonComponent.js'; // Layout export { computeNodeMetrics } from './layout/metrics.js'; diff --git a/xircuits-graph-viewer/packages/core/src/parsePythonComponent.ts b/xircuits-graph-viewer/packages/core/src/parsePythonComponent.ts new file mode 100644 index 00000000..83a10059 --- /dev/null +++ b/xircuits-graph-viewer/packages/core/src/parsePythonComponent.ts @@ -0,0 +1,212 @@ +import type { XGraph, XNode, XPort } from './types.js'; + +export interface ParseResult { + graph: XGraph | null; + error: string | null; + warnings: string[]; +} + +export interface ParsePythonOptions { + /** Node color to use when no @xai_component(color=...) is found. */ + defaultColor?: string; + /** Whether to inject the standard flow-in (▶) port. */ + includeFlowIn?: boolean; + /** Whether to inject the standard flow-out (▶) port. */ + includeFlowOut?: boolean; +} + +const DEFAULT_COLOR = 'rgb(153,51,204)'; + +const FIELD_RE = + /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*:\s*(InArg|InCompArg|OutArg|BaseComponent)\s*(?:\[\s*(.+)\s*\])?\s*(?:=.*)?\s*(?:#.*)?$/; + +const CLASS_RE = /^\s*class\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?:\([^)]*\))?\s*:\s*$/m; + +const DECORATOR_RE = /@xai_component\s*(?:\(([^)]*)\))?/; + +function extractKwarg(kwargs: string, key: string): string | null { + const re = new RegExp(`\\b${key}\\s*=\\s*(?:(["'])([^"']*)\\1|([^,\\s)]+))`); + const m = kwargs.match(re); + return m ? (m[2] ?? m[3] ?? null) : null; +} + +/** + * Parse a Python source string containing a single @xai_component class into + * an XGraph with one node. Designed for a live-preview use case where the + * input may be mid-edit; non-fatal issues are returned as `warnings`. + */ +export function parsePythonComponent( + source: string, + options: ParsePythonOptions = {} +): ParseResult { + const { + defaultColor = DEFAULT_COLOR, + includeFlowIn = true, + includeFlowOut = true, + } = options; + + const warnings: string[] = []; + + if (!source.trim()) { + return { graph: null, error: 'Empty source', warnings }; + } + + const classMatch = source.match(CLASS_RE); + if (!classMatch) { + return { graph: null, error: 'No class definition found', warnings }; + } + + const className = classMatch[1]; + const classIndex = source.indexOf(classMatch[0]); + + const preClass = source.slice(0, classIndex); + const decoratorMatch = preClass.match(DECORATOR_RE); + let color = defaultColor; + if (decoratorMatch) { + const colorKw = extractKwarg(decoratorMatch[1] ?? '', 'color'); + if (colorKw) color = colorKw; + } else { + warnings.push('No @xai_component decorator found; using default color'); + } + + const classBody = source.slice(classIndex + classMatch[0].length); + const fields = extractFields(classBody); + + const portsIn: XPort[] = []; + const portsOut: XPort[] = []; + + if (includeFlowIn) { + portsIn.push({ + id: 'preview-port-in-flow', + direction: 'in', + kind: 'flow', + label: '▶', + varName: 'in-0', + dataType: null, + linkIds: [], + }); + } + if (includeFlowOut) { + portsOut.push({ + id: 'preview-port-out-flow', + direction: 'out', + kind: 'flow', + label: '▶', + varName: 'out-0', + dataType: null, + linkIds: [], + }); + } + + let idCounter = 0; + for (const f of fields) { + const id = `preview-port-${idCounter++}`; + if (f.kind === 'OutArg') { + portsOut.push({ + id, direction: 'out', kind: 'parameter', + label: f.varName, varName: f.varName, + dataType: f.dataType, + linkIds: [], + }); + } else if (f.kind === 'BaseComponent') { + portsOut.push({ + id, direction: 'out', kind: 'flow', + label: f.varName, varName: f.varName, + dataType: null, + linkIds: [], + }); + } else { + // InArg / InCompArg + portsIn.push({ + id, direction: 'in', kind: 'parameter', + label: f.varName, varName: f.varName, + dataType: f.dataType, + linkIds: [], + }); + } + } + + const node: XNode = { + id: 'preview-node', + kind: 'component', + name: className, + color, + x: 0, + y: 0, + portsIn, + portsOut, + extras: { type: 'debug' }, + }; + + const graph: XGraph = { + id: 'preview-graph', + viewport: { x: 0, y: 0, zoom: 100 }, + nodes: [node], + edges: [], + }; + + return { graph, error: null, warnings }; +} + +type FieldKind = 'InArg' | 'InCompArg' | 'OutArg' | 'BaseComponent'; +interface Field { + varName: string; + kind: FieldKind; + dataType: string | null; +} + +// Map Python type annotations to the canonical xircuits type names used by +// the renderer's symbol table (see ./render/symbols.ts). +const PY_TYPE_TO_XIRCUITS: Record = { + str: 'string', + bool: 'boolean', + list: 'list', List: 'list', + tuple: 'tuple', Tuple: 'tuple', + dict: 'dict', Dict: 'dict', + any: 'any', Any: 'any', +}; + +function normaliseDataType(raw: string | null): string | null { + if (!raw) return null; + const outer = raw.split('[')[0].trim(); + return PY_TYPE_TO_XIRCUITS[outer] ?? outer; +} + +function extractFields(classBody: string): Field[] { + const fields: Field[] = []; + const lines = classBody.split('\n'); + + let inDocstring = false; + let docstringDelim = ''; + + for (const raw of lines) { + const line = raw.replace(/\r$/, ''); + const trimmed = line.trim(); + + if (inDocstring) { + if (trimmed.includes(docstringDelim)) inDocstring = false; + continue; + } + if (trimmed.startsWith('"""') || trimmed.startsWith("'''")) { + docstringDelim = trimmed.startsWith('"""') ? '"""' : "'''"; + const rest = trimmed.slice(3); + if (!rest.includes(docstringDelim)) inDocstring = true; + continue; + } + + if (trimmed.startsWith('def ') || trimmed.startsWith('class ') || trimmed.startsWith('@')) { + break; + } + + const m = line.match(FIELD_RE); + if (!m) continue; + const [, varName, kind, dataType] = m; + fields.push({ + varName, + kind: kind as FieldKind, + dataType: normaliseDataType(dataType ? dataType.trim() : null), + }); + } + + return fields; +} diff --git a/xircuits-graph-viewer/packages/react/README.md b/xircuits-graph-viewer/packages/react/README.md index 35842d5f..4d7e045f 100644 --- a/xircuits-graph-viewer/packages/react/README.md +++ b/xircuits-graph-viewer/packages/react/README.md @@ -49,6 +49,44 @@ import workflow from './MyWorkflow.xircuits'; ``` +### Live component preview (Python → node) + +Drop-in: a two-line demo with a textarea editor and a live-updating node preview. + +```tsx +import { ComponentPreview } from '@xpressai/xircuits-viewer-react'; + + +``` + +Plug in a real editor (CodeMirror, Monaco, etc.) via the `editor` prop: + +```tsx +import { ComponentPreview } from '@xpressai/xircuits-viewer-react'; +import CodeMirror from '@uiw/react-codemirror'; +import { python } from '@codemirror/lang-python'; + + ( + + )} + theme="dark" +/> +``` + +For full control over layout, skip `` and compose it yourself — `parsePythonComponent` (re-exported here from `@xpressai/xircuits-viewer`) is a pure function, and `` accepts a pre-built graph: + +```tsx +import { XircuitsGraph, parsePythonComponent } from '@xpressai/xircuits-viewer-react'; + +const { graph } = parsePythonComponent(pythonSource); +return graph ? : null; +``` + +The parser itself is documented in the [core package README](../core/README.md#python-component--node) — what it recognises, what it doesn't, and how Python types map to xircuits type names. + ## Props ### XircuitsGraph @@ -57,6 +95,7 @@ import workflow from './MyWorkflow.xircuits'; |------|------|---------|-------------| | `src` | `string` | — | URL to a `.xircuits` file | | `data` | `object` | — | Pre-loaded JSON (takes precedence over `src`) | +| `graph` | `XGraph` | — | Pre-parsed graph (takes precedence over both `data` and `src`) | | `theme` | `'dark' \| 'light'` | `'dark'` | Color theme | | `showCanvasBackground` | `boolean` | `true` | Render the Xircuits dot-grid background on the container | | `interactive` | `boolean` | `true` | Enable pan/zoom | @@ -73,6 +112,33 @@ import workflow from './MyWorkflow.xircuits'; Same props as above, minus `interactive`, `onNodeClick`, `onEdgeClick`. +### ComponentPreview + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `value` | `string` | *required* | Python source code | +| `onChange` | `(v: string) => void` | *required* | Called on edit | +| `editor` | `React.ComponentType<{ value, onChange, language }>` | plain `