diff --git a/.gitignore b/.gitignore index 40b4a01..02232e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ __pycache__/ +.DS_Store .devcontainer .env .venv @@ -11,7 +12,15 @@ datasets/ lib/ */kg_dump/ */graphs/ + *.json *.html models/ test.ipynb + +wikontic-demo-animation/node_modules/ +wikontic-demo-animation/out/ +wikontic-demo-animation/.vite/ +wikontic-demo-animation/*.mp4 +wikontic-demo-animation/*.png +!wikontic-demo-animation/**/*.html \ No newline at end of file diff --git a/wikontic-demo-animation/README.md b/wikontic-demo-animation/README.md new file mode 100644 index 0000000..1680d36 --- /dev/null +++ b/wikontic-demo-animation/README.md @@ -0,0 +1,227 @@ +# Wikontic Demo Animation + +Local React + Remotion project for the Wikontic demo animations. + +The project contains three independently renderable short animations and a separate presentation-style web viewer. Each animation starts automatically when its slide opens, and the viewer lets you pause, restart, jump between chapters, and move through the animations like a slide deck. + +## Requirements + +- Node.js 20+ recommended. +- npm 10+ recommended. +- A local Chromium-compatible environment for Remotion rendering. Remotion downloads/uses its own browser tooling through the installed packages. +- No backend services are required. +- No API keys are required. +- No live LLM/API calls are made. + +## Install + +From this folder: + +```bash +cd wikontic-demo-animation +npm install +``` + +The source of truth for dependency versions is `package-lock.json`. + +## Run The Presentation Viewer + +This is the recommended mode for a live demo. + +```bash +npm run present +``` + +Open: + +```text +http://localhost:5173/presentation.html +``` + +English is the default. Open the Russian version with: + +```text +http://localhost:5173/presentation.html?lang=ru +``` + +The viewer also has an `EN` / `RU` language toggle in the sidebar. + +If port `5173` is already busy, Vite may choose another port. You can also specify one explicitly: + +```bash +npm run present -- --host=127.0.0.1 --port=5174 +``` + +Presentation controls: + +- animations start automatically when their slide opens +- `Space`: play / pause current animation +- `R`: restart current animation +- `Left` / `Right`: previous / next slide +- `,` / `.`: step backward / forward by 15 frames +- number keys: jump to chapter markers in the current animation +- on-screen buttons: play, pause, restart, frame step, fullscreen, chapter jump + +The presentation viewer uses the Remotion React compositions directly through `@remotion/player`. It does not depend on the exported MP4 files. + +## Run Remotion Studio + +Use this mode for authoring and inspecting Remotion compositions directly. + +```bash +npm run preview +``` + +This opens Remotion Studio for the compositions registered in `src/Root.tsx`. + +Current composition IDs: + +- `TextToGraph` +- `TextToGraphRU` +- `TextToGraphEN` +- `RagVsWikontic` +- `RagVsWikonticRU` +- `RagVsWikonticEN` +- `SyntheticDataFactory` +- `SyntheticDataFactoryRU` +- `SyntheticDataFactoryEN` + +## Render Videos + +Render all three standalone MP4 files in English: + +```bash +npm run render:all +``` + +Render all three standalone MP4 files in Russian: + +```bash +npm run render:all:ru +``` + +Render one animation at a time: + +```bash +npm run render:text-to-graph +npm run render:text-to-graph:en +npm run render:text-to-graph:ru +npm run render:rag-vs-wikontic +npm run render:rag-vs-wikontic:en +npm run render:rag-vs-wikontic:ru +npm run render:synthetic-data +npm run render:synthetic-data:en +npm run render:synthetic-data:ru +``` + +Outputs are written to: + +```text +out/text-to-graph.mp4 +out/text-to-graph-en.mp4 +out/text-to-graph-ru.mp4 +out/rag-vs-wikontic.mp4 +out/rag-vs-wikontic-en.mp4 +out/rag-vs-wikontic-ru.mp4 +out/synthetic-data-factory.mp4 +out/synthetic-data-factory-en.mp4 +out/synthetic-data-factory-ru.mp4 +``` + +The `out/` folder is treated as generated output and should not be committed. + +## Optional Graph Demo + +There is also a simple backup graph demo: + +```bash +npm run graph:preview +``` + +This runs the Vite app entry in `index.html`, which mounts `src/interactive/GraphDemo.tsx`. + +## Code Organization + +Important entrypoints: + +- `src/index.ts`: Remotion registration entrypoint. +- `src/Root.tsx`: registers the three independent Remotion compositions. +- `presentation.html`: separate Vite entry for the presentation viewer. +- `src/presentation/main.tsx`: mounts the presentation viewer. +- `src/main.tsx`: mounts the optional graph demo. + +Animation scenes: + +- `src/scenes/Animation1_TextToGraph.tsx`: method animation, text to structured graph. +- `src/scenes/Animation2_RagVsGraph.tsx`: RAG comparison animation. +- `src/scenes/Animation3_SyntheticData.tsx`: synthetic data generation animation. + +Presentation viewer: + +- `src/presentation/PresentationApp.tsx`: slide-deck UI, Remotion Player, controls, final metrics slide. +- `src/presentation/presentationConfig.ts`: localized slide list, component references, durations, chapter frame markers. +- `src/presentation/presentation.css`: presentation-only styling. +- `src/i18n/types.ts`: shared locale type and locale normalization helper. + +Data: + +- `src/data/animation1.ts`: localized deterministic document, facts, triplets, ontology checks, compact graph. +- `src/data/animation2.ts`: localized natural business question, RAG chunks, internal graph path, answer. +- `src/data/animation3.ts`: localized answer node, sampled paths, natural QA cards, dataset labels. + +## Maintaining Two Languages + +English is the default language. Russian is selected in the viewer with `?lang=ru` or the `RU` toggle. + +When changing demo content: + +- Edit animation copy/data in `src/data/animation1.ts`, `src/data/animation2.ts`, and `src/data/animation3.ts`. +- Edit slide titles, subtitles, and chapter labels in `src/presentation/presentationConfig.ts`. +- Edit final metrics slide copy and viewer UI labels in `src/presentation/PresentationApp.tsx`. +- Keep graph node IDs, edge IDs, path IDs, and card counts identical across `en` and `ru`; translate only visible labels, questions, answers, paths, and display text. +- If changing layout, timing, or animation behavior, do it once in the scene/CSS files and verify both languages still fit. + +After bilingual edits, run: + +```bash +npm run check +``` + +For visual changes, spot-check representative stills in both English and Russian. + +Shared visual components: + +- `src/components/GraphView.tsx`: SVG graph rendering. +- `src/components/DocumentView.tsx`: document text with highlightable fact spans. +- `src/components/TripletCard.tsx`: extracted fact card. +- `src/components/OntologyPass.tsx`: ontology validation panel. +- `src/components/DedupMerge.tsx`: alias/deduplication merge visualization. +- `src/components/DatasetCard.tsx`: synthetic QA card. +- `src/components/MetricBadge.tsx`: metric badges used in final slide. + +## Assets + +Assets are stored in: + +```text +assets/ +public/assets/ +``` + +The presentation and Remotion components use the public assets path where needed, for example `/assets/wikontic.png`. + +## Validation + +Run TypeScript checks: + +```bash +npm run check +``` + +Expected constraints: + +- deterministic hardcoded data only +- no backend requests +- no external API calls +- Russian and English labels remain readable at 1920x1080 +- presentation viewer does not modify the animation scene files diff --git a/wikontic-demo-animation/assets/wikontic-schema.svg b/wikontic-demo-animation/assets/wikontic-schema.svg new file mode 100644 index 0000000..8821ad2 --- /dev/null +++ b/wikontic-demo-animation/assets/wikontic-schema.svg @@ -0,0 +1,3 @@ + + +
LLM
Ontology
+
entity types
relations constraints
Wikidata
LLM

KG view

Triplet view

Current KG
+
LLM
x
KG with Entity types & Relations
aligned with Ontology
Nolan
human
Inception
movie
film
Science fiction
genre
film genre
2010
directed
director
genre
Nolan
human
Inception
movie
Science fiction
genre
2010
directed
genre
entities to be merged
Candidate Triplets
Text
 In 2010Nolan
 directed the 
science fiction 
movie Inception.

Refined triplets w/o duplicate entities   added to the existing KG

Nolan
Christopher Nolan
human
Inception
film
Science fiction
fim genre
2010
director
genre
nodes from existing KG
(1)
(2)
(3)
\ No newline at end of file diff --git a/wikontic-demo-animation/assets/wikontic.png b/wikontic-demo-animation/assets/wikontic.png new file mode 100644 index 0000000..53e7405 Binary files /dev/null and b/wikontic-demo-animation/assets/wikontic.png differ diff --git a/wikontic-demo-animation/assets/wikotic-wo-text.png b/wikontic-demo-animation/assets/wikotic-wo-text.png new file mode 100644 index 0000000..dedf9d0 Binary files /dev/null and b/wikontic-demo-animation/assets/wikotic-wo-text.png differ diff --git a/wikontic-demo-animation/index.html b/wikontic-demo-animation/index.html new file mode 100644 index 0000000..43eaf6b --- /dev/null +++ b/wikontic-demo-animation/index.html @@ -0,0 +1,12 @@ + + + + + + Wikontic Graph Demo + + +
+ + + diff --git a/wikontic-demo-animation/package-lock.json b/wikontic-demo-animation/package-lock.json new file mode 100644 index 0000000..0e35083 --- /dev/null +++ b/wikontic-demo-animation/package-lock.json @@ -0,0 +1,4525 @@ +{ + "name": "wikontic-demo-animation", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "wikontic-demo-animation", + "version": "0.1.0", + "dependencies": { + "@remotion/cli": "^4.0.0", + "@remotion/player": "^4.0.0", + "@remotion/renderer": "^4.0.0", + "@remotion/transitions": "^4.0.0", + "@vitejs/plugin-react": "^5.0.0", + "lucide-react": "^0.468.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "remotion": "^4.0.0", + "vite": "^7.0.0" + }, + "devDependencies": { + "@types/react": "^19.2.16", + "@types/react-dom": "^19.2.3", + "typescript": "^5.7.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@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/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/generator/node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports/node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mediabunny/aac-encoder": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/@mediabunny/aac-encoder/-/aac-encoder-1.45.0.tgz", + "integrity": "sha512-vLQw8cY7Me6pvTTMkMhOiH9UCuINzfTOETCeDxbGNeNfDqc/7QlxloUH1Ylp/Zz2ek0O8kc6YdygV2vWAPakrA==", + "license": "MPL-2.0", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/Vanilagy" + }, + "peerDependencies": { + "mediabunny": "^1.0.0" + } + }, + "node_modules/@mediabunny/flac-encoder": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/@mediabunny/flac-encoder/-/flac-encoder-1.45.0.tgz", + "integrity": "sha512-LfKbAMZVkxRS7PpEIVnWOY/l0KcHv+rjO7pYY3O0TPCZvbHWfrnQjn8JPacPIfuq6Yv7r4f8lhcl7yHSynoRkQ==", + "license": "MPL-2.0", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/Vanilagy" + }, + "peerDependencies": { + "mediabunny": "^1.0.0" + } + }, + "node_modules/@mediabunny/mp3-encoder": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/@mediabunny/mp3-encoder/-/mp3-encoder-1.45.0.tgz", + "integrity": "sha512-Bobi6AaQYEc7TWmPJ8Q0/hcUtBN7pLUC2qjoC7oZR4FcGqGztby6k7A1SWlmswoMOEIhYsOrgDaemrSDAC0QVQ==", + "license": "MPL-2.0", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/Vanilagy" + }, + "peerDependencies": { + "mediabunny": "^1.0.0" + } + }, + "node_modules/@module-federation/error-codes": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz", + "integrity": "sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==", + "license": "MIT" + }, + "node_modules/@module-federation/runtime": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.22.0.tgz", + "integrity": "sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==", + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.22.0", + "@module-federation/runtime-core": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@module-federation/runtime-core": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.22.0.tgz", + "integrity": "sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==", + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.22.0.tgz", + "integrity": "sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==", + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.22.0", + "@module-federation/webpack-bundler-runtime": "0.22.0" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.22.0.tgz", + "integrity": "sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==", + "license": "MIT" + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.22.0.tgz", + "integrity": "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==", + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz", + "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@tybys/wasm-util": "^0.10.1" + } + }, + "node_modules/@remotion/bundler": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/bundler/-/bundler-4.0.472.tgz", + "integrity": "sha512-aj5nZkQJfI45HlHZ9wsjG1pRXJ4QsCHT12LUF7k18pT+7ysoDipAFkGNq85pBbBdQ7pSdl6+uJuGzDVFw2Hacg==", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "@remotion/media-parser": "4.0.472", + "@remotion/studio": "4.0.472", + "@remotion/studio-shared": "4.0.472", + "@remotion/timeline-utils": "4.0.472", + "@rspack/core": "1.7.6", + "@rspack/plugin-react-refresh": "1.6.1", + "css-loader": "7.1.4", + "esbuild": "0.28.0", + "react-refresh": "0.18.0", + "remotion": "4.0.472", + "style-loader": "4.0.0", + "webpack": "5.105.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@remotion/cli": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/cli/-/cli-4.0.472.tgz", + "integrity": "sha512-A+oSK7LcDzo5A+95/PnjU3tRShbD3opTYd7wtb4Pgv6uO2HFpatmfSzsT0uwkEc0MuETs6bjSt5IMttGk/2cKA==", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "@remotion/bundler": "4.0.472", + "@remotion/media-utils": "4.0.472", + "@remotion/player": "4.0.472", + "@remotion/renderer": "4.0.472", + "@remotion/studio": "4.0.472", + "@remotion/studio-server": "4.0.472", + "@remotion/studio-shared": "4.0.472", + "dotenv": "17.3.1", + "minimist": "1.2.6", + "prompts": "2.4.2", + "remotion": "4.0.472" + }, + "bin": { + "remotion": "remotion-cli.js", + "remotionb": "remotionb-cli.js", + "remotiond": "remotiond-cli.js" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@remotion/compositor-darwin-arm64": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/compositor-darwin-arm64/-/compositor-darwin-arm64-4.0.472.tgz", + "integrity": "sha512-rx1CfDem1AutPYWGqXyV8dFQ+YsCE6pYrj0cLDAtx/5xPazTnMhx1X59SM21legGzBrcMVmXyV7TXoc0psGb+A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@remotion/compositor-darwin-x64": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/compositor-darwin-x64/-/compositor-darwin-x64-4.0.472.tgz", + "integrity": "sha512-v8unDWuK52AGIEr9r9g+9G0Q3JNQdnjlKqSw9bBXPI2YkWms4Z5LSfSR5S0BEp7vXFRmhZm7i/3biI6p3P1LDw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@remotion/compositor-linux-arm64-gnu": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/compositor-linux-arm64-gnu/-/compositor-linux-arm64-gnu-4.0.472.tgz", + "integrity": "sha512-Nv+4zePiAn5lYAy4qZKHBTeIoRjoXkatucv72OXC54Q3spkjOravOVGalxbGm021rMMGtJw0JoL0Sq4HyNjzbg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@remotion/compositor-linux-arm64-musl": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/compositor-linux-arm64-musl/-/compositor-linux-arm64-musl-4.0.472.tgz", + "integrity": "sha512-Zal+fYYQQTaymg8IxaZKQzotSWfGYfucNyX0M+uRJZzZ0PIfSqSbk6NyfTqIq3Fvc9r1Lb95ZXvWOGPZxAWdJQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@remotion/compositor-linux-x64-gnu": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/compositor-linux-x64-gnu/-/compositor-linux-x64-gnu-4.0.472.tgz", + "integrity": "sha512-cxjPknG9xeqvHX3eDxcOwKjpF3Yghtpel7QIJkZGZ0pZn0CHA8Q90pHIfWbX5vZ2PuBY9VMd84KafdCi+iXofQ==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@remotion/compositor-linux-x64-musl": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/compositor-linux-x64-musl/-/compositor-linux-x64-musl-4.0.472.tgz", + "integrity": "sha512-b5005WFifrfxsViyReGBEn04I2B/rLe7RQQpNNhl+qr/X3l0ouWf9rqZxB5IU5Sut1iLRCHrPdlAW6M3HgaFCw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@remotion/compositor-win32-x64-msvc": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/compositor-win32-x64-msvc/-/compositor-win32-x64-msvc-4.0.472.tgz", + "integrity": "sha512-hvWIh4qWujTBr8SxJhbzPMSLYoWqjQShWtc3zRfORtziLulc1lf61MdXGPaUYn5RGJMF1BgoVo0pctmJ5ZAdeA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@remotion/licensing": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/licensing/-/licensing-4.0.472.tgz", + "integrity": "sha512-U4HDRXZHA+Jm7n8SErFBIwfUvKm72DB5w9tuddRmPTBbvZGvl6XCmdndDcO6Wy/1QHAPbjIfhy912nWUVz5HGg==", + "license": "MIT" + }, + "node_modules/@remotion/media-parser": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/media-parser/-/media-parser-4.0.472.tgz", + "integrity": "sha512-tgk83JXQCkrZDToYR3uaSxmWcy1jFuy0B5zWYZB58ocskuR4ZxJwFjjyJT7cPlQd7gWZG9RTET2xtdsffycKYg==", + "license": "Remotion License https://remotion.dev/license" + }, + "node_modules/@remotion/media-utils": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/media-utils/-/media-utils-4.0.472.tgz", + "integrity": "sha512-Hz2Ght6qiNg95Uzw/FovybhExHnS0WZPT/rxt4z/y0HrunemyCrSE8XOXNdXxqnVwHGRdfxJ+wlJflXuZQpX1w==", + "license": "MIT", + "dependencies": { + "mediabunny": "1.45.0", + "remotion": "4.0.472" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@remotion/paths": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/paths/-/paths-4.0.472.tgz", + "integrity": "sha512-BfNeYnZBYDdItR3JwQXItc1j6ycSGv0beLaKWFNG1GLcPteICgeHzmFDwg9xmjbvqhKBad+h4aI8ZRirxNQ/jQ==", + "license": "MIT" + }, + "node_modules/@remotion/player": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/player/-/player-4.0.472.tgz", + "integrity": "sha512-YVQDIKzIpLLgHoufoTn9FogLfwrOOvm2UWvFHVLVKNtXp6LFjWaRPoa7vv/a4kZdqyv14Y0r2/1N93CpzoHEZQ==", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "remotion": "4.0.472" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@remotion/renderer": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/renderer/-/renderer-4.0.472.tgz", + "integrity": "sha512-SdYGr2Qw2PYTN6OCdssU41fs8i8ql3mv9A7KISc7rVK43dKjl0QUmgKxnbqng8E0mTFOufUMHkH8O+7eRXaYgQ==", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "@remotion/licensing": "4.0.472", + "@remotion/streaming": "4.0.472", + "execa": "5.1.1", + "remotion": "4.0.472", + "source-map": "0.8.0-beta.0", + "ws": "8.20.1" + }, + "optionalDependencies": { + "@remotion/compositor-darwin-arm64": "4.0.472", + "@remotion/compositor-darwin-x64": "4.0.472", + "@remotion/compositor-linux-arm64-gnu": "4.0.472", + "@remotion/compositor-linux-arm64-musl": "4.0.472", + "@remotion/compositor-linux-x64-gnu": "4.0.472", + "@remotion/compositor-linux-x64-musl": "4.0.472", + "@remotion/compositor-win32-x64-msvc": "4.0.472" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@remotion/shapes": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/shapes/-/shapes-4.0.472.tgz", + "integrity": "sha512-2iv19VDZBxUJv4xfTst8/cmSyzrydYTLUmrG394C5eUgMQofR5ktYq9wh9nImIigSuKz/tY3/IDaW+KBcL03iw==", + "license": "MIT", + "dependencies": { + "@remotion/paths": "4.0.472" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@remotion/streaming": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/streaming/-/streaming-4.0.472.tgz", + "integrity": "sha512-sx2fhVhPwYj6mVoqP4WZUbTC0Pl7xpuiftentSSPtQtmmZ3NP9kPlsBL850JooDHVOS2q5KZPfp+aGkZnIEQ0w==", + "license": "MIT" + }, + "node_modules/@remotion/studio": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/studio/-/studio-4.0.472.tgz", + "integrity": "sha512-BJnZI1BG9v4D1x3MNY/3AvqtjuBWPt77+Y4zK4PTX4Ap2HSnT2H/bu7bxEv1mmBF/7fusFV+BmdQL18IMqGB/A==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.31", + "@remotion/media-utils": "4.0.472", + "@remotion/player": "4.0.472", + "@remotion/renderer": "4.0.472", + "@remotion/studio-shared": "4.0.472", + "@remotion/timeline-utils": "4.0.472", + "@remotion/web-renderer": "4.0.472", + "@remotion/zod-types": "4.0.472", + "mediabunny": "1.45.0", + "memfs": "3.4.3", + "open": "8.4.2", + "remotion": "4.0.472", + "semver": "7.5.3", + "zod": "4.3.6" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@remotion/studio-server": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/studio-server/-/studio-server-4.0.472.tgz", + "integrity": "sha512-GI78aqsM9ntaiFeitYn+B7mOMVMQwIJnyaN/jExZ+tw8/HiQSn1qjt6mvznvMnCTeQRp6wgPmyThoXleBTgoCQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "7.24.1", + "@babel/types": "7.24.0", + "@remotion/bundler": "4.0.472", + "@remotion/renderer": "4.0.472", + "@remotion/studio-shared": "4.0.472", + "memfs": "3.4.3", + "open": "8.4.2", + "prettier": "3.8.1", + "recast": "0.23.11", + "remotion": "4.0.472", + "semver": "7.5.3" + } + }, + "node_modules/@remotion/studio-shared": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/studio-shared/-/studio-shared-4.0.472.tgz", + "integrity": "sha512-JP5SDmfJ+WPbYTpXauZ7OF2Sk0ppKdKSk2NGLE6EASiLTVg9edt1wxat7aP5eHAnkpHbEicCQrYVvSN0lPQORg==", + "license": "MIT", + "dependencies": { + "remotion": "4.0.472" + } + }, + "node_modules/@remotion/timeline-utils": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/timeline-utils/-/timeline-utils-4.0.472.tgz", + "integrity": "sha512-MIJ5+45qvEHubFh5Lb5Jt15CagsEatLRXYhpV/re1DC2GkdnAkdbHqk50yUuw10zYKa8qZyDQrrVD0qM5HL5kQ==", + "license": "MIT", + "dependencies": { + "mediabunny": "1.45.0" + } + }, + "node_modules/@remotion/transitions": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/transitions/-/transitions-4.0.472.tgz", + "integrity": "sha512-2Ov9gbtIiqXisAQDxblPhn6JFpxIPrd/rzgfFIrlE8nYTRG3WdeOyBWLrhjYsT/EwjAsGYUhx7cII9oO4H4vyA==", + "license": "UNLICENSED", + "dependencies": { + "@remotion/paths": "4.0.472", + "@remotion/shapes": "4.0.472", + "remotion": "4.0.472" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@remotion/web-renderer": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/web-renderer/-/web-renderer-4.0.472.tgz", + "integrity": "sha512-ufiFmgQ4dcF8MuKEIZ3WJHU8PyvAQgcPoyOsWUNXHEZoVz9cD0t6efDF67HEOb/sl6sd/1n2li+CRzvmBi+YUA==", + "license": "UNLICENSED", + "dependencies": { + "@mediabunny/aac-encoder": "1.45.0", + "@mediabunny/flac-encoder": "1.45.0", + "@mediabunny/mp3-encoder": "1.45.0", + "@remotion/licensing": "4.0.472", + "mediabunny": "1.45.0", + "remotion": "4.0.472" + }, + "peerDependencies": { + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/@remotion/zod-types": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/@remotion/zod-types/-/zod-types-4.0.472.tgz", + "integrity": "sha512-5exoKjC+7gl2Xaht8uKnhUlwBpDBLvaX6NTzVzhUOvMbWd19JWKFDyjRxZiHKGmz5P2STaN/p4oCU3dNKFmi5w==", + "license": "MIT", + "dependencies": { + "remotion": "4.0.472" + }, + "peerDependencies": { + "zod": "4.3.6" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", + "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", + "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", + "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", + "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", + "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", + "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", + "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", + "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", + "cpu": [ + "arm" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", + "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", + "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", + "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", + "cpu": [ + "loong64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", + "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", + "cpu": [ + "loong64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", + "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", + "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", + "cpu": [ + "ppc64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", + "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", + "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", + "cpu": [ + "riscv64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", + "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", + "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", + "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", + "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", + "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", + "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", + "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", + "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", + "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.7.6.tgz", + "integrity": "sha512-/NrEcfo8Gx22hLGysanrV6gHMuqZSxToSci/3M4kzEQtF5cPjfOv5pqeLK/+B6cr56ul/OmE96cCdWcXeVnFjQ==", + "license": "MIT", + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.7.6", + "@rspack/binding-darwin-x64": "1.7.6", + "@rspack/binding-linux-arm64-gnu": "1.7.6", + "@rspack/binding-linux-arm64-musl": "1.7.6", + "@rspack/binding-linux-x64-gnu": "1.7.6", + "@rspack/binding-linux-x64-musl": "1.7.6", + "@rspack/binding-wasm32-wasi": "1.7.6", + "@rspack/binding-win32-arm64-msvc": "1.7.6", + "@rspack/binding-win32-ia32-msvc": "1.7.6", + "@rspack/binding-win32-x64-msvc": "1.7.6" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.7.6.tgz", + "integrity": "sha512-NZ9AWtB1COLUX1tA9HQQvWpTy07NSFfKBU8A6ylWd5KH8AePZztpNgLLAVPTuNO4CZXYpwcoclf8jG/luJcQdQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.7.6.tgz", + "integrity": "sha512-J2g6xk8ZS7uc024dNTGTHxoFzFovAZIRixUG7PiciLKTMP78svbSSWrmW6N8oAsAkzYfJWwQpVgWfFNRHvYxSw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.7.6.tgz", + "integrity": "sha512-eQfcsaxhFrv5FmtaA7+O1F9/2yFDNIoPZzV/ZvqvFz5bBXVc4FAm/1fVpBg8Po/kX1h0chBc7Xkpry3cabFW8w==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.7.6.tgz", + "integrity": "sha512-DfQXKiyPIl7i1yECHy4eAkSmlUzzsSAbOjgMuKn7pudsWf483jg0UUYutNgXSlBjc/QSUp7906Cg8oty9OfwPA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.7.6.tgz", + "integrity": "sha512-NdA+2X3lk2GGrMMnTGyYTzM3pn+zNjaqXqlgKmFBXvjfZqzSsKq3pdD1KHZCd5QHN+Fwvoszj0JFsquEVhE1og==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.7.6.tgz", + "integrity": "sha512-rEy6MHKob02t/77YNgr6dREyJ0e0tv1X6Xsg8Z5E7rPXead06zefUbfazj4RELYySWnM38ovZyJAkPx/gOn3VA==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-wasm32-wasi": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.7.6.tgz", + "integrity": "sha512-YupOrz0daSG+YBbCIgpDgzfMM38YpChv+afZpaxx5Ml7xPeAZIIdgWmLHnQ2rts73N2M1NspAiBwV00Xx0N4Vg==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "1.0.7" + } + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.7.6.tgz", + "integrity": "sha512-INj7aVXjBvlZ84kEhSK4kJ484ub0i+BzgnjDWOWM1K+eFYDZjLdAsQSS3fGGXwVc3qKbPIssFfnftATDMTEJHQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.7.6.tgz", + "integrity": "sha512-lXGvC+z67UMcw58In12h8zCa9IyYRmuptUBMItQJzu+M278aMuD1nETyGLL7e4+OZ2lvrnnBIcjXN1hfw2yRzw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.7.6.tgz", + "integrity": "sha512-zeUxEc0ZaPpmaYlCeWcjSJUPuRRySiSHN23oJ2Xyw0jsQ01Qm4OScPdr0RhEOFuK/UE+ANyRtDo4zJsY52Hadw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/core": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.7.6.tgz", + "integrity": "sha512-Iax6UhrfZqJajA778c1d5DBFbSIqPOSrI34kpNIiNpWd8Jq7mFIa+Z60SQb5ZQDZuUxcCZikjz5BxinFjTkg7Q==", + "license": "MIT", + "dependencies": { + "@module-federation/runtime-tools": "0.22.0", + "@rspack/binding": "1.7.6", + "@rspack/lite-tapable": "1.1.0" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.1.0.tgz", + "integrity": "sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw==", + "license": "MIT" + }, + "node_modules/@rspack/plugin-react-refresh": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-1.6.1.tgz", + "integrity": "sha512-eqqW5645VG3CzGzFgNg5HqNdHVXY+567PGjtDhhrM8t67caxmsSzRmT5qfoEIfBcGgFkH9vEg7kzXwmCYQdQDw==", + "license": "MIT", + "dependencies": { + "error-stack-parser": "^2.1.4", + "html-entities": "^2.6.0" + }, + "peerDependencies": { + "react-refresh": ">=0.10.0 <1.0.0", + "webpack-hot-middleware": "2.x" + }, + "peerDependenciesMeta": { + "webpack-hot-middleware": { + "optional": true + } + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/babel__traverse/node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@types/dom-mediacapture-transform": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@types/dom-mediacapture-transform/-/dom-mediacapture-transform-0.1.11.tgz", + "integrity": "sha512-Y2p+nGf1bF2XMttBnsVPHUWzRRZzqUoJAKmiP10b5umnO6DDrWI0BrGDJy1pOHoOULVmGSfFNkQrAlC5dcj6nQ==", + "license": "MIT", + "dependencies": { + "@types/dom-webcodecs": "*" + } + }, + "node_modules/@types/dom-webcodecs": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz", + "integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==", + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", + "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", + "license": "MIT", + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/@types/react": { + "version": "19.2.16", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.16.tgz", + "integrity": "sha512-esJiCAnl0kfpNdE69f3So4WJUXy95dLZydX0KwK46riIHDzHM7O9Vtf9xCHW0PXIqvgqNrswl522kA/5yx+F4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", + "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "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", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "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", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "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", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "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", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "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", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "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", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "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", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.33", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.33.tgz", + "integrity": "sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "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", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001793", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", + "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", + "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/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.4.tgz", + "integrity": "sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.40", + "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.6.3" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-loader/node_modules/semver": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.2.tgz", + "integrity": "sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", + "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.367", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.367.tgz", + "integrity": "sha512-4Mk/mrynCNQ+atY40D3UpmhLWB6AHMbYMlIrPhHcMF6x0L7O0b052FCAsxw1LlaR++UFuNg3D/A6XCuGDa0guQ==", + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.22.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.2.tgz", + "integrity": "sha512-0rxICaFZ7NQho/sHely2bvOPRP0Eu2B0NZ9zM54YvRvWMn7jfz3DmnOZDR9LlXDdDcqntAVc6Hfy4gr/tdH/Ag==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "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", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "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/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "license": "Unlicense" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/loader-runner": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", + "integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==", + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.468.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.468.0.tgz", + "integrity": "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, + "node_modules/mediabunny": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.45.0.tgz", + "integrity": "sha512-oK3sMMYbucoF6LUX62L/2M9d+p9ve6KDQgL87kNfhsB0/XmTe9iRLUcgQgg9Gpgvi8Sb96zYfOUL6i17y0bdNg==", + "license": "MPL-2.0", + "workspaces": [ + ".", + "packages/*" + ], + "dependencies": { + "@types/dom-mediacapture-transform": "^0.1.11", + "@types/dom-webcodecs": "0.1.13" + }, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/Vanilagy" + } + }, + "node_modules/memfs": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.3.tgz", + "integrity": "sha512-eivjfi7Ahr6eQTn44nvTnR60e4a1Fs1Via2kCR5lHo/kyNoiMWaXCNJ/GpSd0ilXas2JSOl9B5FTIhflXu0hlg==", + "license": "Unlicense", + "dependencies": { + "fs-monkey": "1.0.3" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "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/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "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/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "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.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "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-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/recast": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/recast/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remotion": { + "version": "4.0.472", + "resolved": "https://registry.npmjs.org/remotion/-/remotion-4.0.472.tgz", + "integrity": "sha512-HxzK5lakpZZyb5Gc+0awg9GLPLsRJo+5uomHknZFbfBWHsFRmdGvEYCiYlvwVZpg/iJNgU1wbSZLuyjCJGxg5A==", + "license": "SEE LICENSE IN LICENSE.md", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", + "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.61.1", + "@rollup/rollup-android-arm64": "4.61.1", + "@rollup/rollup-darwin-arm64": "4.61.1", + "@rollup/rollup-darwin-x64": "4.61.1", + "@rollup/rollup-freebsd-arm64": "4.61.1", + "@rollup/rollup-freebsd-x64": "4.61.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", + "@rollup/rollup-linux-arm-musleabihf": "4.61.1", + "@rollup/rollup-linux-arm64-gnu": "4.61.1", + "@rollup/rollup-linux-arm64-musl": "4.61.1", + "@rollup/rollup-linux-loong64-gnu": "4.61.1", + "@rollup/rollup-linux-loong64-musl": "4.61.1", + "@rollup/rollup-linux-ppc64-gnu": "4.61.1", + "@rollup/rollup-linux-ppc64-musl": "4.61.1", + "@rollup/rollup-linux-riscv64-gnu": "4.61.1", + "@rollup/rollup-linux-riscv64-musl": "4.61.1", + "@rollup/rollup-linux-s390x-gnu": "4.61.1", + "@rollup/rollup-linux-x64-gnu": "4.61.1", + "@rollup/rollup-linux-x64-musl": "4.61.1", + "@rollup/rollup-openbsd-x64": "4.61.1", + "@rollup/rollup-openharmony-arm64": "4.61.1", + "@rollup/rollup-win32-arm64-msvc": "4.61.1", + "@rollup/rollup-win32-ia32-msvc": "4.61.1", + "@rollup/rollup-win32-x64-gnu": "4.61.1", + "@rollup/rollup-win32-x64-msvc": "4.61.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "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/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "deprecated": "The work that was done in this beta branch won't be included in future versions", + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "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", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "license": "MIT" + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/style-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", + "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.27.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz", + "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==", + "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.6.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==", + "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": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "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/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz", + "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "license": "BSD-2-Clause" + }, + "node_modules/webpack": { + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", + "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.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.19.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.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" + }, + "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-sources": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz", + "integrity": "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ws": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", + "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "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/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/wikontic-demo-animation/package.json b/wikontic-demo-animation/package.json new file mode 100644 index 0000000..f8decf4 --- /dev/null +++ b/wikontic-demo-animation/package.json @@ -0,0 +1,41 @@ +{ + "name": "wikontic-demo-animation", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "preview": "remotion studio src/index.ts", + "present": "vite --host 0.0.0.0 --open /presentation.html", + "render:text-to-graph": "remotion render src/index.ts TextToGraph out/text-to-graph.mp4 --codec=h264 --pixel-format=yuv420p", + "render:text-to-graph:en": "remotion render src/index.ts TextToGraphEN out/text-to-graph-en.mp4 --codec=h264 --pixel-format=yuv420p", + "render:text-to-graph:ru": "remotion render src/index.ts TextToGraphRU out/text-to-graph-ru.mp4 --codec=h264 --pixel-format=yuv420p", + "render:rag-vs-wikontic": "remotion render src/index.ts RagVsWikontic out/rag-vs-wikontic.mp4 --codec=h264 --pixel-format=yuv420p", + "render:rag-vs-wikontic:en": "remotion render src/index.ts RagVsWikonticEN out/rag-vs-wikontic-en.mp4 --codec=h264 --pixel-format=yuv420p", + "render:rag-vs-wikontic:ru": "remotion render src/index.ts RagVsWikonticRU out/rag-vs-wikontic-ru.mp4 --codec=h264 --pixel-format=yuv420p", + "render:synthetic-data": "remotion render src/index.ts SyntheticDataFactory out/synthetic-data-factory.mp4 --codec=h264 --pixel-format=yuv420p", + "render:synthetic-data:en": "remotion render src/index.ts SyntheticDataFactoryEN out/synthetic-data-factory-en.mp4 --codec=h264 --pixel-format=yuv420p", + "render:synthetic-data:ru": "remotion render src/index.ts SyntheticDataFactoryRU out/synthetic-data-factory-ru.mp4 --codec=h264 --pixel-format=yuv420p", + "render:all": "npm run render:text-to-graph && npm run render:rag-vs-wikontic && npm run render:synthetic-data", + "render:all:en": "npm run render:text-to-graph:en && npm run render:rag-vs-wikontic:en && npm run render:synthetic-data:en", + "render:all:ru": "npm run render:text-to-graph:ru && npm run render:rag-vs-wikontic:ru && npm run render:synthetic-data:ru", + "check": "tsc --noEmit", + "graph:preview": "vite --host 0.0.0.0" + }, + "dependencies": { + "@remotion/cli": "^4.0.0", + "@remotion/player": "^4.0.0", + "@remotion/renderer": "^4.0.0", + "@remotion/transitions": "^4.0.0", + "@vitejs/plugin-react": "^5.0.0", + "lucide-react": "^0.468.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "remotion": "^4.0.0", + "vite": "^7.0.0" + }, + "devDependencies": { + "@types/react": "^19.2.16", + "@types/react-dom": "^19.2.3", + "typescript": "^5.7.0" + } +} diff --git a/wikontic-demo-animation/presentation.html b/wikontic-demo-animation/presentation.html new file mode 100644 index 0000000..9460558 --- /dev/null +++ b/wikontic-demo-animation/presentation.html @@ -0,0 +1,12 @@ + + + + + + Wikontic Presentation + + +
+ + + diff --git a/wikontic-demo-animation/public/assets/wikontic-schema.svg b/wikontic-demo-animation/public/assets/wikontic-schema.svg new file mode 100644 index 0000000..8821ad2 --- /dev/null +++ b/wikontic-demo-animation/public/assets/wikontic-schema.svg @@ -0,0 +1,3 @@ + + +
LLM
Ontology
+
entity types
relations constraints
Wikidata
LLM

KG view

Triplet view

Current KG
+
LLM
x
KG with Entity types & Relations
aligned with Ontology
Nolan
human
Inception
movie
film
Science fiction
genre
film genre
2010
directed
director
genre
Nolan
human
Inception
movie
Science fiction
genre
2010
directed
genre
entities to be merged
Candidate Triplets
Text
 In 2010Nolan
 directed the 
science fiction 
movie Inception.

Refined triplets w/o duplicate entities   added to the existing KG

Nolan
Christopher Nolan
human
Inception
film
Science fiction
fim genre
2010
director
genre
nodes from existing KG
(1)
(2)
(3)
\ No newline at end of file diff --git a/wikontic-demo-animation/public/assets/wikontic.png b/wikontic-demo-animation/public/assets/wikontic.png new file mode 100644 index 0000000..53e7405 Binary files /dev/null and b/wikontic-demo-animation/public/assets/wikontic.png differ diff --git a/wikontic-demo-animation/public/assets/wikotic-wo-text.png b/wikontic-demo-animation/public/assets/wikotic-wo-text.png new file mode 100644 index 0000000..dedf9d0 Binary files /dev/null and b/wikontic-demo-animation/public/assets/wikotic-wo-text.png differ diff --git a/wikontic-demo-animation/src/Root.tsx b/wikontic-demo-animation/src/Root.tsx new file mode 100644 index 0000000..9778675 --- /dev/null +++ b/wikontic-demo-animation/src/Root.tsx @@ -0,0 +1,98 @@ +import React from 'react'; +import {Composition} from 'remotion'; +import {Animation1_TextToGraph, TEXT_TO_GRAPH_FRAMES} from './scenes/Animation1_TextToGraph'; +import {Animation2_RagVsGraph, RAG_VS_WIKONTIC_FRAMES} from './scenes/Animation2_RagVsGraph'; +import {Animation3_SyntheticData, SYNTHETIC_DATA_FRAMES} from './scenes/Animation3_SyntheticData'; +import {FPS, VIDEO_HEIGHT, VIDEO_WIDTH} from './theme'; +import type {Locale} from './i18n/types'; +import './styles/global.css'; + +const localeProps = (locale: Locale) => ({locale}); + +export const RemotionRoot: React.FC = () => { + return ( + <> + + + + + + + + + + + ); +}; diff --git a/wikontic-demo-animation/src/components/DatasetCard.tsx b/wikontic-demo-animation/src/components/DatasetCard.tsx new file mode 100644 index 0000000..47dc9d1 --- /dev/null +++ b/wikontic-demo-animation/src/components/DatasetCard.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import {Brain, Layers3} from 'lucide-react'; +import {PathHighlight} from './PathHighlight'; + +type DatasetCardProps = { + question: string; + answer: string; + path: string; + difficulty: string; + progress?: number; +}; + +export const DatasetCard: React.FC = ({ + question, + answer, + path, + difficulty, + progress = 1, +}) => ( +
+
+ {difficulty} + +
+
{question}
+
{answer}
+ +
+); + +export const SmallModelIcon: React.FC<{progress?: number}> = ({progress = 1}) => ( +
+ + малая доменная модель +
+); diff --git a/wikontic-demo-animation/src/components/DedupMerge.tsx b/wikontic-demo-animation/src/components/DedupMerge.tsx new file mode 100644 index 0000000..6bc70ca --- /dev/null +++ b/wikontic-demo-animation/src/components/DedupMerge.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import {GitMerge} from 'lucide-react'; +import {colors} from '../theme'; + +type DedupMergeProps = { + progress: number; + title?: string; + aliases?: {label: string; x: number; y: number}[]; + canonical?: string; + aliasTags?: string[]; + aliasesPrefix?: string; + footer?: string; +}; + +const lerp = (from: number, to: number, progress: number) => from + (to - from) * progress; + +export const DedupMerge: React.FC = ({ + progress, + title = 'Очистка и дедупликация', + aliases = [ + {label: 'ЖК', x: 190, y: 155}, + {label: 'жилой комплекс', x: 380, y: 82}, + {label: 'объект', x: 560, y: 155}, + ], + canonical = 'жилой комплекс', + aliasTags = ['ЖК', 'объект'], + aliasesPrefix = 'aliases:', + footer = 'Синонимы объединены в одну сущность', +}) => { + const p = Math.max(0, Math.min(1, progress)); + const target = {x: 380, y: 255}; + return ( +
+
+ + {title} +
+ + + + + + + + + + + {aliases.map((alias) => { + const x = lerp(alias.x, target.x, p); + const y = lerp(alias.y, target.y, p); + return ( + + + + + {alias.label} + + + ); + })} + 0.6 ? 'url(#dedupGlow)' : undefined}> + 0.6 ? colors.greenSoft : '#fff'} + stroke={colors.green} + strokeWidth="4" + /> + + {canonical} + + + {aliasesPrefix} {aliasTags.join(' · ')} + + + + + {footer} + + + +
+ ); +}; diff --git a/wikontic-demo-animation/src/components/DocumentView.tsx b/wikontic-demo-animation/src/components/DocumentView.tsx new file mode 100644 index 0000000..f04ae60 --- /dev/null +++ b/wikontic-demo-animation/src/components/DocumentView.tsx @@ -0,0 +1,79 @@ +import React from 'react'; +import {FileText} from 'lucide-react'; +import type {DocumentLine} from '../data/animation1'; + +type DocumentViewProps = { + lines: DocumentLine[]; + activeFactIds?: string[]; + dimNonFacts?: boolean; + progress?: number; + closeup?: number; + toolbarLabel?: string; + heading?: string; +}; + +const toneByFact: Record = { + 'requirements-date': 'hlAmber', + buildings: 'hlBlue', + parking: 'hlGreen', + 'monitoring-networks': 'hlViolet', + 'risk-control': 'hlBlue', +}; + +export const DocumentView: React.FC = ({ + lines, + activeFactIds = [], + dimNonFacts = false, + progress = 1, + closeup = 0, + toolbarLabel = 'Документ', + heading = 'Проектные требования к объекту', +}) => { + const active = new Set(activeFactIds); + return ( +
+
+ + {toolbarLabel} +
+
{heading}
+
+ {lines.map((line, lineIndex) => ( +

+ {line.map((part, partIndex) => { + if (!part.factId) { + return ( + + {part.text} + + ); + } + const isActive = active.has(part.factId); + return ( + + {part.text} + + ); + })} +

+ ))} +
+
+ ); +}; diff --git a/wikontic-demo-animation/src/components/GraphView.tsx b/wikontic-demo-animation/src/components/GraphView.tsx new file mode 100644 index 0000000..e669a3c --- /dev/null +++ b/wikontic-demo-animation/src/components/GraphView.tsx @@ -0,0 +1,283 @@ +import React from 'react'; +import {colors} from '../theme'; +import type {GraphEdge, GraphNode} from '../data/graphBefore'; +import {refinedNodes} from '../data/graphAfter'; + +type GraphViewProps = { + nodes: GraphNode[]; + edges: GraphEdge[]; + reveal?: number; + showTypes?: boolean; + highlightedNodeIds?: string[]; + highlightedEdgeIds?: string[]; + scannerProgress?: number; + mergeProgress?: number; + width?: number; + height?: number; + muted?: boolean; + nodeRadius?: number; + nodeAspect?: number; + typeOutside?: boolean; + labelFontSize?: number; + typeFontSize?: number; + edgeFontSize?: number; + softReveal?: boolean; + transparentBg?: boolean; + onNodeSelect?: (node: GraphNode) => void; +}; + +const smoothstep = (t: number) => { + const x = Math.max(0, Math.min(1, t)); + return x * x * (3 - 2 * x); +}; + +const kindColor: Record = { + project: {fill: colors.blueSoft, stroke: colors.blue}, + asset: {fill: colors.greenSoft, stroke: colors.green}, + system: {fill: colors.violetSoft, stroke: colors.violet}, + requirement: {fill: colors.amberSoft, stroke: colors.amber}, + time: {fill: '#f4f6f9', stroke: colors.steel}, + document: {fill: '#eef4ff', stroke: colors.blueDark}, +}; + +const edgeColor = (edge: GraphEdge, highlighted: boolean) => { + if (highlighted || edge.status === 'path') { + return colors.blue; + } + if (edge.status === 'invalid') { + return colors.red; + } + if (edge.status === 'warning') { + return colors.amber; + } + return colors.steel; +}; + +const clamp = (value: number) => Math.max(0, Math.min(1, value)); + +const nodePosition = (node: GraphNode, width: number, height: number, mergeProgress: number) => { + if (node.aliasOf && mergeProgress > 0) { + const target = refinedNodes.find((candidate) => candidate.id === node.aliasOf); + if (target) { + const p = clamp(mergeProgress); + return { + x: (node.x * (1 - p) + target.x * p) * width, + y: (node.y * (1 - p) + target.y * p) * height, + }; + } + } + return {x: node.x * width, y: node.y * height}; +}; + +const labelLines = (label: string) => { + const words = label.split(' '); + if (label.length < 14 || words.length === 1) { + return [label]; + } + const midpoint = Math.ceil(words.length / 2); + return [words.slice(0, midpoint).join(' '), words.slice(midpoint).join(' ')]; +}; + +export const GraphView: React.FC = ({ + nodes, + edges, + reveal = 1, + showTypes = false, + highlightedNodeIds = [], + highlightedEdgeIds = [], + scannerProgress, + mergeProgress = 0, + width = 980, + height = 620, + muted = false, + nodeRadius, + nodeAspect = 1, + typeOutside = false, + labelFontSize, + typeFontSize, + edgeFontSize, + softReveal = false, + transparentBg = false, + onNodeSelect, +}) => { + const edgeFs = edgeFontSize ?? 17; + const visibleNodeCount = Math.ceil(nodes.length * clamp(reveal)); + const visibleNodes = nodes.slice(0, visibleNodeCount); + const visibleNodeIds = new Set(visibleNodes.map((node) => node.id)); + + // Soft, staggered reveal: each node gently fades + scales in over an + // overlapping window so the graph "grows" smoothly instead of popping. + const nodeIndex = new Map(nodes.map((node, i) => [node.id, i])); + // Smaller window => more spacing between consecutive node appearances + // (less simultaneous, less jittery). Per-node fade speed is kept constant by + // lengthening the overall reveal window in the caller. + const appearWindow = 0.2; + const appear = (id: string): number => { + if (!softReveal) { + return 1; + } + const i = nodeIndex.get(id) ?? 0; + const start = nodes.length > 1 ? (i / (nodes.length - 1)) * (1 - appearWindow) : 0; + return smoothstep((clamp(reveal) - start) / appearWindow); + }; + + const renderNodes = softReveal ? nodes : visibleNodes; + + return ( + + + + + + + + + + + + + + + + + + {scannerProgress !== undefined ? ( + + ) : null} + {edges.map((edge) => { + if (!softReveal && (!visibleNodeIds.has(edge.source) || !visibleNodeIds.has(edge.target))) { + return null; + } + const source = nodes.find((node) => node.id === edge.source); + const target = nodes.find((node) => node.id === edge.target); + if (!source || !target) { + return null; + } + const edgeAppear = softReveal ? Math.min(appear(edge.source), appear(edge.target)) : 1; + if (edgeAppear <= 0.001) { + return null; + } + const start = nodePosition(source, width, height, mergeProgress); + const end = nodePosition(target, width, height, mergeProgress); + const highlighted = highlightedEdgeIds.includes(edge.id); + const stroke = edgeColor(edge, highlighted); + const midX = (start.x + end.x) / 2; + const midY = (start.y + end.y) / 2; + return ( + + + + {edge.label} + + + ); + })} + {renderNodes.map((node) => { + const pos = nodePosition(node, width, height, mergeProgress); + const highlighted = highlightedNodeIds.includes(node.id) || Boolean(node.aliasOf && mergeProgress > 0.8); + const color = kindColor[node.kind]; + const radius = nodeRadius ?? (node.label.length > 14 ? 68 : 54); + const labelFs = labelFontSize ?? 22; + const typeFs = typeFontSize ?? 15; + const labelLineHeight = labelFs * 1.05; + const aliasFade = node.aliasOf && mergeProgress > 0.75 ? 1 - mergeProgress : 1; + const nodeAppear = appear(node.id); + if (softReveal && nodeAppear <= 0.001) { + return null; + } + const scale = softReveal ? 0.85 + 0.15 * nodeAppear : 1; + const lines = labelLines(node.label); + return ( + onNodeSelect(node) : undefined} + style={{cursor: onNodeSelect ? 'pointer' : 'default'}} + > + + 1 + ? labelLineHeight / 2 + : -2) + } + textAnchor="middle" + className="nodeLabel" + style={{fontSize: labelFs}} + > + {lines.map((line, index) => ( + + {line} + + ))} + + {showTypes && node.type ? ( + 1 ? labelLineHeight + 16 : 24) + } + textAnchor="middle" + className="nodeType" + style={{fontSize: typeFs}} + > + {node.type} + + ) : null} + + ); + })} + + ); +}; diff --git a/wikontic-demo-animation/src/components/HighlightedFact.tsx b/wikontic-demo-animation/src/components/HighlightedFact.tsx new file mode 100644 index 0000000..2829f25 --- /dev/null +++ b/wikontic-demo-animation/src/components/HighlightedFact.tsx @@ -0,0 +1,25 @@ +import React from 'react'; + +type HighlightedFactProps = { + children: React.ReactNode; + tone?: 'blue' | 'green' | 'amber' | 'violet'; + progress?: number; + compact?: boolean; +}; + +export const HighlightedFact: React.FC = ({ + children, + tone = 'blue', + progress = 1, + compact = false, +}) => ( +
+ {children} +
+); diff --git a/wikontic-demo-animation/src/components/MetricBadge.tsx b/wikontic-demo-animation/src/components/MetricBadge.tsx new file mode 100644 index 0000000..0688469 --- /dev/null +++ b/wikontic-demo-animation/src/components/MetricBadge.tsx @@ -0,0 +1,12 @@ +import React from 'react'; + +export const MetricBadge: React.FC<{value: string; label: string; tone?: 'blue' | 'green' | 'amber'}> = ({ + value, + label, + tone = 'blue', +}) => ( +
+ {value} + {label} +
+); diff --git a/wikontic-demo-animation/src/components/OntologyPass.tsx b/wikontic-demo-animation/src/components/OntologyPass.tsx new file mode 100644 index 0000000..3ba5e74 --- /dev/null +++ b/wikontic-demo-animation/src/components/OntologyPass.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import {BadgeCheck, ScanSearch} from 'lucide-react'; +import {colors} from '../theme'; + +type OntologyCheck = { + source: string; + result: string; + tone: 'blue' | 'green' | 'amber' | 'violet'; +}; + +type OntologyPassProps = { + checks: readonly OntologyCheck[]; + progress: number; + title?: string; +}; + +const toneColor: Record = { + blue: colors.blue, + green: colors.green, + amber: colors.amber, + violet: colors.violet, +}; + +export const OntologyPass: React.FC = ({checks, progress, title = 'Онтологическая проверка'}) => { + const scannerX = Math.max(0, Math.min(1, progress)) * 100; + return ( +
+
+ + {title} +
+
+ {checks.map((check, index) => { + const visible = progress > index * 0.17; + return ( +
+ {check.source} + {check.result} + {visible ? : null} +
+ ); + })} +
+
+
+ ); +}; diff --git a/wikontic-demo-animation/src/components/PathHighlight.tsx b/wikontic-demo-animation/src/components/PathHighlight.tsx new file mode 100644 index 0000000..32d58de --- /dev/null +++ b/wikontic-demo-animation/src/components/PathHighlight.tsx @@ -0,0 +1,41 @@ +import React from 'react'; + +type PathHighlightProps = { + path: string; + progress?: number; + compact?: boolean; + fontSize?: number; +}; + +export const PathHighlight: React.FC = ({ + path, + progress = 1, + compact = false, + fontSize, +}) => { + const parts = path.split(' -> '); + const visibleCount = Math.max(1, Math.ceil(parts.length * Math.max(0, Math.min(1, progress)))); + return ( +
+ {parts.map((part, index) => { + const visible = index < visibleCount; + const isRelation = index % 2 === 1; + return ( + + + {part} + + {index < parts.length - 1 ? ( + + → + + ) : null} + + ); + })} +
+ ); +}; diff --git a/wikontic-demo-animation/src/components/SceneLayout.tsx b/wikontic-demo-animation/src/components/SceneLayout.tsx new file mode 100644 index 0000000..33579f9 --- /dev/null +++ b/wikontic-demo-animation/src/components/SceneLayout.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import {colors} from '../theme'; + +type SceneLayoutProps = { + eyebrow?: string; + title: string; + subtitle?: string; + children: React.ReactNode; + frameLabel?: string; +}; + +export const SceneLayout: React.FC = ({ + eyebrow, + title, + subtitle, + children, + frameLabel, +}) => { + return ( +
+
+
+ {eyebrow ?
{eyebrow}
: null} +

{title}

+ {subtitle ?

{subtitle}

: null} +
+ {frameLabel ?
{frameLabel}
: null} +
+
{children}
+
+
+
+ ); +}; + +export const Panel: React.FC<{ + children: React.ReactNode; + className?: string; + style?: React.CSSProperties; +}> = ({children, className, style}) => ( +
+ {children} +
+); diff --git a/wikontic-demo-animation/src/components/TripletCard.tsx b/wikontic-demo-animation/src/components/TripletCard.tsx new file mode 100644 index 0000000..3d511a4 --- /dev/null +++ b/wikontic-demo-animation/src/components/TripletCard.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import {Database, Link2} from 'lucide-react'; + +type TripletCardProps = { + subject: string; + relation: string; + object: string; + qualifier?: string; + progress?: number; + compact?: boolean; +}; + +export const TripletCard: React.FC = ({ + subject, + relation, + object, + qualifier, + progress = 1, + compact = false, +}) => { + return ( +
+
+ {subject} + + + {relation} + + {object} +
+ {qualifier ? ( +
+ + {qualifier} +
+ ) : null} +
+ ); +}; diff --git a/wikontic-demo-animation/src/data/animation1.ts b/wikontic-demo-animation/src/data/animation1.ts new file mode 100644 index 0000000..9c8679e --- /dev/null +++ b/wikontic-demo-animation/src/data/animation1.ts @@ -0,0 +1,264 @@ +import type {GraphEdge, GraphNode} from './graphBefore'; +import type {Locale} from '../i18n/types'; + +export type DocumentPart = { + text: string; + factId?: string; +}; + +export type DocumentLine = DocumentPart[]; + +export const methodDocument: DocumentLine[] = [ + [ + {text: 'В '}, + {text: '2024', factId: 'requirements-date'}, + {text: ' году проектная команда '}, + {text: 'утвердила требования к жилому комплексу', factId: 'requirements-date'}, + {text: '.'}, + ], + [ + {text: 'Объект включает '}, + {text: 'три корпуса', factId: 'buildings'}, + {text: ', '}, + {text: 'подземный паркинг', factId: 'parking'}, + {text: ' и '}, + {text: 'систему мониторинга инженерных сетей', factId: 'monitoring-networks'}, + {text: '.'}, + ], + [ + {text: 'Система мониторинга используется для '}, + {text: 'контроля эксплуатационных рисков', factId: 'risk-control'}, + {text: '.'}, + ], +]; + +export const highlightedFacts = [ + {id: 'requirements-date', text: 'требования утверждены в 2024 году', tone: 'amber'}, + {id: 'buildings', text: 'объект включает три корпуса', tone: 'blue'}, + {id: 'parking', text: 'объект включает подземный паркинг', tone: 'green'}, + {id: 'monitoring-networks', text: 'система мониторинга инженерных сетей', tone: 'violet'}, + {id: 'risk-control', text: 'мониторинг контролирует эксплуатационные риски', tone: 'blue'}, +] as const; + +export const methodTriplets = [ + {subject: 'жилой комплекс', relation: 'включает', object: 'три корпуса'}, + {subject: 'жилой комплекс', relation: 'включает', object: 'подземный паркинг'}, + {subject: 'жилой комплекс', relation: 'включает', object: 'система мониторинга'}, + {subject: 'система мониторинга', relation: 'контролирует', object: 'инженерные сети'}, + {subject: 'утверждение требований', relation: 'дата', object: '2024', qualifier: 'контекст: проект'}, +]; + +export const ontologyChecks = [ + {source: 'ЖК', result: 'строительный объект', tone: 'blue'}, + {source: 'инженерные сети', result: 'инженерная система', tone: 'green'}, + {source: 'содержит / имеет в составе', result: 'включает', tone: 'amber'}, + {source: 'контроль рисков', result: 'допустимая связь', tone: 'green'}, +] as const; + +export const dedupGroups = [ + {aliases: ['ЖК', 'жилой комплекс', 'объект'], canonical: 'жилой комплекс'}, + {aliases: ['сети', 'инженерные сети'], canonical: 'инженерные сети'}, +]; + +export const compactGraphNodes: GraphNode[] = [ + {id: 'project', label: 'проект', type: 'документ', x: 0.12, y: 0.48, kind: 'document'}, + {id: 'complex', label: 'жилой комплекс', type: 'строительный объект', x: 0.34, y: 0.48, kind: 'project'}, + {id: 'buildings', label: 'три корпуса', type: 'здание', x: 0.58, y: 0.24, kind: 'asset'}, + {id: 'parking', label: 'подземный паркинг', type: 'строительный объект', x: 0.62, y: 0.48, kind: 'asset'}, + {id: 'monitoring', label: 'система мониторинга', type: 'инженерная система', x: 0.58, y: 0.72, kind: 'system'}, + {id: 'networks', label: 'инженерные сети', type: 'инженерная система', x: 0.84, y: 0.72, kind: 'system'}, + {id: 'requirements', label: 'требования', type: 'требование', x: 0.34, y: 0.2, kind: 'requirement'}, + {id: 'year', label: '2024', type: 'дата', x: 0.12, y: 0.2, kind: 'time'}, + {id: 'risks', label: 'эксплуатационные риски', type: 'риск', x: 0.86, y: 0.45, kind: 'requirement'}, +]; + +export const compactGraphEdges: GraphEdge[] = [ + {id: 'project-complex', source: 'project', target: 'complex', label: 'содержит', status: 'valid'}, + {id: 'complex-buildings', source: 'complex', target: 'buildings', label: 'включает', status: 'valid'}, + {id: 'complex-parking', source: 'complex', target: 'parking', label: 'включает', status: 'valid'}, + {id: 'complex-monitoring', source: 'complex', target: 'monitoring', label: 'включает', status: 'valid'}, + {id: 'monitoring-networks', source: 'monitoring', target: 'networks', label: 'контролирует', status: 'valid'}, + {id: 'networks-risks', source: 'networks', target: 'risks', label: 'связаны с', status: 'valid'}, + {id: 'requirements-year', source: 'requirements', target: 'year', label: 'дата', status: 'valid'}, + {id: 'requirements-complex', source: 'requirements', target: 'complex', label: 'для объекта', status: 'valid'}, +]; + +const methodDocumentEn: DocumentLine[] = [ + [ + {text: 'In '}, + {text: '2024', factId: 'requirements-date'}, + {text: ', the project team '}, + {text: 'approved requirements for a residential complex', factId: 'requirements-date'}, + {text: '.'}, + ], + [ + {text: 'The asset includes '}, + {text: 'three buildings', factId: 'buildings'}, + {text: ', '}, + {text: 'underground parking', factId: 'parking'}, + {text: ', and '}, + {text: 'a utility-network monitoring system', factId: 'monitoring-networks'}, + {text: '.'}, + ], + [ + {text: 'The monitoring system is used for '}, + {text: 'controlling operational risks', factId: 'risk-control'}, + {text: '.'}, + ], +]; + +const highlightedFactsEn = [ + {id: 'requirements-date', text: 'requirements approved in 2024', tone: 'amber'}, + {id: 'buildings', text: 'asset includes three buildings', tone: 'blue'}, + {id: 'parking', text: 'asset includes underground parking', tone: 'green'}, + {id: 'monitoring-networks', text: 'utility-network monitoring system', tone: 'violet'}, + {id: 'risk-control', text: 'monitoring controls operational risks', tone: 'blue'}, +] as const; + +const methodTripletsEn = [ + {subject: 'residential complex', relation: 'includes', object: 'three buildings'}, + {subject: 'residential complex', relation: 'includes', object: 'underground parking'}, + {subject: 'residential complex', relation: 'includes', object: 'monitoring system'}, + {subject: 'monitoring system', relation: 'controls', object: 'utility networks'}, + {subject: 'requirements approval', relation: 'date', object: '2024', qualifier: 'context: project'}, +]; + +const ontologyChecksEn = [ + {source: 'RC', result: 'construction asset', tone: 'blue'}, + {source: 'utility networks', result: 'engineering system', tone: 'green'}, + {source: 'contains / has part', result: 'includes', tone: 'amber'}, + {source: 'risk control', result: 'valid relation', tone: 'green'}, +] as const; + +const dedupGroupsEn = [ + {aliases: ['RC', 'residential complex', 'asset'], canonical: 'residential complex'}, + {aliases: ['networks', 'utility networks'], canonical: 'utility networks'}, +]; + +const compactGraphNodesEn: GraphNode[] = [ + {id: 'project', label: 'project', type: 'document', x: 0.12, y: 0.48, kind: 'document'}, + {id: 'complex', label: 'residential complex', type: 'construction asset', x: 0.34, y: 0.48, kind: 'project'}, + {id: 'buildings', label: 'three buildings', type: 'building', x: 0.58, y: 0.24, kind: 'asset'}, + {id: 'parking', label: 'underground parking', type: 'construction asset', x: 0.62, y: 0.48, kind: 'asset'}, + {id: 'monitoring', label: 'monitoring system', type: 'engineering system', x: 0.58, y: 0.72, kind: 'system'}, + {id: 'networks', label: 'utility networks', type: 'engineering system', x: 0.84, y: 0.72, kind: 'system'}, + {id: 'requirements', label: 'requirements', type: 'requirement', x: 0.34, y: 0.2, kind: 'requirement'}, + {id: 'year', label: '2024', type: 'date', x: 0.12, y: 0.2, kind: 'time'}, + {id: 'risks', label: 'operational risks', type: 'risk', x: 0.86, y: 0.45, kind: 'requirement'}, +]; + +const compactGraphEdgesEn: GraphEdge[] = [ + {id: 'project-complex', source: 'project', target: 'complex', label: 'contains', status: 'valid'}, + {id: 'complex-buildings', source: 'complex', target: 'buildings', label: 'includes', status: 'valid'}, + {id: 'complex-parking', source: 'complex', target: 'parking', label: 'includes', status: 'valid'}, + {id: 'complex-monitoring', source: 'complex', target: 'monitoring', label: 'includes', status: 'valid'}, + {id: 'monitoring-networks', source: 'monitoring', target: 'networks', label: 'controls', status: 'valid'}, + {id: 'networks-risks', source: 'networks', target: 'risks', label: 'linked to', status: 'valid'}, + {id: 'requirements-year', source: 'requirements', target: 'year', label: 'date', status: 'valid'}, + {id: 'requirements-complex', source: 'requirements', target: 'complex', label: 'for asset', status: 'valid'}, +]; + +export type Animation1Content = { + methodDocument: DocumentLine[]; + highlightedFacts: readonly {id: string; text: string; tone: 'amber' | 'blue' | 'green' | 'violet'}[]; + methodTriplets: {subject: string; relation: string; object: string; qualifier?: string}[]; + ontologyChecks: readonly {source: string; result: string; tone: 'blue' | 'green' | 'amber' | 'violet'}[]; + dedupGroups: {aliases: string[]; canonical: string}[]; + compactGraphNodes: GraphNode[]; + compactGraphEdges: GraphEdge[]; + titles: { + document: string; + triplets: string; + ontology: string; + dedup: string; + final: string; + }; + labels: { + eyebrow: string; + sourceText: string; + graph: string; + before: string; + after: string; + tokens: string; + entitiesAnd: string; + triplets: string; + documentToolbar: string; + documentHeading: string; + ontologyTitle: string; + dedupTitle: string; + dedupAliasesPrefix: string; + dedupFooter: string; + }; + graphBenefits: string[]; +}; + +export const animation1Content: Record = { + ru: { + methodDocument, + highlightedFacts, + methodTriplets, + ontologyChecks, + dedupGroups, + compactGraphNodes, + compactGraphEdges, + titles: { + document: 'Документы содержат факты', + triplets: '1. Из текста извлекаются триплеты-кандидаты', + ontology: '2. Верификация и согласование графа с онтологией', + dedup: '3. Очистка и дедупликация графа', + final: 'Информация сохранена в компактном и проверяемом графе знаний', + }, + labels: { + eyebrow: 'Метод', + sourceText: 'Исходный текст', + graph: 'Граф знаний', + before: 'Было', + after: 'Стало', + tokens: 'токенов', + entitiesAnd: 'сущностей и', + triplets: 'триплетов', + documentToolbar: 'Документ', + documentHeading: 'Проектные требования к объекту', + ontologyTitle: 'Онтологическая проверка', + dedupTitle: 'Очистка и дедупликация', + dedupAliasesPrefix: 'aliases:', + dedupFooter: 'Синонимы объединены в одну сущность', + }, + graphBenefits: ['Интерпретируемость', 'Верифицируемость', 'Редактируемость', 'Компактность'], + }, + en: { + methodDocument: methodDocumentEn, + highlightedFacts: highlightedFactsEn, + methodTriplets: methodTripletsEn, + ontologyChecks: ontologyChecksEn, + dedupGroups: dedupGroupsEn, + compactGraphNodes: compactGraphNodesEn, + compactGraphEdges: compactGraphEdgesEn, + titles: { + document: 'Documents contain facts', + triplets: '1. Text becomes candidate triplets', + ontology: '2. Ontology verification and graph alignment', + dedup: '3. Cleaning and deduplication', + final: 'Information is preserved in a compact, verifiable knowledge graph', + }, + labels: { + eyebrow: 'Method', + sourceText: 'Source text', + graph: 'Knowledge graph', + before: 'Before', + after: 'After', + tokens: 'tokens', + entitiesAnd: 'entities and', + triplets: 'triplets', + documentToolbar: 'Document', + documentHeading: 'Project requirements for the asset', + ontologyTitle: 'Ontology check', + dedupTitle: 'Cleaning and deduplication', + dedupAliasesPrefix: 'aliases:', + dedupFooter: 'Aliases are merged into one entity', + }, + graphBenefits: ['Interpretability', 'Verification', 'Editable', 'Compact data representation'], + }, +}; + +export const getAnimation1Content = (locale: Locale = 'ru') => animation1Content[locale]; diff --git a/wikontic-demo-animation/src/data/animation2.ts b/wikontic-demo-animation/src/data/animation2.ts new file mode 100644 index 0000000..e291b81 --- /dev/null +++ b/wikontic-demo-animation/src/data/animation2.ts @@ -0,0 +1,184 @@ +import {compactGraphEdges, compactGraphNodes, getAnimation1Content} from './animation1'; +import type {Locale} from '../i18n/types'; + +export const ragQuestion = 'Что важно проверить перед вводом жилого комплекса в эксплуатацию?'; + +export const ragChunks = [ + { + title: 'Фрагмент 1', + text: 'Объект включает систему мониторинга.', + }, + { + title: 'Фрагмент 2', + text: 'Система мониторинга контролирует инженерные сети.', + }, + { + title: 'Фрагмент 3', + text: 'Инженерные сети связаны с эксплуатационными рисками.', + }, + { + title: 'Фрагмент 4', + text: 'Требования к объекту утверждены проектной командой в 2024 году.', + }, +]; + +export const ragVsGraphNodes = compactGraphNodes; +export const ragVsGraphEdges = compactGraphEdges; + +export const answerPathNodeIds = ['complex', 'monitoring', 'networks', 'risks']; +export const answerPathEdgeIds = ['complex-monitoring', 'monitoring-networks', 'networks-risks']; + +export const internalPathText = + 'жилой комплекс -> включает -> система мониторинга -> контролирует -> инженерные сети -> связаны с -> эксплуатационные риски'; + +export const ragVsWikonticAnswer = + 'Нужно проверить систему мониторинга инженерных сетей, потому что она связана с эксплуатационным контролем объекта.'; + +export type Animation2Tone = 'blue' | 'green' | 'violet'; +export type Animation2Segment = {t: string; tone?: Animation2Tone}; +export type Animation2AnswerSegment = {text: string; tone?: 'blue' | 'green'}; + +export type Animation2Content = { + ragQuestion: string; + ragChunks: {title: string; text: string}[]; + ragVsGraphNodes: typeof compactGraphNodes; + ragVsGraphEdges: typeof compactGraphEdges; + internalPathText: string; + questionSegments: Animation2Segment[]; + answerSegments: Animation2AnswerSegment[]; + corpusGrid: { + text: string; + col: number; + row: number; + slot?: number; + lost?: boolean; + segments?: Animation2Segment[]; + tx?: number; + ty?: number; + }[]; + labels: { + question: string; + notFound: string; + noDirectLink: string; + relevantNotFound: string; + ragNote: string; + uniteDocuments: string; + pathToAnswer: string; + answer: string; + }; +}; + +const contentRu: Animation2Content = { + ragQuestion, + ragChunks, + ragVsGraphNodes, + ragVsGraphEdges, + internalPathText, + questionSegments: [ + {t: 'Что важно '}, + {t: 'проверить', tone: 'violet'}, + {t: ' перед вводом '}, + {t: 'жилого комплекса', tone: 'blue'}, + {t: ' в '}, + {t: 'эксплуатацию', tone: 'green'}, + {t: '?'}, + ], + answerSegments: [ + {text: 'Нужно проверить '}, + {text: 'систему мониторинга', tone: 'blue'}, + {text: ' инженерных сетей, потому что она связана с '}, + {text: 'эксплуатационным контролем', tone: 'green'}, + {text: ' объекта.'}, + ], + corpusGrid: [ + {text: 'Требования к объекту утверждены проектной командой в 2024 году.', col: 0, row: 0, slot: 2, + segments: [{t: 'Требования', tone: 'violet'}, {t: ' к '}, {t: 'объекту', tone: 'blue'}, {t: ' утверждены проектной командой в 2024 году.'}]}, + {text: 'Объект включает систему мониторинга.', col: 1, row: 0, slot: 0, + segments: [{t: 'Объект', tone: 'blue'}, {t: ' включает систему мониторинга.'}]}, + {text: 'Система мониторинга контролирует инженерные сети.', col: 2, row: 1, lost: true, tx: 1, ty: 1}, + {text: 'Инженерные сети связаны с эксплуатационными рисками.', col: 0, row: 2, slot: 1, + segments: [{t: 'Инженерные сети связаны с '}, {t: 'эксплуатационными', tone: 'green'}, {t: ' рисками.'}]}, + {text: 'Подземный паркинг рассчитан на 120 машино-мест.', col: 2, row: 0, tx: 1, ty: -1}, + {text: 'Фасадные работы завершены в третьем квартале.', col: 3, row: 0, tx: 1, ty: -1}, + {text: 'Договор подряда подписан с генеральным подрядчиком.', col: 1, row: 1, tx: -1, ty: 0}, + {text: 'Высота типового этажа составляет три метра.', col: 3, row: 1, tx: 1, ty: 0}, + {text: 'Озеленение территории запланировано на весну.', col: 1, row: 2, tx: 1, ty: 1}, + {text: 'Гарантийный срок на кровлю — десять лет.', col: 3, row: 2, tx: 1, ty: 1}, + {text: 'Лифтовое оборудование поставлено зарубежным производителем.', col: 0, row: 1, tx: -1, ty: 0}, + {text: 'Система пожарной сигнализации принята в эксплуатацию.', col: 2, row: 2, tx: 1, ty: 1}, + ], + labels: { + question: 'Вопрос', + notFound: 'Не найден!', + noDirectLink: 'Нет прямой связи с вопросом.', + relevantNotFound: 'Релевантный фрагмент не найден', + ragNote: 'RAG смотрит только на близость к вопросу, а не на взаимосвязь между фактами.', + uniteDocuments: 'Объединяем документы в граф', + pathToAnswer: 'В графе находим путь к ответу', + answer: 'Ответ', + }, +}; + +const enGraph = getAnimation1Content('en'); + +const contentEn: Animation2Content = { + ragQuestion: 'What should be checked before commissioning the residential complex?', + ragChunks: [ + {title: 'Fragment 1', text: 'The asset includes a monitoring system.'}, + {title: 'Fragment 2', text: 'The monitoring system controls utility networks.'}, + {title: 'Fragment 3', text: 'Utility networks are linked to operational risks.'}, + {title: 'Fragment 4', text: 'Requirements for the asset were approved by the project team in 2024.'}, + ], + ragVsGraphNodes: enGraph.compactGraphNodes, + ragVsGraphEdges: enGraph.compactGraphEdges, + internalPathText: + 'residential complex -> includes -> monitoring system -> controls -> utility networks -> linked to -> operational risks', + questionSegments: [ + {t: 'What should be '}, + {t: 'checked', tone: 'violet'}, + {t: ' before commissioning the '}, + {t: 'residential complex', tone: 'blue'}, + {t: '?'}, + ], + answerSegments: [ + {text: 'Check the '}, + {text: 'monitoring system', tone: 'blue'}, + {text: ' for utility networks, because it is tied to '}, + {text: 'operational control', tone: 'green'}, + {text: ' of the asset.'}, + ], + corpusGrid: [ + {text: 'Requirements for the asset were approved by the project team in 2024.', col: 0, row: 0, slot: 2, + segments: [{t: 'Requirements', tone: 'violet'}, {t: ' for the '}, {t: 'asset', tone: 'blue'}, {t: ' were approved by the project team in 2024.'}]}, + {text: 'The asset includes a monitoring system.', col: 1, row: 0, slot: 0, + segments: [{t: 'The asset', tone: 'blue'}, {t: ' includes a monitoring system.'}]}, + {text: 'The monitoring system controls utility networks.', col: 2, row: 1, lost: true, tx: 1, ty: 1}, + {text: 'Utility networks are linked to operational risks.', col: 0, row: 2, slot: 1, + segments: [{t: 'Utility networks are linked to '}, {t: 'operational', tone: 'green'}, {t: ' risks.'}]}, + {text: 'Underground parking is designed for 120 spaces.', col: 2, row: 0, tx: 1, ty: -1}, + {text: 'Facade work was completed in the third quarter.', col: 3, row: 0, tx: 1, ty: -1}, + {text: 'The construction contract was signed with the general contractor.', col: 1, row: 1, tx: -1, ty: 0}, + {text: 'The standard floor height is three meters.', col: 3, row: 1, tx: 1, ty: 0}, + {text: 'Landscaping is scheduled for spring.', col: 1, row: 2, tx: 1, ty: 1}, + {text: 'The roof warranty period is ten years.', col: 3, row: 2, tx: 1, ty: 1}, + {text: 'Elevator equipment was supplied by an overseas manufacturer.', col: 0, row: 1, tx: -1, ty: 0}, + {text: 'The fire alarm system has been accepted for operation.', col: 2, row: 2, tx: 1, ty: 1}, + ], + labels: { + question: 'Question', + notFound: 'Not found', + noDirectLink: 'No direct match to the question.', + relevantNotFound: 'Relevant fragment not retrieved', + ragNote: 'RAG uses similarity to the question, not the explicit relationships between facts.', + uniteDocuments: 'Unifying documents into a graph', + pathToAnswer: 'The graph finds a path to the answer', + answer: 'Answer', + }, +}; + +export const animation2Content: Record = { + ru: contentRu, + en: contentEn, +}; + +export const getAnimation2Content = (locale: Locale = 'ru') => animation2Content[locale]; diff --git a/wikontic-demo-animation/src/data/animation3.ts b/wikontic-demo-animation/src/data/animation3.ts new file mode 100644 index 0000000..04e8525 --- /dev/null +++ b/wikontic-demo-animation/src/data/animation3.ts @@ -0,0 +1,174 @@ +import {compactGraphEdges, compactGraphNodes, getAnimation1Content} from './animation1'; +import type {Locale} from '../i18n/types'; + +export const syntheticGraphNodes = compactGraphNodes; +export const syntheticGraphEdges = compactGraphEdges; + +export const syntheticAnswerNodeId = 'networks'; + +export const syntheticPaths = [ + { + id: 'one-hop', + difficulty: '1-hop', + nodeIds: ['monitoring', 'networks'], + edgeIds: ['monitoring-networks'], + path: 'система мониторинга -> контролирует -> инженерные сети', + }, + { + id: 'two-hop', + difficulty: '2-hop', + nodeIds: ['complex', 'monitoring', 'networks'], + edgeIds: ['complex-monitoring', 'monitoring-networks'], + path: 'жилой комплекс -> включает -> система мониторинга -> контролирует -> инженерные сети', + }, + { + id: 'three-hop', + difficulty: '3-hop', + nodeIds: ['project', 'complex', 'monitoring', 'networks'], + edgeIds: ['project-complex', 'complex-monitoring', 'monitoring-networks'], + path: + 'проект -> содержит -> жилой комплекс -> включает -> система мониторинга -> контролирует -> инженерные сети', + }, +]; + +export const naturalQACards = [ + { + question: 'Что контролирует система мониторинга?', + answer: 'Инженерные сети.', + path: syntheticPaths[0].path, + difficulty: '1-hop', + }, + { + question: 'Что нужно контролировать при эксплуатации жилого комплекса?', + answer: 'Инженерные сети.', + path: syntheticPaths[1].path, + difficulty: '2-hop', + }, + { + question: 'Какая часть инфраструктуры проекта требует мониторингового контроля?', + answer: 'Инженерные сети.', + path: syntheticPaths[2].path, + difficulty: '3-hop', + }, +]; + +export const datasetLabels = ['QA pairs', 'reasoning chains', 'difficulty control', 'negative examples']; + +export type Animation3Content = { + syntheticGraphNodes: typeof compactGraphNodes; + syntheticGraphEdges: typeof compactGraphEdges; + syntheticAnswerNodeId: string; + syntheticPaths: typeof syntheticPaths; + naturalQACards: typeof naturalQACards; + datasetLabels: string[]; + labels: { + answerCallout: string; + graphEyebrow: string; + graphTitle: string; + graphSubtitle: string; + pathsEyebrow: string; + pathsTitle: string; + pathsSubtitle: string; + dataEyebrow: string; + dataTitle: string; + dataSubtitle: string; + syntheticDataset: string; + smallModel: string; + }; +}; + +const enGraph = getAnimation1Content('en'); + +const syntheticPathsEn = [ + { + id: 'one-hop', + difficulty: '1-hop', + nodeIds: ['monitoring', 'networks'], + edgeIds: ['monitoring-networks'], + path: 'monitoring system -> controls -> utility networks', + }, + { + id: 'two-hop', + difficulty: '2-hop', + nodeIds: ['complex', 'monitoring', 'networks'], + edgeIds: ['complex-monitoring', 'monitoring-networks'], + path: 'residential complex -> includes -> monitoring system -> controls -> utility networks', + }, + { + id: 'three-hop', + difficulty: '3-hop', + nodeIds: ['project', 'complex', 'monitoring', 'networks'], + edgeIds: ['project-complex', 'complex-monitoring', 'monitoring-networks'], + path: 'project -> contains -> residential complex -> includes -> monitoring system -> controls -> utility networks', + }, +]; + +const naturalQACardsEn = [ + { + question: 'What does the monitoring system control?', + answer: 'Utility networks.', + path: syntheticPathsEn[0].path, + difficulty: '1-hop', + }, + { + question: 'What should be monitored during operation of the residential complex?', + answer: 'Utility networks.', + path: syntheticPathsEn[1].path, + difficulty: '2-hop', + }, + { + question: 'Which part of the project infrastructure requires monitoring control?', + answer: 'Utility networks.', + path: syntheticPathsEn[2].path, + difficulty: '3-hop', + }, +]; + +export const animation3Content: Record = { + ru: { + syntheticGraphNodes, + syntheticGraphEdges, + syntheticAnswerNodeId, + syntheticPaths, + naturalQACards, + datasetLabels, + labels: { + answerCallout: 'ответ: инженерные сети', + graphEyebrow: 'Синтетические данные', + graphTitle: 'Граф становится источником данных для обучения', + graphSubtitle: 'Выбираем вершину-ответ в графе знаний', + pathsEyebrow: 'Контроль сложности', + pathsTitle: 'Выбираем пути разной длины', + pathsSubtitle: 'Один и тот же ответ можно получить через 1-hop, 2-hop или 3-hop пути', + dataEyebrow: 'Генерация', + dataTitle: 'Пути по графу превращаются в QA-примеры', + dataSubtitle: 'Путь объясняет ответ на вопрос', + syntheticDataset: 'Проверяемая синтетика', + smallModel: 'малая доменная модель', + }, + }, + en: { + syntheticGraphNodes: enGraph.compactGraphNodes, + syntheticGraphEdges: enGraph.compactGraphEdges, + syntheticAnswerNodeId, + syntheticPaths: syntheticPathsEn, + naturalQACards: naturalQACardsEn, + datasetLabels, + labels: { + answerCallout: 'answer: utility networks', + graphEyebrow: 'Synthetic data', + graphTitle: 'The graph becomes a source of training data', + graphSubtitle: 'Choose an answer node in the knowledge graph', + pathsEyebrow: 'Complexity control', + pathsTitle: 'Sample paths of different length', + pathsSubtitle: 'The same answer can be reached through 1-hop, 2-hop, or 3-hop paths', + dataEyebrow: 'Generation', + dataTitle: 'Graph paths become QA examples', + dataSubtitle: 'The path explains the answer to the question', + syntheticDataset: 'Verifiable synthetic data', + smallModel: 'small domain model', + }, + }, +}; + +export const getAnimation3Content = (locale: Locale = 'ru') => animation3Content[locale]; diff --git a/wikontic-demo-animation/src/data/graphAfter.ts b/wikontic-demo-animation/src/data/graphAfter.ts new file mode 100644 index 0000000..4d5eb6a --- /dev/null +++ b/wikontic-demo-animation/src/data/graphAfter.ts @@ -0,0 +1,77 @@ +import type {GraphEdge, GraphNode} from './graphBefore'; + +export const refinedNodes: GraphNode[] = [ + { + id: 'complex_clean', + label: 'жилой комплекс', + type: 'строительный объект', + x: 0.22, + y: 0.46, + kind: 'project', + }, + { + id: 'buildings', + label: 'три корпуса', + type: 'здание', + x: 0.52, + y: 0.24, + kind: 'asset', + }, + { + id: 'parking', + label: 'подземный паркинг', + type: 'инфраструктура', + x: 0.57, + y: 0.45, + kind: 'asset', + }, + { + id: 'monitoring', + label: 'система мониторинга', + type: 'инженерная система', + x: 0.55, + y: 0.68, + kind: 'system', + }, + { + id: 'networks_clean', + label: 'инженерные сети', + type: 'инженерная система', + x: 0.8, + y: 0.68, + kind: 'system', + }, + { + id: 'requirements', + label: 'требования', + type: 'требование', + x: 0.3, + y: 0.2, + kind: 'requirement', + }, + { + id: 'year', + label: '2024', + type: 'дата', + x: 0.12, + y: 0.2, + kind: 'time', + }, +]; + +export const refinedEdges: GraphEdge[] = [ + {id: 'e1_clean', source: 'complex_clean', target: 'buildings', label: 'включает', status: 'valid'}, + {id: 'e2_clean', source: 'complex_clean', target: 'parking', label: 'включает', status: 'valid'}, + {id: 'e3_clean', source: 'complex_clean', target: 'monitoring', label: 'включает', status: 'path'}, + {id: 'e4_clean', source: 'monitoring', target: 'networks_clean', label: 'относится к', status: 'path'}, + {id: 'e5_clean', source: 'requirements', target: 'year', label: 'дата', status: 'valid'}, + {id: 'e6_clean', source: 'requirements', target: 'complex_clean', label: 'объект требований', status: 'valid'}, +]; + +export const aliasMerges = [ + {from: ['ЖК', 'объект'], to: 'жилой комплекс'}, + {from: ['сети'], to: 'инженерные сети'}, +]; + +export const qaPathEdgeIds = ['e3_clean', 'e4_clean']; +export const qaPathNodeIds = ['complex_clean', 'monitoring', 'networks_clean']; diff --git a/wikontic-demo-animation/src/data/graphBefore.ts b/wikontic-demo-animation/src/data/graphBefore.ts new file mode 100644 index 0000000..d606624 --- /dev/null +++ b/wikontic-demo-animation/src/data/graphBefore.ts @@ -0,0 +1,39 @@ +export type GraphNode = { + id: string; + label: string; + type?: string; + x: number; + y: number; + kind: 'project' | 'asset' | 'system' | 'requirement' | 'time' | 'document'; + aliasOf?: string; +}; + +export type GraphEdge = { + id: string; + source: string; + target: string; + label: string; + status?: 'valid' | 'warning' | 'invalid' | 'path'; +}; + +export const dirtyNodes: GraphNode[] = [ + {id: 'complex', label: 'жилой комплекс', x: 0.24, y: 0.38, kind: 'project', aliasOf: 'complex_clean'}, + {id: 'jk', label: 'ЖК', x: 0.17, y: 0.58, kind: 'project', aliasOf: 'complex_clean'}, + {id: 'object', label: 'объект', x: 0.31, y: 0.62, kind: 'project', aliasOf: 'complex_clean'}, + {id: 'buildings', label: 'три корпуса', x: 0.52, y: 0.23, kind: 'asset'}, + {id: 'parking', label: 'подземный паркинг', x: 0.61, y: 0.42, kind: 'asset'}, + {id: 'monitoring', label: 'система мониторинга', x: 0.55, y: 0.66, kind: 'system'}, + {id: 'networks', label: 'инженерные сети', x: 0.78, y: 0.58, kind: 'system', aliasOf: 'networks_clean'}, + {id: 'nets', label: 'сети', x: 0.82, y: 0.77, kind: 'system', aliasOf: 'networks_clean'}, + {id: 'requirements', label: 'требования', x: 0.28, y: 0.18, kind: 'requirement'}, + {id: 'year', label: '2024', x: 0.13, y: 0.21, kind: 'time'}, +]; + +export const dirtyEdges: GraphEdge[] = [ + {id: 'e1', source: 'complex', target: 'buildings', label: 'включает', status: 'valid'}, + {id: 'e2', source: 'jk', target: 'parking', label: 'содержит', status: 'warning'}, + {id: 'e3', source: 'object', target: 'monitoring', label: 'имеет в составе', status: 'warning'}, + {id: 'e4', source: 'monitoring', target: 'nets', label: 'про сети', status: 'invalid'}, + {id: 'e5', source: 'requirements', target: 'year', label: 'дата', status: 'valid'}, + {id: 'e6', source: 'requirements', target: 'object', label: 'для', status: 'warning'}, +]; diff --git a/wikontic-demo-animation/src/i18n/types.ts b/wikontic-demo-animation/src/i18n/types.ts new file mode 100644 index 0000000..43ad890 --- /dev/null +++ b/wikontic-demo-animation/src/i18n/types.ts @@ -0,0 +1,3 @@ +export type Locale = 'ru' | 'en'; + +export const normalizeLocale = (value: string | null | undefined): Locale => (value === 'ru' ? 'ru' : 'en'); diff --git a/wikontic-demo-animation/src/index.ts b/wikontic-demo-animation/src/index.ts new file mode 100644 index 0000000..d831f7b --- /dev/null +++ b/wikontic-demo-animation/src/index.ts @@ -0,0 +1,4 @@ +import {registerRoot} from 'remotion'; +import {RemotionRoot} from './Root'; + +registerRoot(RemotionRoot); diff --git a/wikontic-demo-animation/src/interactive/GraphDemo.tsx b/wikontic-demo-animation/src/interactive/GraphDemo.tsx new file mode 100644 index 0000000..8b892cc --- /dev/null +++ b/wikontic-demo-animation/src/interactive/GraphDemo.tsx @@ -0,0 +1,63 @@ +import React, {useMemo, useState} from 'react'; +import {GraphView} from '../components/GraphView'; +import type {GraphNode} from '../data/graphBefore'; +import {qaPathEdgeIds, qaPathNodeIds, refinedEdges, refinedNodes} from '../data/graphAfter'; +import {ragQuestion as question, ragVsWikonticAnswer as answer} from '../data/animation2'; +import '../styles/global.css'; + +const aliases: Record = { + complex_clean: ['ЖК', 'объект', 'жилой комплекс'], + networks_clean: ['сети', 'инженерные сети'], + monitoring: ['система мониторинга'], +}; + +export const GraphDemo: React.FC = () => { + const [selectedNode, setSelectedNode] = useState(refinedNodes[0]); + const [showPath, setShowPath] = useState(true); + const selectedEdges = useMemo( + () => refinedEdges.filter((edge) => edge.source === selectedNode.id || edge.target === selectedNode.id), + [selectedNode.id], + ); + + return ( +
+
+ Wikontic +
+

Wikontic backup graph demo

+

Детерминированный локальный граф без API и backend-запросов

+
+
+
+
+ edge.id)} + muted + onNodeSelect={(node) => { + setSelectedNode(node); + setShowPath(false); + }} + width={1120} + height={700} + /> +
+ +
+
+ ); +}; diff --git a/wikontic-demo-animation/src/main.tsx b/wikontic-demo-animation/src/main.tsx new file mode 100644 index 0000000..0945145 --- /dev/null +++ b/wikontic-demo-animation/src/main.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import {createRoot} from 'react-dom/client'; +import {GraphDemo} from './interactive/GraphDemo'; + +createRoot(document.getElementById('root') as HTMLElement).render( + + + , +); diff --git a/wikontic-demo-animation/src/presentation/PresentationApp.tsx b/wikontic-demo-animation/src/presentation/PresentationApp.tsx new file mode 100644 index 0000000..e0cbfb4 --- /dev/null +++ b/wikontic-demo-animation/src/presentation/PresentationApp.tsx @@ -0,0 +1,481 @@ +import React, {useCallback, useEffect, useRef, useState} from 'react'; +import {Player} from '@remotion/player'; +import type {CallbackListener, PlayerRef} from '@remotion/player'; +import {ChevronLeft, ChevronRight, Maximize2, Pause, Play, RotateCcw, SkipBack, SkipForward} from 'lucide-react'; +import {MetricBadge} from '../components/MetricBadge'; +import {getPresentationSlides, presentationVideo} from './presentationConfig'; +import type {AnimationSlide} from './presentationConfig'; +import {normalizeLocale} from '../i18n/types'; +import type {Locale} from '../i18n/types'; + +const clampFrame = (frame: number, slide: AnimationSlide) => + Math.max(0, Math.min(slide.durationInFrames - 1, Math.round(frame))); + +const formatTime = (frame: number, duration: number) => `${frame} / ${duration - 1}`; + +const presentationCopy: Record = { + ru: { + metrics: { + title: 'из документов в проверяемую базу фактов', + subtitle: 'Интерпретируемость · Multi-hop reasoning · Генерация синтетических данных', + badges: [ + {value: '84-86%', label: 'извлеченных фактов на MINE-1', tone: 'blue'}, + {value: '76.0 F1', label: 'QA только по графу на HotpotQA', tone: 'green'}, + {value: 'x20 экономия токенов', label: 'по сравнению с GraphRAG', tone: 'blue'}, + ], + }, + controls: { + back: 'Назад', + pause: 'Пауза', + continue: 'Продолжить', + restart: 'Сначала', + next: 'Далее', + finalNote: 'Финальный слайд статичен: используйте стрелки, чтобы вернуться к анимациям.', + hints: ['Space: play/pause', '← / →: slide', 'R: restart', ', / .: ±15 frames'], + }, + }, + en: { + metrics: { + title: 'from documents to a verifiable fact base', + subtitle: 'Interpretability · Multi-hop reasoning · Synthetic data generation', + badges: [ + {value: '84-86%', label: 'fact retention on MINE-1', tone: 'blue'}, + {value: '76.0 F1', label: 'graph-only QA on HotpotQA', tone: 'green'}, + {value: 'x20 token economy', label: 'compared with GraphRAG', tone: 'blue'}, + ], + }, + controls: { + back: 'Back', + pause: 'Pause', + continue: 'Continue', + restart: 'Restart', + next: 'Next', + finalNote: 'The final slide is static: use arrows to return to the animations.', + hints: ['Space: play/pause', '← / →: slide', 'R: restart', ', / .: ±15 frames'], + }, + }, +}; + +const MetricsSlide: React.FC<{locale: Locale}> = ({locale}) => { + const copy = presentationCopy[locale].metrics; + return ( +
+
+
+ Wikontic +
+

{copy.title}

+

{copy.subtitle}

+
+
+ {copy.badges.map((badge) => ( + + ))} +
+
+
+ ); +}; + +const StaticStage: React.FC<{children: React.ReactNode}> = ({children}) => { + const viewportRef = useRef(null); + const [size, setSize] = useState({ + width: presentationVideo.width, + height: presentationVideo.height, + }); + + useEffect(() => { + const viewport = viewportRef.current; + if (!viewport) { + return; + } + + const updateSize = () => { + const rect = viewport.getBoundingClientRect(); + setSize({width: rect.width, height: rect.height}); + }; + + updateSize(); + const observer = new ResizeObserver(updateSize); + observer.observe(viewport); + return () => observer.disconnect(); + }, []); + + const scale = Math.min(size.width / presentationVideo.width, size.height / presentationVideo.height); + + return ( +
+
+ {children} +
+
+ ); +}; + +export const PresentationApp: React.FC = () => { + const [locale, setLocale] = useState(() => normalizeLocale(new URLSearchParams(window.location.search).get('lang'))); + const presentationSlides = getPresentationSlides(locale); + const copy = presentationCopy[locale].controls; + const [activeIndex, setActiveIndex] = useState(0); + const [currentFrame, setCurrentFrame] = useState(0); + const [isPlaying, setIsPlaying] = useState(false); + const playerRef = useRef(null); + const [playerHandle, setPlayerHandle] = useState(null); + const activeSlide = presentationSlides[activeIndex]; + const activeAnimation = activeSlide.kind === 'animation' ? activeSlide : null; + + const setPlayerRef = useCallback((node: PlayerRef | null) => { + playerRef.current = node; + setPlayerHandle(node); + }, []); + + const pause = useCallback(() => { + playerRef.current?.pause(); + setIsPlaying(false); + }, []); + + const changeLocale = useCallback( + (nextLocale: Locale) => { + if (nextLocale === locale) { + return; + } + pause(); + setCurrentFrame(0); + setLocale(nextLocale); + + const url = new URL(window.location.href); + if (nextLocale === 'en') { + url.searchParams.delete('lang'); + } else { + url.searchParams.set('lang', nextLocale); + } + window.history.replaceState(null, '', `${url.pathname}${url.search}${url.hash}`); + }, + [locale, pause], + ); + + const play = useCallback(() => { + if (!activeAnimation) { + return; + } + playerRef.current?.play(); + setIsPlaying(true); + }, [activeAnimation]); + + const seekTo = useCallback( + (frame: number) => { + if (!activeAnimation) { + return; + } + const nextFrame = clampFrame(frame, activeAnimation); + playerRef.current?.seekTo(nextFrame); + setCurrentFrame(nextFrame); + }, + [activeAnimation], + ); + + const restart = useCallback(() => { + if (!activeAnimation) { + return; + } + seekTo(0); + playerRef.current?.play(); + setIsPlaying(true); + }, [activeAnimation, seekTo]); + + const goToSlide = useCallback( + (nextIndex: number) => { + pause(); + setActiveIndex(Math.max(0, Math.min(presentationSlides.length - 1, nextIndex))); + setCurrentFrame(0); + }, + [pause, presentationSlides.length], + ); + + const togglePlayback = useCallback(() => { + if (!activeAnimation) { + return; + } + if (playerRef.current?.isPlaying()) { + pause(); + } else { + play(); + } + }, [activeAnimation, pause, play]); + + useEffect(() => { + if (!activeAnimation || !playerHandle) { + return; + } + + const timer = window.setTimeout(() => { + playerHandle.seekTo(0); + setCurrentFrame(0); + playerHandle.play(); + setIsPlaying(true); + }, 0); + + return () => window.clearTimeout(timer); + }, [activeAnimation?.id, playerHandle]); + + useEffect(() => { + if (!activeAnimation) { + setIsPlaying(false); + setCurrentFrame(0); + return; + } + + const player = playerRef.current; + if (!player) { + return; + } + + const onFrame: CallbackListener<'frameupdate'> = ({detail}) => setCurrentFrame(detail.frame); + const onPlay: CallbackListener<'play'> = () => setIsPlaying(true); + const onPause: CallbackListener<'pause'> = () => setIsPlaying(false); + const onEnded: CallbackListener<'ended'> = () => setIsPlaying(false); + + player.addEventListener('frameupdate', onFrame); + player.addEventListener('play', onPlay); + player.addEventListener('pause', onPause); + player.addEventListener('ended', onEnded); + + return () => { + player.removeEventListener('frameupdate', onFrame); + player.removeEventListener('play', onPlay); + player.removeEventListener('pause', onPause); + player.removeEventListener('ended', onEnded); + }; + }, [activeAnimation?.id]); + + useEffect(() => { + const onKeyDown = (event: KeyboardEvent) => { + const target = event.target as HTMLElement | null; + if (target && ['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)) { + return; + } + + if (event.key === ' ') { + event.preventDefault(); + togglePlayback(); + } else if (event.key === 'ArrowRight') { + event.preventDefault(); + goToSlide(activeIndex + 1); + } else if (event.key === 'ArrowLeft') { + event.preventDefault(); + goToSlide(activeIndex - 1); + } else if (event.key.toLowerCase() === 'r') { + event.preventDefault(); + restart(); + } else if (event.key === ',') { + event.preventDefault(); + seekTo(currentFrame - 15); + } else if (event.key === '.') { + event.preventDefault(); + seekTo(currentFrame + 15); + } else if (/^[1-9]$/.test(event.key) && activeAnimation) { + const chapter = activeAnimation.chapters[Number(event.key) - 1]; + if (chapter) { + event.preventDefault(); + pause(); + seekTo(chapter.frame); + } + } + }; + + window.addEventListener('keydown', onKeyDown); + return () => window.removeEventListener('keydown', onKeyDown); + }, [activeAnimation, activeIndex, currentFrame, goToSlide, pause, restart, seekTo, togglePlayback]); + + return ( +
+ + +
+
+
+
+ {activeIndex + 1} / {presentationSlides.length} +
+

{activeSlide.title}

+

{activeSlide.subtitle}

+
+ {activeAnimation ? ( +
{formatTime(currentFrame, activeAnimation.durationInFrames)}
+ ) : null} +
+ +
+
+ {activeAnimation ? ( + + ) : ( + + + + )} +
+
+ +
+
+ + + + + + + +
+ + {activeAnimation ? ( + <> + { + pause(); + seekTo(Number(event.currentTarget.value)); + }} + /> +
+ {activeAnimation.chapters.map((chapter, index) => ( + + ))} +
+ + ) : ( +
+ {copy.finalNote} +
+ )} +
+
+
+ ); +}; diff --git a/wikontic-demo-animation/src/presentation/main.tsx b/wikontic-demo-animation/src/presentation/main.tsx new file mode 100644 index 0000000..8d8822f --- /dev/null +++ b/wikontic-demo-animation/src/presentation/main.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import {createRoot} from 'react-dom/client'; +import {PresentationApp} from './PresentationApp'; +import '../styles/global.css'; +import './presentation.css'; + +createRoot(document.getElementById('presentation-root') as HTMLElement).render( + + + , +); diff --git a/wikontic-demo-animation/src/presentation/presentation.css b/wikontic-demo-animation/src/presentation/presentation.css new file mode 100644 index 0000000..e34cf46 --- /dev/null +++ b/wikontic-demo-animation/src/presentation/presentation.css @@ -0,0 +1,393 @@ +#presentation-root { + min-height: 100vh; +} + +.presentationShell { + min-height: 100vh; + display: grid; + grid-template-columns: 330px minmax(0, 1fr); + background: #eef3f9; + color: #172033; +} + +.presentationSidebar { + display: grid; + grid-template-rows: auto auto 1fr auto; + gap: 28px; + padding: 28px 22px; + border-right: 1px solid #dbe3ef; + background: rgba(255, 255, 255, 0.88); +} + +.presentationBrand { + display: flex; + align-items: center; + gap: 14px; +} + +.presentationBrand img { + width: 46px; + height: 46px; +} + +.presentationBrand strong, +.presentationBrand span { + display: block; +} + +.presentationBrand strong { + font-size: 23px; + line-height: 1; +} + +.presentationBrand span { + margin-top: 5px; + color: #647084; + font-size: 14px; + font-weight: 700; +} + +.localeToggle { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 6px; + padding: 5px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #f8fafc; +} + +.localeToggle button { + min-height: 34px; + border: 0; + border-radius: 6px; + background: transparent; + color: #647084; + font: inherit; + font-size: 13px; + font-weight: 850; + cursor: pointer; +} + +.localeToggle button:hover { + color: #1748b5; +} + +.localeToggle .activeLocale { + background: #ffffff; + color: #1748b5; + box-shadow: 0 8px 20px rgba(23, 32, 51, 0.1); +} + +.slideList { + display: grid; + align-content: start; + gap: 12px; +} + +.slideList button { + display: grid; + grid-template-columns: auto 1fr; + gap: 4px 12px; + width: 100%; + padding: 15px 16px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + color: #172033; + text-align: left; + cursor: pointer; +} + +.slideList button span { + grid-row: span 2; + color: #8b98aa; + font-size: 14px; + font-weight: 820; +} + +.slideList button strong { + font-size: 18px; + line-height: 1.1; +} + +.slideList button small { + color: #647084; + font-size: 13px; + line-height: 1.25; + font-weight: 650; +} + +.slideList .activeSlideButton { + border-color: #2f6df6; + background: #eef4ff; + box-shadow: 0 14px 32px rgba(47, 109, 246, 0.12); +} + +.slideList .activeSlideButton span, +.slideList .activeSlideButton strong { + color: #1748b5; +} + +.keyboardHints { + display: grid; + gap: 7px; + padding: 14px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #f8fafc; + color: #647084; + font-size: 13px; + font-weight: 720; +} + +.presentationMain { + min-width: 0; + display: grid; + grid-template-rows: auto minmax(0, 1fr) auto; + gap: 18px; + padding: 26px 32px 24px; +} + +.presentationTopbar { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 24px; +} + +.presentationEyebrow { + margin-bottom: 5px; + color: #2f6df6; + font-size: 13px; + font-weight: 850; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.presentationTopbar h1 { + margin: 0; + font-size: 34px; + line-height: 1.05; +} + +.presentationTopbar p { + margin: 6px 0 0; + color: #647084; + font-size: 17px; + font-weight: 650; +} + +.frameCounter { + min-width: 150px; + padding: 10px 12px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + color: #647084; + font-size: 15px; + font-weight: 800; + text-align: center; +} + +.stageOuter { + min-height: 0; + display: grid; + place-items: center; +} + +.stageFrame { + width: min(100%, calc((100vh - 230px) * 16 / 9)); + aspect-ratio: 16 / 9; + border: 1px solid #cfd9e8; + border-radius: 8px; + background: #ffffff; + overflow: hidden; + box-shadow: 0 24px 80px rgba(23, 32, 51, 0.16); +} + +.presentationControls { + display: grid; + gap: 13px; + padding: 16px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: rgba(255, 255, 255, 0.92); +} + +.transportControls, +.chapterControls { + display: flex; + flex-wrap: wrap; + gap: 9px; +} + +.transportControls button, +.chapterControls button { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 7px; + min-height: 40px; + padding: 9px 12px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + color: #172033; + font: inherit; + font-size: 14px; + font-weight: 800; + cursor: pointer; +} + +.transportControls button:disabled, +.chapterControls button:disabled { + cursor: not-allowed; + opacity: 0.45; +} + +.transportControls button:hover:not(:disabled), +.chapterControls button:hover:not(:disabled) { + border-color: #2f6df6; +} + +.chapterControls button span { + display: inline-grid; + place-items: center; + width: 22px; + height: 22px; + border-radius: 6px; + background: #eef4ff; + color: #1748b5; + font-size: 12px; +} + +.chapterControls .activeChapter { + border-color: #2f6df6; + background: #eef4ff; + color: #1748b5; +} + +.frameScrubber { + width: 100%; + accent-color: #2f6df6; +} + +.finalSlideNote { + min-height: 40px; + align-items: center; + color: #647084; + font-size: 15px; + font-weight: 760; +} + +.staticStageViewport { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + background: #ffffff; +} + +.staticStageCanvas { + position: absolute; + top: 50%; + left: 50%; + transform-origin: center center; +} + +.metricsSlide { + position: relative; + width: 100%; + height: 100%; + display: grid; + place-items: center; + overflow: hidden; + background: linear-gradient(180deg, #fbfcff 0%, #f4f7fb 100%); +} + +.metricsGridTexture { + position: absolute; + inset: 0; + background-image: + linear-gradient(rgba(23, 32, 51, 0.035) 1px, transparent 1px), + linear-gradient(90deg, rgba(23, 32, 51, 0.035) 1px, transparent 1px); + background-size: 42px 42px; +} + +.metricsContent { + position: relative; + z-index: 1; + display: grid; + justify-items: center; + gap: 42px; + width: min(1420px, 92%); + text-align: center; +} + +.metricsLogo { + width: 430px; + max-width: 48%; + height: auto; +} + +.metricsEyebrow { + margin-bottom: 12px; + color: #2f6df6; + font-size: 18px; + font-weight: 850; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.metricsContent h1 { + margin: 0; + color: #172033; + font-size: 66px; + line-height: 1.06; + font-weight: 780; + letter-spacing: 0; +} + +.metricsContent p { + margin: 18px 0 0; + color: #647084; + font-size: 38px; + line-height: 1.25; +} + +.metricsBadges { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 22px; +} + +.metricsSlide .metricBadge { + gap: 7px; + min-width: 300px; + padding: 22px 26px; +} + +.metricsSlide .metricBadge strong { + font-size: 42px; +} + +.metricsSlide .metricBadge span { + font-size: 21px; + line-height: 1.25; +} + +@media (max-width: 1100px) { + .presentationShell { + grid-template-columns: 1fr; + } + + .presentationSidebar { + grid-template-rows: auto auto; + } + + .keyboardHints { + display: none; + } +} diff --git a/wikontic-demo-animation/src/presentation/presentationConfig.ts b/wikontic-demo-animation/src/presentation/presentationConfig.ts new file mode 100644 index 0000000..f694ec3 --- /dev/null +++ b/wikontic-demo-animation/src/presentation/presentationConfig.ts @@ -0,0 +1,169 @@ +import type {ComponentType} from 'react'; +import {Animation1_TextToGraph, TEXT_TO_GRAPH_FRAMES} from '../scenes/Animation1_TextToGraph'; +import {Animation2_RagVsGraph, RAG_VS_WIKONTIC_FRAMES} from '../scenes/Animation2_RagVsGraph'; +import {Animation3_SyntheticData, SYNTHETIC_DATA_FRAMES} from '../scenes/Animation3_SyntheticData'; +import {FPS, VIDEO_HEIGHT, VIDEO_WIDTH} from '../theme'; +import type {Locale} from '../i18n/types'; + +export type Chapter = { + label: string; + frame: number; +}; + +export type AnimationSlide = { + kind: 'animation'; + id: string; + title: string; + subtitle: string; + component: ComponentType<{locale?: Locale}>; + durationInFrames: number; + chapters: Chapter[]; +}; + +export type MetricsSlide = { + kind: 'metrics'; + id: string; + title: string; + subtitle: string; + chapters: []; +}; + +export type PresentationSlide = AnimationSlide | MetricsSlide; + +type LocalizedAnimationSlide = { + kind: 'animation'; + id: string; + title: string; + subtitle: string; + chapters: Chapter[]; +}; + +type LocalizedMetricsSlide = MetricsSlide; + +type LocalizedPresentationSlide = LocalizedAnimationSlide | LocalizedMetricsSlide; + +export const presentationVideo = { + width: VIDEO_WIDTH, + height: VIDEO_HEIGHT, + fps: FPS, +}; + +const localizedSlides: Record = { + ru: [ + { + kind: 'animation', + id: 'text-to-graph', + title: 'Wikontic', + subtitle: 'Текст превращается в проверяемую базу фактов', + chapters: [ + {label: 'Документ', frame: 0}, + {label: 'Триплеты', frame: 245}, + {label: 'Онтология', frame: 425}, + {label: 'Дедупликация', frame: 540}, + {label: 'Финальный граф', frame: 869}, + ], + }, + { + kind: 'animation', + id: 'rag-vs-wikontic', + title: 'RAG vs Wikontic', + subtitle: 'Wikontic лучше подходит для сложных вопросов, где надо связать несколько фактов', + chapters: [ + {label: 'Вопрос', frame: 25}, + {label: 'RAG-фрагменты', frame: 275}, + {label: 'RAG failure', frame: 350}, + {label: 'RAG итог', frame: 600}, + {label: 'Путь в графе', frame: 1050}, + {label: 'Ответ', frame: 1200}, + ], + }, + { + kind: 'animation', + id: 'synthetic-data', + title: 'Генерация синтетических данных', + subtitle: 'Граф как генератор качественных синтетических данных для обучения моделей', + chapters: [ + {label: 'Граф', frame: 50}, + {label: 'Ответ', frame: 140}, + {label: 'Пути', frame: 400}, + {label: 'QA-карточки', frame: 588}, + {label: 'Датасет', frame: 680}, + ], + }, + { + kind: 'metrics', + id: 'metrics', + title: 'Итог', + subtitle: 'Ключевые результаты', + chapters: [], + }, + ], + en: [ + { + kind: 'animation', + id: 'text-to-graph', + title: 'Wikontic', + subtitle: 'Text becomes a verifiable fact base', + chapters: [ + {label: 'Document', frame: 0}, + {label: 'Triplets', frame: 245}, + {label: 'Ontology', frame: 425}, + {label: 'Deduplication', frame: 540}, + {label: 'Final graph', frame: 869}, + ], + }, + { + kind: 'animation', + id: 'rag-vs-wikontic', + title: 'RAG vs Wikontic', + subtitle: 'For complex questions, Wikontic follows explicit relations between facts', + chapters: [ + {label: 'Question', frame: 25}, + {label: 'RAG chunks', frame: 275}, + {label: 'RAF failure', frame: 350}, + {label: 'RAF summary', frame: 600}, + {label: 'Graph path', frame: 1050}, + {label: 'Answer', frame: 1200}, + ], + }, + { + kind: 'animation', + id: 'synthetic-data', + title: 'Synthetic data generation', + subtitle: 'The graph becomes a source of high-quality synthetic data for model training', + chapters: [ + {label: 'Graph', frame: 50}, + {label: 'Answer', frame: 140}, + {label: 'Paths', frame: 400}, + {label: 'QA cards', frame: 588}, + {label: 'Dataset', frame: 680}, + ], + }, + { + kind: 'metrics', + id: 'metrics', + title: 'Summary', + subtitle: 'Key results', + chapters: [], + }, + ], +}; + +const slideComponents = [ + {component: Animation1_TextToGraph, durationInFrames: TEXT_TO_GRAPH_FRAMES}, + {component: Animation2_RagVsGraph, durationInFrames: RAG_VS_WIKONTIC_FRAMES}, + {component: Animation3_SyntheticData, durationInFrames: SYNTHETIC_DATA_FRAMES}, +]; + +export const getPresentationSlides = (locale: Locale = 'ru'): PresentationSlide[] => + localizedSlides[locale].map((slide, index) => { + if (slide.kind === 'metrics') { + return slide; + } + return { + ...slide, + ...slideComponents[index], + }; + }); + +export const presentationSlides = getPresentationSlides('ru'); diff --git a/wikontic-demo-animation/src/scenes/Animation1_TextToGraph.tsx b/wikontic-demo-animation/src/scenes/Animation1_TextToGraph.tsx new file mode 100644 index 0000000..57fc731 --- /dev/null +++ b/wikontic-demo-animation/src/scenes/Animation1_TextToGraph.tsx @@ -0,0 +1,243 @@ +import React from 'react'; +import {interpolate, useCurrentFrame} from 'remotion'; +import {CheckCircle2} from 'lucide-react'; +import {DedupMerge} from '../components/DedupMerge'; +import {DocumentView} from '../components/DocumentView'; +import {GraphView} from '../components/GraphView'; +import {OntologyPass} from '../components/OntologyPass'; +import {Panel, SceneLayout} from '../components/SceneLayout'; +import {TripletCard} from '../components/TripletCard'; +import {getAnimation1Content} from '../data/animation1'; +import type {Locale} from '../i18n/types'; + +const clamp = (value: number) => Math.max(0, Math.min(1, value)); +const progress = (frame: number, from: number, to: number) => + interpolate(frame, [from, to], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); + +// Same spread-out grid layout used in Animation 2 — nodes never overlap at any size. +// Columns shifted to give edge labels clearance: complex→right, center-column→right, +// networks→right; risks moved up so "связаны с" becomes diagonal (longer path, label fits). +const finalGraphLayout: Record = { + requirements: {x: 0.08, y: 0.14}, + year: {x: 0.3, y: 0.14}, + project: {x: 0.05, y: 0.5}, + complex: {x: 0.285, y: 0.5}, + buildings: {x: 0.51, y: 0.14}, + monitoring: {x: 0.51, y: 0.5}, + parking: {x: 0.51, y: 0.86}, + networks: {x: 0.74, y: 0.5}, + risks: {x: 0.91, y: 0.25}, +}; +export const TEXT_TO_GRAPH_FRAMES = 870; + +type Animation1Props = { + locale?: Locale; +}; + +export const Animation1_TextToGraph: React.FC = ({locale = 'ru'}) => { + const content = getAnimation1Content(locale); + const finalGraphNodes = content.compactGraphNodes.map((node) => ({ + ...node, + ...(finalGraphLayout[node.id] ?? {}), + })); + const frame = useCurrentFrame(); + const activeFactCount = Math.min(content.highlightedFacts.length, Math.floor(frame / 22) + 1); + const activeFactIds = content.highlightedFacts.slice(0, activeFactCount).map((fact) => fact.id); + const factsRemain = progress(frame, 110, 150); + const tripletsIn = progress(frame, 120, 180); + const ontologyIn = progress(frame, 270, 455); + const dedupIn = progress(frame, 455, 600); + // Panel background fades in fast (opaque quickly, less "transparent" time). + // Node reveal is separate and slower — each of 9 nodes gets ~18 frames to itself. + const graphFadeIn = progress(frame, 600, 635); + const graphReveal = progress(frame, 605, 770); + const title = + frame < 120 + ? content.titles.document + : frame < 270 + ? content.titles.triplets + : frame < 455 + ? content.titles.ontology + : frame < 625 + ? content.titles.dedup + : content.titles.final; + + // During step 2 (ontologyIn): document fades out and triplets slide left + const docFadeForOntology = progress(frame, 265, 300); + const ontologyFadeIn = progress(frame, 260, 305); + const tripletsSlide = progress(frame, 270, 295); + const tripletsLeft = interpolate(tripletsSlide, [0, 1], [840, 40]); + const dedupFadeIn = progress(frame, 450, 470); + const dedupSlide = progress(frame, 450, 485); + const tripletsDedupScale = interpolate(dedupSlide, [0, 1], [1, 0.80]); + const tripletsScale = interpolate(tripletsSlide, [0, 1], [1, 0.88]) * tripletsDedupScale; + const tripletsOpacityDedup = interpolate(dedupSlide, [0, 1], [1, 0.40]); + + const ontologyDedupX = interpolate(dedupSlide, [0, 1], [0, -560]); + const ontologyDedupScale = interpolate(dedupSlide, [0, 1], [1, 0.65]); + const ontologyOpacityDedup = interpolate(dedupSlide, [0, 1], [1, 0.60]); + + return ( + +
+
0 ? 0 : 1 - docFadeForOntology, + transform: `translateX(${graphFadeIn * -70 - docFadeForOntology * 80}px) scale(${1 - graphFadeIn * 0.12})`, + }} + > + 0.45} + closeup={1 - progress(frame, 40, 130)} + toolbarLabel={content.labels.documentToolbar} + heading={content.labels.documentHeading} + /> +
+ +
+ {content.methodTriplets.map((triplet, index) => ( + + ))} +
+ +
+ +
+ +
+ [ + {label, x: 190, y: 155}, + {label, x: 380, y: 82}, + {label, x: 560, y: 155}, + ][index])} + canonical={content.dedupGroups[0].canonical} + aliasTags={[content.dedupGroups[0].aliases[0], content.dedupGroups[0].aliases[2]]} + aliasesPrefix={content.labels.dedupAliasesPrefix} + footer={content.labels.dedupFooter} + /> +
+ +
+
+ +
+
+
+ + {content.labels.sourceText} +
+
+ fact.id)} + closeup={0} + toolbarLabel={content.labels.documentToolbar} + heading={content.labels.documentHeading} + /> +
+
+
+
+ + {content.labels.graph} +
+ 0.55} + softReveal={true} + typeOutside={true} + nodeRadius={42} + nodeAspect={1.32} + labelFontSize={16} + typeFontSize={11} + edgeFontSize={13} + width={680} + height={400} + /> +
+
+
+
+ {content.labels.before} + 420 + {content.labels.tokens} +
+
+
+ {content.labels.after} +
+ 9 + {content.labels.entitiesAnd} + 12 + {content.labels.triplets} +
+
+
+
+
+ {content.graphBenefits.map((benefit, index) => { + const itemIn = clamp(graphReveal * 1.45 - index * 0.16); + return ( +
+ + {benefit} +
+ ); + })} +
+
+
+
+
+ ); +}; diff --git a/wikontic-demo-animation/src/scenes/Animation2_RagVsGraph.tsx b/wikontic-demo-animation/src/scenes/Animation2_RagVsGraph.tsx new file mode 100644 index 0000000..ff208bf --- /dev/null +++ b/wikontic-demo-animation/src/scenes/Animation2_RagVsGraph.tsx @@ -0,0 +1,762 @@ +import React from 'react'; +import {AbsoluteFill, Sequence, interpolate, useCurrentFrame} from 'remotion'; +import {Search, Split, Waypoints, X} from 'lucide-react'; +import {GraphView} from '../components/GraphView'; +import {PathHighlight} from '../components/PathHighlight'; +import {colors, font} from '../theme'; +import { + answerPathEdgeIds, + answerPathNodeIds, + getAnimation2Content, +} from '../data/animation2'; +import type {Animation2Content, Animation2Segment} from '../data/animation2'; +import type {Locale} from '../i18n/types'; + +const clamp = (value: number) => Math.max(0, Math.min(1, value)); +const progress = (frame: number, from: number, to: number) => + interpolate(frame, [from, to], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); + +// Sequential phases. Each phase fades IN from white and OUT to white quickly, +// with a long hold so it reads on the first watch. Phases never overlap. +const FADE = 11; // ~0.37s — fast decay/appear to/from white +const PHASES = { + rag: 616, // links → concept highlight → select → flag missed (cross + caption, dwell) → settle → takeaway + wikontic: 620, // ~20.7s — same docs → unite → build graph → path → answer box +} as const; + +const RAG_FROM = 0; +const WIKONTIC_FROM = RAG_FROM + PHASES.rag; + +export const RAG_VS_WIKONTIC_FRAMES = WIKONTIC_FROM + PHASES.wikontic; + +// Wraps phase content, handling the fast fade from/to white via opacity over +// the white composition background. +const Phase: React.FC<{duration: number; children: React.ReactNode}> = ({duration, children}) => { + const frame = useCurrentFrame(); + const opacity = Math.min( + interpolate(frame, [0, FADE], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}), + interpolate(frame, [duration - FADE, duration], [1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}), + ); + return ( + + {children} + + ); +}; + +const BigIcon: React.FC<{tone: 'muted' | 'wikontic'; children: React.ReactNode}> = ({tone, children}) => { + const accent = tone === 'wikontic' ? colors.blueDark : colors.muted; + const bg = tone === 'wikontic' ? colors.blueSoft : '#eef1f6'; + return ( +
+ {children} +
+ ); +}; + +// Three semantic "themes" that emphasise the key words of the question. +type Tone = 'blue' | 'green' | 'violet'; +const toneRgb: Record = { + blue: {bg: '219,232,255', line: '47,109,246'}, + green: {bg: '223,248,236', line: '25,169,116'}, + violet: {bg: '238,233,255', line: '122,92,255'}, +}; + +type Seg = Animation2Segment; + +// `on` (0→1) very gently fades in the tint + colored underline so the links +// read as a soft hint, not a hard highlight. +const SemText: React.FC<{segments: Seg[]; on: number; size: number; weight: number; color?: string}> = ({ + segments, + on, + size, + weight, + color, +}) => ( + + {segments.map((seg, i) => + seg.tone ? ( + + {seg.t} + + ) : ( + {seg.t} + ), + )} + +); + +// --- Filtering beat ------------------------------------------------------- +// A corpus of identical grey document boxes (no titles), linked by arrows that +// show how the fragments relate. RAG then highlights the question's concepts +// inside them, flags the relevant fragment it will miss, picks the matching +// ones and discards the rest, and the kept fragments slide into a column. +const STAGE_W = 1400; +const STAGE_H = 700; +const COL_X = 80; +const COL_W = 1240; +const SLOT_Y = [20, 120, 220]; +const MISSED_Y = 340; +const NOTE_Y = 500; +const BOX_H = 104; // assumed scatter height, used only for arrow anchoring + +const lerp = (a: number, b: number, t: number) => a + (b - a) * t; +const ease = (t: number) => t * t * (3 - 2 * t); // smoothstep — calm, pretty motion + +type CorpusBox = { + text: string; + col: number; // grid column (0..3) + row: number; // grid row (0..2) + slot?: number; // column slot if selected; undefined = discarded + lost?: boolean; // the relevant fragment RAG fails to retrieve + segments?: Seg[]; // question-concept highlighting (relevant fragments only) + tx?: number; // throw direction x (discarded) + ty?: number; // throw direction y (discarded) + sx: number; // derived screen x + sy: number; // derived screen y + sw: number; // derived width +}; + +// Tidy 4×3 grid (like the Wikontic intro) so nothing overlaps. +const GRID_COLS = [20, 365, 710, 1055]; +const GRID_ROWS = [20, 240, 460]; +const GRID_W = 300; + +// Relevant fragments sit on different rows AND columns; arrows connect the ones +// that share an entity (объект, система мониторинга, инженерные сети). The lost +// fragment is the bridge between фрагмент 1 and фрагмент 3. +const buildCorpus = (content: Animation2Content): CorpusBox[] => + content.corpusGrid.map((b) => ({ + ...b, + sx: GRID_COLS[b.col], + sy: GRID_ROWS[b.row], + sw: GRID_W, + })); + +// Arrows connect entity-sharing fragments, clipped to box edges so the heads +// land in the gaps (фрагмент 4 → 1 → 2(lost) → 3). +const boxCenter = (b: CorpusBox) => ({x: b.sx + b.sw / 2, y: b.sy + BOX_H / 2}); +const edgePoint = (b: CorpusBox, dx: number, dy: number) => { + const c = boxCenter(b); + const len = Math.hypot(dx, dy) || 1; + const ux = dx / len; + const uy = dy / len; + const t = Math.min( + ux !== 0 ? b.sw / 2 / Math.abs(ux) : Infinity, + uy !== 0 ? BOX_H / 2 / Math.abs(uy) : Infinity, + ); + return {x: c.x + ux * t, y: c.y + uy * t}; +}; +// Arrows by corpus index. `strong` marks the relevant chain through the lost +// bridge (slot2 → slot0 → lost → slot1); the rest is the surrounding mesh that +// shows the documents — and especially the lost one — are all connected. +const buildArrows = (corpus: CorpusBox[]) => { + const idxBySlot = (s: number) => corpus.findIndex((b) => b.slot === s); + const idxLost = corpus.findIndex((b) => b.lost); + const arrowSpecs: {from: number; to: number; strong?: boolean}[] = [ + {from: idxBySlot(2), to: idxBySlot(0), strong: true}, + {from: idxBySlot(0), to: idxLost, strong: true}, + {from: idxLost, to: idxBySlot(1), strong: true}, + {from: 4, to: idxLost}, + {from: 6, to: idxLost}, + {from: idxLost, to: 7}, + {from: idxLost, to: 11}, + {from: idxBySlot(0), to: 4}, + {from: 10, to: 6}, + {from: 5, to: 7}, + {from: 8, to: 11}, + {from: idxBySlot(1), to: 8}, + ]; + return arrowSpecs.map(({from, to, strong}) => { + const a = corpus[from]; + const b = corpus[to]; + const ca = boxCenter(a); + const cb = boxCenter(b); + const p1 = edgePoint(a, cb.x - ca.x, cb.y - ca.y); + const p2 = edgePoint(b, ca.x - cb.x, ca.y - cb.y); + return {p1, p2, len: Math.hypot(p2.x - p1.x, p2.y - p1.y), strong: strong === true}; + }); +}; + +const RagPhase: React.FC<{content: Animation2Content}> = ({content}) => { + const frame = useCurrentFrame(); + const corpus = buildCorpus(content); + const arrows = buildArrows(corpus); + const missedChunk = content.ragChunks[1]; + const headerIn = progress(frame, 6, 30); + const allIn = progress(frame, 24, 84); // all boxes appear (identical grey) + const arrowsIn = progress(frame, 92, 150); // links between fragments + const linkIn = progress(frame, 162, 220); // question concepts highlighted + const select = progress(frame, 226, 268); // relevant ones brighten FIRST + const lostIn = progress(frame, 282, 322); // THEN the missed fragment flares (softly) red + const lostMark = progress(frame, 318, 344); // red cross + «Фрагмент не найден!» appear + // dwell ~344-374 (≈1s) so the miss sinks in before anything moves + const arrowsOut = progress(frame, 374, 390); // links fade out quickly, before any box moves + const discard = progress(frame, 396, 440); // irrelevant (incl. lost) leave + const settle = progress(frame, 404, 444); // relevant slide into column — fast, hides reflow + const missedIn = progress(frame, 466, 509); // the relevant fragment RAG missed + const noteIn = progress(frame, 530, 573); // takeaway, then holds + return ( + + {/* Header: RAG title + the question, mirroring the Wikontic slide. */} +
+
+ + + + RAG +
+
+
+ {content.labels.question} +
+ +
+
+ +
+ {corpus.map((box, i) => { + const itemIn = clamp(allIn * 1.3 - i * 0.05); + const isSel = box.slot !== undefined; + const isLost = box.lost === true; + let left = box.sx; + let top = box.sy; + let width = box.sw; + let opacity = itemIn; + let scale = 1; + if (isSel) { + left = lerp(box.sx, COL_X, settle); + top = lerp(box.sy, SLOT_Y[box.slot!], settle); + width = lerp(box.sw, COL_W, settle); + } else { + left = box.sx + (box.tx ?? 0) * 600 * discard; + top = box.sy + (box.ty ?? 0) * 420 * discard; + opacity = itemIn * (isLost ? 1 : 1 - 0.45 * select) * (1 - discard); + scale = 1 - 0.12 * discard; + } + const sel = isSel ? select : 0; + const lost = isLost ? lostIn : 0; + const ch = (a: number, b: number, t: number) => Math.round(lerp(a, b, t)); + // All cards start as identical grey; selected brighten, lost goes red-outlined. + const bg = isLost + ? `rgb(${ch(238, 253, lost)}, ${ch(241, 237, lost)}, ${ch(246, 237, lost)})` + : `rgb(${ch(238, 248, sel)}, ${ch(241, 250, sel)}, ${ch(246, 252, sel)})`; + const borderCol = isSel + ? `rgb(${ch(221, 47, sel)}, ${ch(227, 109, sel)}, ${ch(236, 246, sel)})` + : isLost + ? `rgb(${ch(221, 216, lost)}, ${ch(227, 116, lost)}, ${ch(236, 116, lost)})` + : 'rgb(221, 227, 236)'; + const textCol = isLost + ? `rgb(${ch(91, 168, lost)}, ${ch(102, 70, lost)}, ${ch(117, 70, lost)})` + : `rgb(${ch(91, 23, sel)}, ${ch(102, 32, sel)}, ${ch(117, 51, sel)})`; + const fontSize = isSel ? lerp(24, 29, settle) : 24; + const weight = Math.round(lerp(600, 700, sel)); + return ( +
+ {box.segments ? ( + + ) : ( + box.text + )} + {isLost && lostMark > 0.001 ? ( + <> + {/* Red cross badge in the corner — clearly "this one is lost". */} +
+ +
+ {/* Caption under the box. */} +
+ {content.labels.notFound} +
+ {content.labels.noDirectLink} +
+ + ) : null} +
+ ); + })} + + {/* Links between related fragments (drawn BEHIND the docs). */} + + + + + + + {arrows.map((ar, i) => { + const o = clamp(arrowsIn * 1.2 - i * 0.12) * (1 - arrowsOut); + return ( + + ); + })} + + + {/* The relevant fragment RAG failed to retrieve. */} +
+
+ + {content.labels.relevantNotFound} +
+

+ {missedChunk.text} +

+
+ + {/* Takeaway. */} +
+ + {content.labels.ragNote} +
+
+
+ ); +}; + +// Intro beat: the SAME corpus RAG saw, laid out as a tidy 4×3 scatter across the +// graph area. Wikontic then unites them all (converge to centre + text fades) and +// the graph grows out of the merged mass. Reuses `corpus` text so it visibly reads +// as "same documents, handled differently". +const DOC_COLS = [70, 490, 910, 1330]; +const DOC_ROWS = [40, 235, 430]; +const DOC_W = 320; + +// Clean, evenly-spaced layout tuned for this wide canvas (1180x470) so bubbles +// never overlap. Overrides only x/y; node identity/labels stay from the data. +const wikonticLayout: Record = { + requirements: {x: 0.08, y: 0.14}, + year: {x: 0.3, y: 0.14}, + project: {x: 0.05, y: 0.5}, + complex: {x: 0.265, y: 0.5}, + buildings: {x: 0.5, y: 0.14}, + monitoring: {x: 0.5, y: 0.5}, + parking: {x: 0.5, y: 0.86}, + networks: {x: 0.735, y: 0.5}, + risks: {x: 0.95, y: 0.5}, +}; +const GRAPH_W = 1740; +const GRAPH_H = 560; + +const GRAPH_CY = GRAPH_H / 2; + +// The dot squashes onto — and unfolds from — where the first graph node (проект) +// will render, so the handoff reads as a single seamless motion. +const PROJECT_SX = wikonticLayout.project.x * GRAPH_W; +const PROJECT_SY = wikonticLayout.project.y * GRAPH_H; +const DOT_SCALE = 0.05; +const DOT_HALF = (DOC_W * DOT_SCALE) / 2; + +const WikonticPhase: React.FC<{content: Animation2Content}> = ({content}) => { + const frame = useCurrentFrame(); + const corpus = buildCorpus(content); + const docScatter = corpus.map((box, i) => ({ + text: box.text, + x: DOC_COLS[i % 4], + y: DOC_ROWS[Math.floor(i / 4)], + })); + const wikonticGraphNodes = content.ragVsGraphNodes.map((node) => ({ + ...node, + ...(wikonticLayout[node.id] ?? {}), + })); + const headerIn = progress(frame, 6, 40); + const docsIn = progress(frame, 24, 96); // same corpus appears, scattered & grey + const uniteIn = progress(frame, 124, 192); // all docs converge + squash to a single dot + const graphIn = progress(frame, 200, 286); // the dot unfolds into the graph, проект first + const pathIn = progress(frame, 300, 420); + const internalIn = progress(frame, 320, 410); + const answerIn = progress(frame, 510, 558); // answer box slides up from the bottom + const pathOut = progress(frame, 510, 552); // path box slides out downward + const visiblePathCount = Math.ceil(answerPathEdgeIds.length * pathIn); + // The dot fades out fully BEFORE the проект node ramps up, so the node always + // fades in over clean white and the dot never bleeds through it. + const docsGone = progress(frame, 192, 204); + return ( + + {/* Header: Wikontic title + the question, mirroring the RAG slide. */} +
+
+ + + + Wikontic +
+
+
+ {content.labels.question} +
+ +
+
+ +
+ {/* Intro: the same corpus RAG saw, scattered — then squashed to a dot. + Sits BEHIND the graph layer so the проект node unfolds over it. */} + {docsGone < 1 && ( +
+ {docScatter.map((doc, i) => { + const itemIn = clamp(docsIn * 1.3 - i * 0.05); + const u = ease(uniteIn); + // Converge + squash onto the проект node's spot, collapsing to a dot. + const left = lerp(doc.x, PROJECT_SX - DOT_HALF, u); + const top = lerp(doc.y, PROJECT_SY - DOT_HALF, u); + const scale = lerp(1, DOT_SCALE, u); + const textOpacity = clamp(1 - uniteIn * 2.4); + // Borders blend toward a single united block, then round into a dot. + const united = uniteIn; + const cornerRadius = lerp(12, 80, united); + return ( +
+ {doc.text} +
+ ); + })} +
+ )} + + {/* Caption that narrates the unite beat, fading out as the graph forms. */} +
+ {content.labels.uniteDocuments} +
+ +
+ 0.05} + /> +
+
+ + {/* Bottom slot: the path box, then the answer box slides up to replace it. */} +
+ {/* Path-to-answer box */} +
+
+ {content.labels.pathToAnswer} +
+ +
+ + {/* Answer box — slides up from the bottom to replace the path box */} +
+
+ {content.labels.answer} +
+

+ {content.answerSegments.map((seg, index) => + seg.tone ? ( + + {seg.text} + + ) : ( + {seg.text} + ), + )} +

+
+
+
+ ); +}; + +type Animation2Props = { + locale?: Locale; +}; + +export const Animation2_RagVsGraph: React.FC = ({locale = 'ru'}) => { + const content = getAnimation2Content(locale); + return ( + + + + + + + + + ); +}; diff --git a/wikontic-demo-animation/src/scenes/Animation3_SyntheticData.tsx b/wikontic-demo-animation/src/scenes/Animation3_SyntheticData.tsx new file mode 100644 index 0000000..30e611c --- /dev/null +++ b/wikontic-demo-animation/src/scenes/Animation3_SyntheticData.tsx @@ -0,0 +1,602 @@ +import React from 'react'; +import {AbsoluteFill, Sequence, interpolate, useCurrentFrame} from 'remotion'; +import {DatabaseZap, Layers3, Network, Waypoints} from 'lucide-react'; +import {GraphView} from '../components/GraphView'; +import {PathHighlight} from '../components/PathHighlight'; +import {colors, font} from '../theme'; +import {getAnimation3Content} from '../data/animation3'; +import type {Animation3Content} from '../data/animation3'; +import type {GraphEdge, GraphNode} from '../data/graphBefore'; +import type {Locale} from '../i18n/types'; + +const clamp = (value: number) => Math.max(0, Math.min(1, value)); +const progress = (frame: number, from: number, to: number) => + interpolate(frame, [from, to], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); + +const FADE = 11; +const PHASES = { + graph: 210, + paths: 240, + data: 270, +} as const; + +const GRAPH_FROM = 0; +const PATHS_FROM = GRAPH_FROM + PHASES.graph; +const DATA_FROM = PATHS_FROM + PHASES.paths; + +export const SYNTHETIC_DATA_FRAMES = DATA_FROM + PHASES.data; + +const STAGE_W = 1540; +const GRAPH_W = 1420; +const GRAPH_H = 600; + +const syntheticLayout: Record = { + requirements: {x: 0.1, y: 0.16}, + year: {x: 0.28, y: 0.16}, + project: {x: 0.08, y: 0.52}, + complex: {x: 0.3, y: 0.52}, + buildings: {x: 0.53, y: 0.16}, + monitoring: {x: 0.51, y: 0.52}, + parking: {x: 0.53, y: 0.82}, + networks: {x: 0.8, y: 0.52}, + risks: {x: 0.9, y: 0.22}, +}; + +const pathColors: Record = { + 'one-hop': colors.green, + 'two-hop': colors.blue, + 'three-hop': colors.amber, +}; + +const pathOffsets: Record = { + 'one-hop': -13, + 'two-hop': 0, + 'three-hop': 13, +}; + +const answerColor = colors.violet; + +type SyntheticGraph = { + nodes: GraphNode[]; + edges: GraphEdge[]; + paths: Animation3Content['syntheticPaths']; + answerNode: GraphNode; + nodeById: Map; + edgeById: Map; +}; + +const labelLines = (label: string) => { + const words = label.split(' '); + if (label.length < 14 || words.length === 1) { + return [label]; + } + const midpoint = Math.ceil(words.length / 2); + return [words.slice(0, midpoint).join(' '), words.slice(midpoint).join(' ')]; +}; + +const Phase: React.FC<{duration: number; children: React.ReactNode}> = ({duration, children}) => { + const frame = useCurrentFrame(); + const opacity = Math.min( + interpolate(frame, [0, FADE], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}), + interpolate(frame, [duration - FADE, duration], [1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}), + ); + return ( + + {children} + + ); +}; + +const Header: React.FC<{ + eyebrow: string; + title: string; + icon: React.ReactNode; + subtitle?: string; + progress: number; +}> = ({eyebrow, title, icon, subtitle, progress: p}) => ( +
+
+ {icon} +
+
+
+ {eyebrow} +
+
{title}
+ {subtitle ? ( +
+ {subtitle} +
+ ) : null} +
+
+); + +const GraphStage: React.FC<{ + graph: SyntheticGraph; + reveal: number; + muted?: boolean; + highlightedNodeIds?: string[]; + highlightedEdgeIds?: string[]; + stageHeight?: number; + graphHeight?: number; + showTypes?: boolean; + softReveal?: boolean; + overlay?: React.ReactNode; +}> = ({ + graph, + reveal, + muted = false, + highlightedNodeIds = [], + highlightedEdgeIds = [], + stageHeight = 650, + graphHeight = GRAPH_H, + showTypes = true, + softReveal = false, + overlay, +}) => ( +
+ + {overlay} +
+); + +const endpoint = ( + graph: SyntheticGraph, + sourceId: string, + targetId: string, + graphHeight: number, + trimFromSource: boolean, + offset: number, +) => { + const source = graph.nodeById.get(sourceId)!; + const target = graph.nodeById.get(targetId)!; + const sx = source.x * GRAPH_W; + const sy = source.y * graphHeight; + const tx = target.x * GRAPH_W; + const ty = target.y * graphHeight; + const dx = tx - sx; + const dy = ty - sy; + const len = Math.hypot(dx, dy) || 1; + const ux = dx / len; + const uy = dy / len; + const rx = 68 * 1.28; + const ry = 68; + const trim = 1 / Math.sqrt((ux / rx) ** 2 + (uy / ry) ** 2); + const baseX = trimFromSource ? sx + ux * trim : tx - ux * trim; + const baseY = trimFromSource ? sy + uy * trim : ty - uy * trim; + return { + x: baseX + -uy * offset, + y: baseY + ux * offset, + }; +}; + +const AnswerNodeOverlay: React.FC<{graph: SyntheticGraph; progress?: number; graphHeight: number; showType?: boolean}> = ({ + graph, + progress: p = 1, + graphHeight, + showType = true, +}) => { + const {answerNode} = graph; + const x = answerNode.x * GRAPH_W; + const y = answerNode.y * graphHeight; + const lines = labelLines(answerNode.label); + const scale = 0.92 + 0.08 * clamp(p); + const haloOpacity = 0.12 + 0.2 * clamp(p); + return ( + + + + + + + 1 ? 13 : -2)} textAnchor="middle" className="nodeLabel" style={{fontSize: 25}}> + {lines.map((line, index) => ( + + {line} + + ))} + + {showType && answerNode.type ? ( + + {answerNode.type} + + ) : null} + + ); +}; + +const GraphOverlaySvg: React.FC<{children: React.ReactNode; graphHeight: number}> = ({children, graphHeight}) => ( + + + + + + + + + + + + {children} + +); + +const MultiPathOverlay: React.FC<{graph: SyntheticGraph; progress: number; graphHeight: number}> = ({ + graph, + progress: p, + graphHeight, +}) => ( + + {graph.paths.map((path, pathIndex) => { + const color = pathColors[path.id]; + const offset = pathOffsets[path.id]; + return ( + + {path.edgeIds.map((edgeId) => { + const edge = graph.edgeById.get(edgeId); + if (!edge) { + return null; + } + const start = endpoint(graph, edge.source, edge.target, graphHeight, true, offset); + const end = endpoint(graph, edge.source, edge.target, graphHeight, false, offset); + const len = Math.hypot(end.x - start.x, end.y - start.y); + return ( + + ); + })} + + ); + })} + + +); + +const AnswerOnlyOverlay: React.FC<{graph: SyntheticGraph; progress: number; graphHeight: number}> = ({ + graph, + progress: p, + graphHeight, +}) => ( + + + +); + +const AnswerCallout: React.FC<{progress: number; label: string; bottom?: number}> = ({progress: p, label, bottom = 58}) => ( +
+ + {label} +
+); + +const GraphPhase: React.FC<{content: Animation3Content; graph: SyntheticGraph}> = ({content, graph}) => { + const frame = useCurrentFrame(); + const headerIn = progress(frame, 6, 36); + const answerIn = progress(frame, 82, 138); + return ( + +
} + progress={headerIn} + /> +
+ 0.25} + overlay={} + /> + +
+ + ); +}; + +const PathPhase: React.FC<{content: Animation3Content; graph: SyntheticGraph}> = ({content, graph}) => { + const frame = useCurrentFrame(); + const headerIn = progress(frame, 6, 34); + const pathsIn = progress(frame, 46, 118); + const legendIn = progress(frame, 80, 136); + const pathGraphHeight = 470; + + return ( + +
} + progress={headerIn} + /> +
+
+ } + /> + +
+
+ {content.syntheticPaths.map((path) => ( +
+
+ + {path.difficulty} +
+ +
+ ))} +
+
+ + ); +}; + +const DataCard: React.FC<{ + question: string; + answer: string; + path: string; + difficulty: string; + progress: number; +}> = ({question, answer, path, difficulty, progress: p}) => ( +
+
+ {difficulty} + +
+
{question}
+
{answer}
+ +
+); + +const DataPhase: React.FC<{content: Animation3Content}> = ({content}) => { + const frame = useCurrentFrame(); + const headerIn = progress(frame, 6, 36); + const cardsIn = progress(frame, 38, 142); + const datasetIn = progress(frame, 138, 206); + + return ( + +
} + progress={headerIn} + /> +
+
+ {content.naturalQACards.map((card, index) => ( + + ))} +
+ +
+
+
+ + {content.labels.syntheticDataset} +
+
+ {content.datasetLabels.map((label, index) => ( + + {label} + + ))} +
+
+
+
+ + ); +}; + +type Animation3Props = { + locale?: Locale; +}; + +export const Animation3_SyntheticData: React.FC = ({locale = 'ru'}) => { + const content = getAnimation3Content(locale); + const nodes = content.syntheticGraphNodes.map((node) => ({ + ...node, + ...(syntheticLayout[node.id] ?? {}), + })); + const graph: SyntheticGraph = { + nodes, + edges: content.syntheticGraphEdges, + paths: content.syntheticPaths, + answerNode: nodes.find((node) => node.id === content.syntheticAnswerNodeId)!, + nodeById: new Map(nodes.map((node) => [node.id, node])), + edgeById: new Map(content.syntheticGraphEdges.map((edge) => [edge.id, edge])), + }; + return ( + + + + + + + + + + + + ); +}; diff --git a/wikontic-demo-animation/src/styles/global.css b/wikontic-demo-animation/src/styles/global.css new file mode 100644 index 0000000..08e4d23 --- /dev/null +++ b/wikontic-demo-animation/src/styles/global.css @@ -0,0 +1,1416 @@ +* { + box-sizing: border-box; +} + +html, +body, +#root { + margin: 0; + min-height: 100%; + font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; + color: #172033; + background: #f7f9fc; +} + +.scene { + position: relative; + width: 100%; + height: 100%; + padding: 56px 86px 54px; + overflow: hidden; + background: + radial-gradient(circle at 82% 18%, rgba(47, 109, 246, 0.08), transparent 28%), + linear-gradient(180deg, #fbfcff 0%, #f4f7fb 100%); +} + +.gridTexture { + position: absolute; + inset: 0; + pointer-events: none; + background-image: + linear-gradient(rgba(23, 32, 51, 0.035) 1px, transparent 1px), + linear-gradient(90deg, rgba(23, 32, 51, 0.035) 1px, transparent 1px); + background-size: 42px 42px; + mask-image: linear-gradient(180deg, transparent 0%, #000 15%, #000 86%, transparent 100%); +} + +.cornerMark { + position: absolute; + right: 58px; + bottom: 58px; + width: 132px; + height: 132px; + border-right: 4px solid; + border-bottom: 4px solid; + opacity: 0.8; +} + +.sceneHeader { + position: relative; + z-index: 2; + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 48px; + margin-bottom: 40px; +} + +.sceneHeader h1 { + margin: 0; + max-width: 1700px; + font-size: 44px; + line-height: 1.1; + font-weight: 760; + letter-spacing: 0; +} + +.sceneHeader p { + margin: 18px 0 0; + max-width: 1020px; + font-size: 29px; + line-height: 1.3; + color: #647084; +} + +.eyebrow { + margin-bottom: 14px; + font-size: 20px; + letter-spacing: 0.08em; + text-transform: uppercase; + color: #2f6df6; + font-weight: 760; +} + +.frameLabel { + min-width: 238px; + padding: 15px 20px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: rgba(255, 255, 255, 0.82); + color: #647084; + font-size: 22px; + text-align: center; +} + +.sceneBody { + position: relative; + z-index: 2; + height: 650px; +} + +.panel { + position: relative; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: rgba(255, 255, 255, 0.92); + box-shadow: 0 24px 70px rgba(23, 32, 51, 0.1); + overflow: hidden; +} + +.documentPanel { + width: 720px; + min-height: 570px; + padding: 34px 40px 42px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 24px 70px rgba(23, 32, 51, 0.12); +} + +.docTop { + display: flex; + align-items: center; + gap: 10px; + height: 36px; + color: #8b98aa; + font-size: 18px; + border-bottom: 1px solid #edf1f6; + padding-bottom: 20px; + margin-bottom: 26px; +} + +.docDot { + width: 12px; + height: 12px; + border-radius: 999px; + background: #dbe3ef; +} + +.docTitle { + margin-bottom: 26px; + font-size: 31px; + font-weight: 760; +} + +.documentPanel p { + margin: 0 0 25px; + font-size: 27px; + line-height: 1.58; + color: #172033; + transition: opacity 0.2s, transform 0.2s; +} + +.docHighlight { + border-radius: 6px; + padding: 2px 5px; + box-decoration-break: clone; + -webkit-box-decoration-break: clone; +} + +.hlBlue { + background: #dbe8ff; + color: #1748b5; +} + +.hlGreen { + background: #dff8ec; + color: #08724d; +} + +.hlAmber { + background: #fff2cc; + color: #8a5c00; +} + +.hlViolet { + background: #eee9ff; + color: #5637c8; +} + +.tripletCard { + width: 770px; + padding: 22px 24px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 18px 44px rgba(23, 32, 51, 0.1); +} + +.tripletCompact { + width: 700px; + padding: 18px 20px; +} + +.tripletRow { + display: grid; + grid-template-columns: 1fr auto 1fr; + align-items: center; + gap: 18px; + font-size: 23px; + font-weight: 700; +} + +.tripletRow > span:not(.tripletRelation) { + min-width: 0; + padding: 11px 15px; + border-radius: 7px; + background: #f4f7fb; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + text-align: center; +} + +.tripletRelation { + display: inline-flex; + align-items: center; + gap: 8px; + color: #2f6df6; + font-weight: 760; + white-space: nowrap; +} + +.qualifier { + display: inline-flex; + align-items: center; + gap: 8px; + margin-top: 14px; + padding: 7px 10px; + border-radius: 6px; + background: #fff2cc; + color: #8a5c00; + font-size: 18px; + font-weight: 680; +} + +.graphSvg { + width: 100%; + height: 100%; + overflow: visible; + border-radius: 8px; + box-shadow: 0 14px 38px rgba(23, 32, 51, 0.05); +} + +.nodeLabel { + font-size: 22px; + font-weight: 760; + fill: #172033; + dominant-baseline: middle; +} + +.nodeType { + font-size: 15px; + font-weight: 700; + fill: #4a5568; + dominant-baseline: middle; +} + +.edgeLabel { + font-size: 17px; + font-weight: 760; + dominant-baseline: middle; +} + +.ontologyLayer { + padding: 24px; + border: 1px solid #cbd9ff; + border-radius: 8px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(238, 244, 255, 0.92)); + box-shadow: 0 20px 50px rgba(47, 109, 246, 0.14); +} + +.ontologyHeader { + display: flex; + align-items: center; + gap: 12px; + color: #1748b5; + font-size: 26px; + font-weight: 780; +} + +.ontologyRules { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 12px; + margin-top: 18px; +} + +.ontologyRules span { + padding: 12px; + border-radius: 7px; + background: #ffffff; + color: #647084; + font-size: 18px; + font-weight: 700; + text-align: center; +} + +.scannerTrack { + position: relative; + height: 18px; + margin: 24px 0; + border-radius: 999px; + background: #dbe8ff; + overflow: hidden; +} + +.scannerBeam { + position: absolute; + top: -18px; + width: 42px; + height: 54px; + border-radius: 999px; + background: #2f6df6; + box-shadow: 0 0 34px rgba(47, 109, 246, 0.75); +} + +.ontologyChecks { + display: grid; + gap: 10px; + color: #08724d; + font-size: 18px; + font-weight: 700; +} + +.ontologyChecks div { + display: flex; + align-items: center; + gap: 9px; +} + +.metricBadge { + display: grid; + gap: 3px; + min-width: 220px; + padding: 15px 18px; + border-radius: 8px; + border: 1px solid #dbe3ef; + background: rgba(255, 255, 255, 0.86); +} + +.metricBadge strong { + font-size: 30px; + line-height: 1; +} + +.metricBadge span { + font-size: 16px; + color: #647084; + font-weight: 680; +} + +.metric-blue strong { + color: #2f6df6; +} + +.metric-green strong { + color: #19a974; +} + +.metric-amber strong { + color: #8a5c00; +} + +.pipelinePill { + display: inline-flex; + align-items: center; + gap: 9px; + padding: 12px 15px; + border-radius: 8px; + border: 1px solid #dbe3ef; + background: rgba(255, 255, 255, 0.88); + color: #647084; + font-size: 18px; + font-weight: 740; +} + +.ragCompare { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 28px; + height: 100%; +} + +.compareColumn { + padding: 28px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; +} + +.compareColumn h3 { + margin: 0 0 20px; + font-size: 30px; +} + +.chunk { + margin: 14px 0; + padding: 17px 18px; + border-radius: 7px; + background: #f4f7fb; + color: #647084; + font-size: 20px; + line-height: 1.35; +} + +.answerBox { + padding: 24px 28px; + border-radius: 8px; + background: #dff8ec; + border: 1px solid rgba(25, 169, 116, 0.35); + color: #08724d; + font-size: 29px; + line-height: 1.32; + font-weight: 760; +} + +.syntheticCard { + width: 390px; + min-height: 118px; + padding: 18px 20px; + border-radius: 8px; + border: 1px solid #dbe3ef; + background: #ffffff; + box-shadow: 0 18px 40px rgba(23, 32, 51, 0.1); +} + +.syntheticCard strong { + display: block; + margin-bottom: 8px; + color: #2f6df6; + font-size: 18px; +} + +.syntheticCard span { + font-size: 21px; + line-height: 1.28; + color: #172033; + font-weight: 680; +} + +.smallModel { + width: 290px; + height: 290px; + border-radius: 8px; + border: 1px solid #cbd9ff; + background: linear-gradient(180deg, #ffffff, #eef4ff); + display: grid; + place-items: center; + text-align: center; + color: #1748b5; + font-size: 28px; + font-weight: 800; + box-shadow: 0 22px 50px rgba(47, 109, 246, 0.14); +} + +.interactivePage { + min-height: 100vh; + padding: 38px; + background: #f7f9fc; +} + +.interactiveHeader { + display: flex; + align-items: center; + gap: 18px; + margin-bottom: 28px; +} + +.interactiveHeader img { + width: 50px; + height: 50px; +} + +.interactiveHeader h1 { + margin: 0; + font-size: 34px; +} + +.interactiveGrid { + display: grid; + grid-template-columns: minmax(760px, 1fr) 420px; + gap: 24px; + align-items: start; +} + +.sidePanel { + padding: 24px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 18px 48px rgba(23, 32, 51, 0.08); +} + +.sidePanel h2 { + margin: 0 0 12px; +} + +.sidePanel p { + margin: 10px 0; + color: #647084; + line-height: 1.45; +} + +.sidePanel button { + width: 100%; + margin-top: 16px; + padding: 12px 14px; + border: 0; + border-radius: 7px; + background: #2f6df6; + color: #ffffff; + font: inherit; + font-weight: 760; + cursor: pointer; +} + +.documentView { + width: 760px; + min-height: 500px; + padding: 30px 36px 34px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 28px 75px rgba(23, 32, 51, 0.13); + transform-origin: 48% 32%; +} + +.documentToolbar { + display: flex; + align-items: center; + gap: 10px; + padding-bottom: 18px; + border-bottom: 1px solid #edf1f6; + color: #647084; + font-size: 20px; + font-weight: 720; +} + +.documentHeading { + margin: 24px 0 20px; + font-size: 30px; + font-weight: 780; +} + +.documentText p { + margin: 0 0 22px; + font-size: 28px; + line-height: 1.55; +} + +.docMutedText { + opacity: 0.16; + filter: blur(1.6px); +} + +.highlightedFact { + max-width: 520px; + padding: 14px 18px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 15px 36px rgba(23, 32, 51, 0.1); + font-size: 21px; + line-height: 1.24; + font-weight: 750; +} + +.highlightedFactCompact { + font-size: 18px; + padding: 10px 13px; +} + +.fact-blue { + border-color: #cbd9ff; + color: #1748b5; + background: #eef4ff; +} + +.fact-green { + border-color: rgba(25, 169, 116, 0.32); + color: #08724d; + background: #dff8ec; +} + +.fact-amber { + border-color: rgba(242, 169, 0, 0.34); + color: #8a5c00; + background: #fff2cc; +} + +.fact-violet { + border-color: rgba(122, 92, 255, 0.34); + color: #5637c8; + background: #eee9ff; +} + +.methodStage { + position: relative; + height: 100%; +} + +.methodDocumentSlot { + position: absolute; + left: 0; + top: 22px; +} + +.floatingFacts { + position: absolute; + left: 820px; + top: 26px; + display: grid; + gap: 14px; +} + +.methodTriplets { + position: absolute; + left: 840px; + top: 12px; + display: grid; + gap: 12px; +} + +.methodOntology { + position: absolute; + right: 8px; + top: 24px; + width: 740px; +} + +.methodDedup { + position: absolute; + right: 8px; + top: 24px; + width: 760px; +} + +.methodFinalGraph { + position: absolute; + inset: 0; +} + +.methodFinalLayout { + width: 1704px; + max-width: 100%; + height: 820px; + margin: 0 auto; + display: grid; + grid-template-columns: 1380px 300px; + gap: 24px; + align-items: start; +} + +.finalGraphPanel { + width: 1380px; + height: 820px; + margin: 0; + padding: 24px; +} + +.finalComparisonPanel { + padding: 22px 24px 112px; +} + +.finalComparisonGrid { + display: grid; + grid-template-columns: 430px 1fr; + gap: 30px; + height: 100%; +} + +.finalDocumentPanel, +.finalGraphColumn { + min-width: 0; +} + +.compactTitleRow { + margin-bottom: 10px; + font-size: 21px; +} + +.finalDocumentCompact { + overflow: hidden; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; +} + +.finalDocumentCompact .documentView { + width: auto; + min-height: 0; + padding: 20px 22px 24px; + border: 0; + border-radius: 0; + box-shadow: none; + transform: none !important; +} + +.finalDocumentCompact .documentToolbar { + padding-bottom: 11px; + font-size: 15px; +} + +.finalDocumentCompact .documentHeading { + margin: 14px 0 12px; + font-size: 19px; +} + +.finalDocumentCompact .documentText p { + margin: 0 0 13px; + font-size: 17px; + line-height: 1.48; +} + +.finalGraphPanel .graphSvg { + height: 460px; + box-shadow: none; +} + +.finalGraphColumn .graphSvg { + height: 470px; +} + +.panelTitleRow { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 14px; + color: #1748b5; + font-size: 24px; + font-weight: 780; +} + +.metricRow { + position: absolute; + right: 24px; + bottom: 20px; + display: flex; + gap: 12px; +} + +.metricTransform { + position: absolute; + left: 50%; + bottom: 18px; + display: grid; + grid-template-columns: minmax(300px, auto) 58px minmax(340px, auto); + align-items: center; + gap: 12px; + transform: translateX(-50%); + padding: 12px 16px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: rgba(255, 255, 255, 0.94); + box-shadow: 0 18px 44px rgba(23, 32, 51, 0.1); +} + +.finalComparisonPanel .metricTransform { + left: 24px; + right: 24px; + grid-template-columns: 430px 30px 1fr; + gap: 0; + transform: none; +} + +.finalComparisonPanel .metricBefore { + justify-self: center; +} + +.finalComparisonPanel .metricAfter { + justify-self: center; +} + +.finalComparisonPanel .metricTransformArrow { + justify-self: center; +} + +.finalGraphBenefits { + align-self: center; + display: grid; + gap: 14px; +} + +.finalGraphBenefit { + display: grid; + grid-template-columns: 24px 1fr; + align-items: center; + gap: 12px; + min-height: 72px; + padding: 16px 18px; + border: 1px solid #cbd9ff; + border-radius: 8px; + background: rgba(255, 255, 255, 0.94); + color: #1748b5; + font-size: 24px; + line-height: 1.14; + font-weight: 820; + box-shadow: 0 18px 44px rgba(23, 32, 51, 0.1); +} + +.finalGraphBenefit svg { + color: #19a974; +} + +.metricTransformBlock { + display: grid; + grid-template-columns: auto auto auto; + align-items: baseline; + gap: 8px; + min-height: 62px; + padding: 10px 14px; + border-radius: 8px; + white-space: nowrap; +} + +.metricTransformBlock span { + color: #647084; + font-size: 18px; + font-weight: 760; +} + +.metricTransformBlock strong { + font-size: 36px; + line-height: 1; + font-weight: 830; +} + +.metricTransformBlock em { + color: #647084; + font-size: 18px; + font-style: normal; + font-weight: 720; +} + +.metricBefore { + background: #fff2cc; + border: 1px solid rgba(242, 169, 0, 0.38); +} + +.metricBefore strong { + color: #8a5c00; +} + +.metricAfter { + grid-template-columns: auto auto; + background: #dff8ec; + border: 1px solid rgba(25, 169, 116, 0.34); +} + +.metricAfter strong { + color: #08724d; +} + +.structuredMetrics { + display: grid; + grid-template-columns: auto auto auto auto; + align-items: baseline; + gap: 8px; +} + +.metricTransformArrow { + color: #2f6df6; + font-size: 43px; + line-height: 1; + font-weight: 820; + text-align: center; +} + +.ontologyPass { + position: relative; + padding: 24px; + border: 1px solid #cbd9ff; + border-radius: 8px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(238, 244, 255, 0.94)); + box-shadow: 0 22px 58px rgba(47, 109, 246, 0.14); + overflow: hidden; +} + +.ontologyGrid { + display: grid; + gap: 13px; + margin-top: 18px; +} + +.ontologyRow { + display: grid; + grid-template-columns: 1fr 1fr auto; + align-items: center; + gap: 14px; + min-height: 62px; + padding: 14px 16px; + border: 1px solid; + border-radius: 8px; + background: rgba(255, 255, 255, 0.92); + transition: opacity 0.2s, transform 0.2s; +} + +.ontologyRow span { + color: #647084; + font-size: 18px; + font-weight: 690; +} + +.ontologyRow strong { + color: #172033; + font-size: 20px; + line-height: 1.2; +} + +.ontologyScanner { + position: absolute; + top: 0; + width: 52px; + height: 100%; + border-radius: 999px; + background: rgba(47, 109, 246, 0.1); + box-shadow: 0 0 45px rgba(47, 109, 246, 0.42); +} + +.dedupPanel { + padding: 22px; + border: 1px solid rgba(25, 169, 116, 0.3); + border-radius: 8px; + background: rgba(255, 255, 255, 0.95); + box-shadow: 0 24px 64px rgba(23, 32, 51, 0.12); +} + +.dedupHeader { + display: flex; + align-items: center; + gap: 10px; + color: #08724d; + font-size: 24px; + font-weight: 780; +} + +.dedupSvg { + width: 100%; + height: 430px; +} + +.mergeAlias, +.mergeCanonical, +.mergeFooter { + font-size: 22px; + font-weight: 780; + fill: #172033; +} + +.mergeTags { + font-size: 15px; + font-weight: 720; + fill: #647084; +} + +.ragQuestionWrap { + position: absolute; + top: -8px; + left: 0; + right: 0; + z-index: 4; + display: flex; + align-items: center; + gap: 14px; + width: fit-content; + max-width: 1160px; + margin: 0 auto; + padding: 18px 24px; + border: 1px solid #cbd9ff; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 18px 50px rgba(23, 32, 51, 0.12); + color: #172033; + font-size: 31px; + font-weight: 780; +} + +.comparisonGrid { + display: grid; + grid-template-columns: 0.88fr 1.12fr; + gap: 28px; + height: 100%; + padding-top: 86px; +} + +.comparisonPanel { + padding: 24px; + min-height: 548px; +} + +.comparisonHeader { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 18px; + font-size: 28px; + font-weight: 820; +} + +.ragHeader { + color: #647084; +} + +.wikonticHeader { + color: #1748b5; +} + +.chunkStack { + display: grid; + gap: 13px; +} + +.ragChunk { + padding: 16px 18px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #f8fafc; +} + +.ragChunk strong { + display: block; + margin-bottom: 6px; + color: #647084; + font-size: 17px; +} + +.ragChunk p { + margin: 0; + color: #172033; + font-size: 21px; + line-height: 1.28; + font-weight: 680; +} + +.ragNote { + display: flex; + align-items: center; + gap: 9px; + margin-top: 16px; + padding: 13px 15px; + border-radius: 8px; + background: #fff2cc; + color: #8a5c00; + font-size: 19px; + font-weight: 760; +} + +.wikonticPanel .graphSvg { + height: 470px; + box-shadow: none; +} + +.internalPath { + margin-top: 12px; + padding: 12px 14px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; +} + +.internalPathLabel { + margin-bottom: 7px; + color: #647084; + font-size: 15px; + font-weight: 760; + text-transform: uppercase; + letter-spacing: 0.04em; +} + +.pathHighlight { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px; + font-size: 19px; + line-height: 1.25; + font-weight: 760; +} + +.pathHighlightCompact { + gap: 6px; + font-size: 14px; +} + +.pathNode { + padding: 6px 8px; + border-radius: 7px; + background: #eef4ff; + color: #1748b5; +} + +.pathRelation { + color: #08724d; +} + +.pathArrow { + color: #8b98aa; + font-weight: 780; +} + +.answerOverlay { + position: absolute; + left: 235px; + right: 235px; + bottom: 0; + z-index: 7; + padding: 22px 28px; + border: 1px solid rgba(25, 169, 116, 0.34); + border-radius: 8px; + background: rgba(255, 255, 255, 0.98); + box-shadow: 0 24px 68px rgba(23, 32, 51, 0.18); +} + +.answerOverlay strong { + color: #08724d; + font-size: 20px; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.answerOverlay p { + margin: 8px 0 10px; + font-size: 29px; + line-height: 1.25; + font-weight: 790; +} + +.answerOverlay div { + color: #647084; + font-size: 22px; + font-weight: 720; +} + +.syntheticStage { + display: grid; + grid-template-columns: 0.95fr 1.05fr; + gap: 28px; + height: 100%; +} + +.syntheticGraphPanel { + position: relative; + padding: 24px; +} + +.syntheticGraphPanel .graphSvg { + height: 560px; + box-shadow: none; +} + +.selectedAnswer { + position: absolute; + left: 28px; + bottom: 28px; + display: flex; + align-items: center; + gap: 9px; + padding: 11px 13px; + border-radius: 8px; + background: #eee9ff; + color: #5637c8; + font-size: 20px; + font-weight: 770; +} + +.syntheticRightRail { + position: relative; + min-height: 650px; +} + +.pathSampler { + padding: 20px; +} + +.sampledPath { + margin-top: 11px; + padding: 12px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; +} + +.sampledPath strong { + display: inline-flex; + margin-bottom: 7px; + padding: 5px 9px; + border-radius: 7px; + background: #eee9ff; + color: #5637c8; + font-size: 16px; +} + +.qaCardRail { + position: absolute; + inset: 0; + display: grid; + gap: 12px; +} + +.datasetCard { + padding: 14px 16px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 16px 42px rgba(23, 32, 51, 0.1); +} + +.datasetCardTop { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 8px; + color: #5637c8; + font-size: 16px; + font-weight: 820; +} + +.datasetQuestion { + margin-bottom: 8px; + color: #172033; + font-size: 22px; + line-height: 1.2; + font-weight: 780; +} + +.datasetAnswer { + margin-bottom: 10px; + color: #08724d; + font-size: 19px; + font-weight: 760; +} + +.datasetAssembly { + position: absolute; + left: 0; + right: 0; + bottom: 0; + display: grid; + grid-template-columns: 1fr auto 270px; + align-items: center; + gap: 18px; +} + +.datasetStackPanel { + padding: 18px; +} + +.datasetLabelGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 10px; +} + +.datasetLabelGrid span { + padding: 11px 12px; + border-radius: 7px; + background: #f4f7fb; + color: #172033; + font-size: 17px; + font-weight: 760; + text-align: center; +} + +.datasetArrow { + color: #2f6df6; +} + +.smallModel { + width: 270px; + height: 164px; + padding: 18px; + border-radius: 8px; + border: 1px solid #cbd9ff; + background: linear-gradient(180deg, #ffffff, #eef4ff); + display: grid; + place-items: center; + gap: 8px; + text-align: center; + color: #1748b5; + font-size: 22px; + font-weight: 800; + box-shadow: 0 18px 44px rgba(47, 109, 246, 0.14); +} + +.syntheticHeroCards { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 22px; + align-items: start; +} + +.syntheticGraphOverlay { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + overflow: visible; + pointer-events: none; +} + +.syntheticPathGrid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 14px; + align-items: stretch; +} + +.syntheticPathCard { + min-height: 118px; + padding: 16px 18px; + border: 2px solid #dbe3ef; + border-radius: 8px; + background: rgba(255, 255, 255, 0.98); + box-shadow: 0 18px 46px rgba(23, 32, 51, 0.1); +} + +.syntheticPathCardTop { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 10px; +} + +.syntheticPathCardTop span { + width: 17px; + height: 17px; + border-radius: 999px; + flex-shrink: 0; +} + +.syntheticPathCardTop strong { + color: #172033; + font-size: 22px; + font-weight: 850; +} + +.syntheticHeroCard { + min-height: 360px; + padding: 24px 26px; + border: 1px solid #dbe3ef; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 22px 58px rgba(23, 32, 51, 0.12); +} + +.syntheticHeroCardTop { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 18px; + color: #5637c8; + font-size: 22px; + font-weight: 850; +} + +.syntheticHeroQuestion { + min-height: 96px; + margin-bottom: 18px; + color: #172033; + font-size: 29px; + line-height: 1.18; + font-weight: 830; +} + +.syntheticHeroAnswer { + margin-bottom: 18px; + color: #08724d; + font-size: 25px; + font-weight: 800; +} + +.syntheticDatasetFlow { + position: absolute; + left: 50%; + bottom: 24px; + width: min(980px, calc(100% - 96px)); + display: flex; + justify-content: center; + align-items: center; +} + +.syntheticDatasetStack { + width: 100%; + max-width: 900px; + padding: 28px 30px; + border: 1px solid #cbd9ff; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 22px 58px rgba(23, 32, 51, 0.12); +} + +.syntheticDatasetTitle { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 18px; + color: #1748b5; + font-size: 30px; + font-weight: 840; +} + +.syntheticDatasetLabels { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 12px; +} + +.syntheticDatasetLabels span { + padding: 14px 16px; + border-radius: 8px; + background: #f4f7fb; + color: #172033; + font-size: 20px; + font-weight: 780; + text-align: center; +} diff --git a/wikontic-demo-animation/src/theme.ts b/wikontic-demo-animation/src/theme.ts new file mode 100644 index 0000000..dfaf35c --- /dev/null +++ b/wikontic-demo-animation/src/theme.ts @@ -0,0 +1,41 @@ +export const VIDEO_WIDTH = 1920; +export const VIDEO_HEIGHT = 1080; +export const FPS = 30; +export const DURATION_IN_FRAMES = 2700; + +export const colors = { + background: '#f7f9fc', + panel: '#ffffff', + panelAlt: '#eef4ff', + ink: '#172033', + muted: '#647084', + faint: '#dbe3ef', + blue: '#2f6df6', + blueDark: '#1748b5', + blueSoft: '#dbe8ff', + green: '#19a974', + greenSoft: '#dff8ec', + amber: '#f2a900', + amberSoft: '#fff2cc', + red: '#d84d4d', + redSoft: '#ffe1e1', + violet: '#7a5cff', + violetSoft: '#eee9ff', + steel: '#8b98aa', +}; + +export const font = { + family: + 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif', +}; + +export const sceneFrames = { + intro: {from: 0, duration: 300}, + extraction: {from: 300, duration: 360}, + dirtyGraph: {from: 660, duration: 300}, + ontology: {from: 960, duration: 450}, + normalization: {from: 1410, duration: 360}, + qa: {from: 1770, duration: 480}, + synthetic: {from: 2250, duration: 300}, + finale: {from: 2550, duration: 150}, +}; diff --git a/wikontic-demo-animation/tsconfig.json b/wikontic-demo-animation/tsconfig.json new file mode 100644 index 0000000..c0ea4e1 --- /dev/null +++ b/wikontic-demo-animation/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ES2022"], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": ["src"] +} diff --git a/wikontic-demo-animation/vite.config.ts b/wikontic-demo-animation/vite.config.ts new file mode 100644 index 0000000..2615a0d --- /dev/null +++ b/wikontic-demo-animation/vite.config.ts @@ -0,0 +1,9 @@ +import {defineConfig} from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + server: { + port: 5173, + }, +});