From 39c0f7e70825705f58998b8c8a737bc096c913eb Mon Sep 17 00:00:00 2001 From: yinsx Date: Sat, 13 Dec 2025 15:40:01 +0800 Subject: [PATCH] init --- .claude/settings.local.json | 16 + .gitignore | 1 + .vscode/settings.json | 3 + backend/.env.example | 2 + backend/bun.lock | 197 ++ backend/flow.db | Bin 0 -> 28672 bytes backend/package.json | 12 + backend/src/db.ts | 25 + backend/src/executors/base.ts | 7 + backend/src/executors/index.ts | 14 + backend/src/executors/llm.ts | 20 + backend/src/index.ts | 101 + backend/src/services/executor.ts | 73 + backend/src/services/socket.ts | 25 + flow.md | 40 + frontend/index.html | 12 + frontend/package-lock.json | 3070 +++++++++++++++++ frontend/package.json | 31 + frontend/src/App.vue | 498 +++ frontend/src/api/index.ts | 23 + frontend/src/assets/main.css | 54 + frontend/src/components/ContextMenu.vue | 62 + frontend/src/components/ContextMenuList.vue | 187 + frontend/src/components/PropertyPanel.vue | 70 + .../nodes/AggregationNode/index.scss | 3 + .../components/nodes/AggregationNode/index.ts | 1 + .../nodes/AggregationNode/index.vue | 46 + .../components/nodes/AggregationNode/types.ts | 10 + .../nodes/ConditionalNode/index.scss | 3 + .../components/nodes/ConditionalNode/index.ts | 1 + .../nodes/ConditionalNode/index.vue | 46 + .../components/nodes/ConditionalNode/types.ts | 11 + .../components/nodes/ContainerNode/index.scss | 91 + .../components/nodes/ContainerNode/index.ts | 1 + .../components/nodes/ContainerNode/index.vue | 123 + .../components/nodes/ContainerNode/types.ts | 16 + .../components/nodes/DataInputNode/index.scss | 3 + .../components/nodes/DataInputNode/index.ts | 1 + .../components/nodes/DataInputNode/index.vue | 45 + .../components/nodes/DataInputNode/types.ts | 10 + .../nodes/DataOutputNode/index.scss | 3 + .../components/nodes/DataOutputNode/index.ts | 1 + .../components/nodes/DataOutputNode/index.vue | 45 + .../components/nodes/DataOutputNode/types.ts | 10 + .../nodes/DataTransferNode/index.scss | 3 + .../nodes/DataTransferNode/index.ts | 1 + .../nodes/DataTransferNode/index.vue | 46 + .../nodes/DataTransferNode/types.ts | 10 + .../src/components/nodes/DelayNode/index.scss | 3 + .../src/components/nodes/DelayNode/index.ts | 1 + .../src/components/nodes/DelayNode/index.vue | 46 + .../src/components/nodes/DelayNode/types.ts | 9 + .../src/components/nodes/HttpNode/index.scss | 11 + .../src/components/nodes/HttpNode/index.ts | 1 + .../src/components/nodes/HttpNode/index.vue | 53 + .../src/components/nodes/HttpNode/types.ts | 9 + .../src/components/nodes/ImageNode/index.scss | 3 + .../src/components/nodes/ImageNode/index.ts | 1 + .../src/components/nodes/ImageNode/index.vue | 46 + .../src/components/nodes/ImageNode/types.ts | 9 + .../components/nodes/IntentNode/index.scss | 3 + .../src/components/nodes/IntentNode/index.ts | 1 + .../src/components/nodes/IntentNode/index.vue | 46 + .../src/components/nodes/IntentNode/types.ts | 10 + .../src/components/nodes/LLMNode/index.scss | 3 + .../src/components/nodes/LLMNode/index.ts | 1 + .../src/components/nodes/LLMNode/index.vue | 46 + .../src/components/nodes/LLMNode/types.ts | 9 + .../src/components/nodes/LoopNode/index.scss | 3 + .../src/components/nodes/LoopNode/index.ts | 1 + .../src/components/nodes/LoopNode/index.vue | 46 + .../src/components/nodes/LoopNode/types.ts | 10 + .../src/components/nodes/MCPNode/index.scss | 3 + .../src/components/nodes/MCPNode/index.ts | 1 + .../src/components/nodes/MCPNode/index.vue | 46 + .../src/components/nodes/MCPNode/types.ts | 9 + .../components/nodes/ScriptNode/index.scss | 3 + .../src/components/nodes/ScriptNode/index.ts | 1 + .../src/components/nodes/ScriptNode/index.vue | 46 + .../src/components/nodes/ScriptNode/types.ts | 10 + .../src/components/nodes/UdpNode/index.scss | 3 + .../src/components/nodes/UdpNode/index.ts | 1 + .../src/components/nodes/UdpNode/index.vue | 46 + .../src/components/nodes/UdpNode/types.ts | 9 + .../components/nodes/WebhookNode/index.scss | 3 + .../src/components/nodes/WebhookNode/index.ts | 1 + .../components/nodes/WebhookNode/index.vue | 46 + .../src/components/nodes/WebhookNode/types.ts | 10 + frontend/src/components/nodes/index.ts | 36 + .../components/nodes/shared/StandardNode.vue | 95 + .../nodes/shared/standard-node.scss | 114 + frontend/src/components/nodes/shared/types.ts | 42 + .../nodes/shared/useStandardNode.ts | 28 + frontend/src/data/nodeCatalog.ts | 197 ++ frontend/src/main.ts | 19 + frontend/src/stores/flow.ts | 161 + frontend/src/types/context-menu.ts | 8 + frontend/src/vite-env.d.ts | 6 + frontend/tsconfig.json | 18 + frontend/tsconfig.node.json | 10 + frontend/vite.config.ts | 26 + run.bat | 11 + start.bat | 7 + 编排.png | Bin 0 -> 130607 bytes 104 files changed, 6460 insertions(+) create mode 100644 .claude/settings.local.json create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 backend/.env.example create mode 100644 backend/bun.lock create mode 100644 backend/flow.db create mode 100644 backend/package.json create mode 100644 backend/src/db.ts create mode 100644 backend/src/executors/base.ts create mode 100644 backend/src/executors/index.ts create mode 100644 backend/src/executors/llm.ts create mode 100644 backend/src/index.ts create mode 100644 backend/src/services/executor.ts create mode 100644 backend/src/services/socket.ts create mode 100644 flow.md create mode 100644 frontend/index.html create mode 100644 frontend/package-lock.json create mode 100644 frontend/package.json create mode 100644 frontend/src/App.vue create mode 100644 frontend/src/api/index.ts create mode 100644 frontend/src/assets/main.css create mode 100644 frontend/src/components/ContextMenu.vue create mode 100644 frontend/src/components/ContextMenuList.vue create mode 100644 frontend/src/components/PropertyPanel.vue create mode 100644 frontend/src/components/nodes/AggregationNode/index.scss create mode 100644 frontend/src/components/nodes/AggregationNode/index.ts create mode 100644 frontend/src/components/nodes/AggregationNode/index.vue create mode 100644 frontend/src/components/nodes/AggregationNode/types.ts create mode 100644 frontend/src/components/nodes/ConditionalNode/index.scss create mode 100644 frontend/src/components/nodes/ConditionalNode/index.ts create mode 100644 frontend/src/components/nodes/ConditionalNode/index.vue create mode 100644 frontend/src/components/nodes/ConditionalNode/types.ts create mode 100644 frontend/src/components/nodes/ContainerNode/index.scss create mode 100644 frontend/src/components/nodes/ContainerNode/index.ts create mode 100644 frontend/src/components/nodes/ContainerNode/index.vue create mode 100644 frontend/src/components/nodes/ContainerNode/types.ts create mode 100644 frontend/src/components/nodes/DataInputNode/index.scss create mode 100644 frontend/src/components/nodes/DataInputNode/index.ts create mode 100644 frontend/src/components/nodes/DataInputNode/index.vue create mode 100644 frontend/src/components/nodes/DataInputNode/types.ts create mode 100644 frontend/src/components/nodes/DataOutputNode/index.scss create mode 100644 frontend/src/components/nodes/DataOutputNode/index.ts create mode 100644 frontend/src/components/nodes/DataOutputNode/index.vue create mode 100644 frontend/src/components/nodes/DataOutputNode/types.ts create mode 100644 frontend/src/components/nodes/DataTransferNode/index.scss create mode 100644 frontend/src/components/nodes/DataTransferNode/index.ts create mode 100644 frontend/src/components/nodes/DataTransferNode/index.vue create mode 100644 frontend/src/components/nodes/DataTransferNode/types.ts create mode 100644 frontend/src/components/nodes/DelayNode/index.scss create mode 100644 frontend/src/components/nodes/DelayNode/index.ts create mode 100644 frontend/src/components/nodes/DelayNode/index.vue create mode 100644 frontend/src/components/nodes/DelayNode/types.ts create mode 100644 frontend/src/components/nodes/HttpNode/index.scss create mode 100644 frontend/src/components/nodes/HttpNode/index.ts create mode 100644 frontend/src/components/nodes/HttpNode/index.vue create mode 100644 frontend/src/components/nodes/HttpNode/types.ts create mode 100644 frontend/src/components/nodes/ImageNode/index.scss create mode 100644 frontend/src/components/nodes/ImageNode/index.ts create mode 100644 frontend/src/components/nodes/ImageNode/index.vue create mode 100644 frontend/src/components/nodes/ImageNode/types.ts create mode 100644 frontend/src/components/nodes/IntentNode/index.scss create mode 100644 frontend/src/components/nodes/IntentNode/index.ts create mode 100644 frontend/src/components/nodes/IntentNode/index.vue create mode 100644 frontend/src/components/nodes/IntentNode/types.ts create mode 100644 frontend/src/components/nodes/LLMNode/index.scss create mode 100644 frontend/src/components/nodes/LLMNode/index.ts create mode 100644 frontend/src/components/nodes/LLMNode/index.vue create mode 100644 frontend/src/components/nodes/LLMNode/types.ts create mode 100644 frontend/src/components/nodes/LoopNode/index.scss create mode 100644 frontend/src/components/nodes/LoopNode/index.ts create mode 100644 frontend/src/components/nodes/LoopNode/index.vue create mode 100644 frontend/src/components/nodes/LoopNode/types.ts create mode 100644 frontend/src/components/nodes/MCPNode/index.scss create mode 100644 frontend/src/components/nodes/MCPNode/index.ts create mode 100644 frontend/src/components/nodes/MCPNode/index.vue create mode 100644 frontend/src/components/nodes/MCPNode/types.ts create mode 100644 frontend/src/components/nodes/ScriptNode/index.scss create mode 100644 frontend/src/components/nodes/ScriptNode/index.ts create mode 100644 frontend/src/components/nodes/ScriptNode/index.vue create mode 100644 frontend/src/components/nodes/ScriptNode/types.ts create mode 100644 frontend/src/components/nodes/UdpNode/index.scss create mode 100644 frontend/src/components/nodes/UdpNode/index.ts create mode 100644 frontend/src/components/nodes/UdpNode/index.vue create mode 100644 frontend/src/components/nodes/UdpNode/types.ts create mode 100644 frontend/src/components/nodes/WebhookNode/index.scss create mode 100644 frontend/src/components/nodes/WebhookNode/index.ts create mode 100644 frontend/src/components/nodes/WebhookNode/index.vue create mode 100644 frontend/src/components/nodes/WebhookNode/types.ts create mode 100644 frontend/src/components/nodes/index.ts create mode 100644 frontend/src/components/nodes/shared/StandardNode.vue create mode 100644 frontend/src/components/nodes/shared/standard-node.scss create mode 100644 frontend/src/components/nodes/shared/types.ts create mode 100644 frontend/src/components/nodes/shared/useStandardNode.ts create mode 100644 frontend/src/data/nodeCatalog.ts create mode 100644 frontend/src/main.ts create mode 100644 frontend/src/stores/flow.ts create mode 100644 frontend/src/types/context-menu.ts create mode 100644 frontend/src/vite-env.d.ts create mode 100644 frontend/tsconfig.json create mode 100644 frontend/tsconfig.node.json create mode 100644 frontend/vite.config.ts create mode 100644 run.bat create mode 100644 start.bat create mode 100644 编排.png diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..e1cdf99 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,16 @@ +{ + "permissions": { + "allow": [ + "Bash(netstat:*)", + "Bash(findstr:*)", + "Bash(taskkill:*)", + "Bash(cat:*)", + "Bash(npm install:*)", + "Bash(npx vue-tsc:*)", + "Bash(xargs cat:*)", + "Bash(find:*)", + "Bash(npm run dev:*)", + "Bash(timeout 10 npm run dev:*)" + ] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3b66410 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "git.ignoreLimitWarning": true +} \ No newline at end of file diff --git a/backend/.env.example b/backend/.env.example new file mode 100644 index 0000000..520ffb3 --- /dev/null +++ b/backend/.env.example @@ -0,0 +1,2 @@ +OPENAI_API_KEY=your_api_key_here +OPENAI_BASE_URL= diff --git a/backend/bun.lock b/backend/bun.lock new file mode 100644 index 0000000..0f9591d --- /dev/null +++ b/backend/bun.lock @@ -0,0 +1,197 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "flow-backend", + "dependencies": { + "@langchain/openai": "^0.0.14", + "langchain": "^0.1.0", + }, + }, + }, + "packages": { + "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.9.1", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "digest-fetch": "^1.3.0", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7", "web-streams-polyfill": "^3.2.1" } }, "sha512-wa1meQ2WSfoY8Uor3EdrJq0jTiZJoKoSii2ZVWRY1oN4Tlr5s59pADg9T79FTbPe1/se5c3pBeZgJL63wmuoBA=="], + + "@langchain/community": ["@langchain/community@0.0.57", "", { "dependencies": { "@langchain/core": "~0.1.60", "@langchain/openai": "~0.0.28", "expr-eval": "^2.0.2", "flat": "^5.0.2", "langsmith": "~0.1.1", "uuid": "^9.0.0", "zod": "^3.22.3", "zod-to-json-schema": "^3.22.5" }, "peerDependencies": { "@aws-crypto/sha256-js": "^5.0.0", "@aws-sdk/client-bedrock-agent-runtime": "^3.485.0", "@aws-sdk/client-bedrock-runtime": "^3.422.0", "@aws-sdk/client-dynamodb": "^3.310.0", "@aws-sdk/client-kendra": "^3.352.0", "@aws-sdk/client-lambda": "^3.310.0", "@aws-sdk/client-sagemaker-runtime": "^3.310.0", "@aws-sdk/client-sfn": "^3.310.0", "@aws-sdk/credential-provider-node": "^3.388.0", "@azure/search-documents": "^12.0.0", "@clickhouse/client": "^0.2.5", "@cloudflare/ai": "*", "@datastax/astra-db-ts": "^1.0.0", "@elastic/elasticsearch": "^8.4.0", "@getmetal/metal-sdk": "*", "@getzep/zep-js": "^0.9.0", "@gomomento/sdk": "^1.51.1", "@gomomento/sdk-core": "^1.51.1", "@google-ai/generativelanguage": "^0.2.1", "@gradientai/nodejs-sdk": "^1.2.0", "@huggingface/inference": "^2.6.4", "@mlc-ai/web-llm": "^0.2.35", "@mozilla/readability": "*", "@neondatabase/serverless": "*", "@opensearch-project/opensearch": "*", "@pinecone-database/pinecone": "*", "@planetscale/database": "^1.8.0", "@premai/prem-sdk": "^0.3.25", "@qdrant/js-client-rest": "^1.8.2", "@raycast/api": "^1.55.2", "@rockset/client": "^0.9.1", "@smithy/eventstream-codec": "^2.0.5", "@smithy/protocol-http": "^3.0.6", "@smithy/signature-v4": "^2.0.10", "@smithy/util-utf8": "^2.0.0", "@supabase/postgrest-js": "^1.1.1", "@supabase/supabase-js": "^2.10.0", "@tensorflow-models/universal-sentence-encoder": "*", "@tensorflow/tfjs-converter": "*", "@tensorflow/tfjs-core": "*", "@upstash/redis": "^1.20.6", "@upstash/vector": "^1.0.7", "@vercel/kv": "^0.2.3", "@vercel/postgres": "^0.5.0", "@writerai/writer-sdk": "^0.40.2", "@xata.io/client": "^0.28.0", "@xenova/transformers": "^2.5.4", "@zilliz/milvus2-sdk-node": ">=2.2.7", "better-sqlite3": "^9.4.0", "cassandra-driver": "^4.7.2", "cborg": "^4.1.1", "chromadb": "*", "closevector-common": "0.1.3", "closevector-node": "0.1.6", "closevector-web": "0.1.6", "cohere-ai": "*", "convex": "^1.3.1", "couchbase": "^4.3.0", "discord.js": "^14.14.1", "dria": "^0.0.3", "duck-duck-scrape": "^2.2.5", "faiss-node": "^0.5.1", "firebase-admin": "^11.9.0 || ^12.0.0", "google-auth-library": "^8.9.0", "googleapis": "^126.0.1", "hnswlib-node": "^3.0.0", "html-to-text": "^9.0.5", "interface-datastore": "^8.2.11", "ioredis": "^5.3.2", "it-all": "^3.0.4", "jsdom": "*", "jsonwebtoken": "^9.0.2", "llmonitor": "^0.5.9", "lodash": "^4.17.21", "lunary": "^0.6.11", "mongodb": ">=5.2.0", "mysql2": "^3.3.3", "neo4j-driver": "*", "node-llama-cpp": "*", "pg": "^8.11.0", "pg-copy-streams": "^6.0.5", "pickleparser": "^0.2.1", "portkey-ai": "^0.1.11", "redis": "*", "replicate": "^0.18.0", "typeorm": "^0.3.12", "typesense": "^1.5.3", "usearch": "^1.1.1", "vectordb": "^0.1.4", "voy-search": "0.6.2", "weaviate-ts-client": "*", "web-auth-library": "^1.0.3", "ws": "^8.14.2" }, "optionalPeers": ["@aws-crypto/sha256-js", "@aws-sdk/client-bedrock-agent-runtime", "@aws-sdk/client-bedrock-runtime", "@aws-sdk/client-dynamodb", "@aws-sdk/client-kendra", "@aws-sdk/client-lambda", "@aws-sdk/client-sagemaker-runtime", "@aws-sdk/client-sfn", "@aws-sdk/credential-provider-node", "@azure/search-documents", "@clickhouse/client", "@cloudflare/ai", "@datastax/astra-db-ts", "@elastic/elasticsearch", "@getmetal/metal-sdk", "@getzep/zep-js", "@gomomento/sdk", "@gomomento/sdk-core", "@google-ai/generativelanguage", "@gradientai/nodejs-sdk", "@huggingface/inference", "@mlc-ai/web-llm", "@mozilla/readability", "@neondatabase/serverless", "@opensearch-project/opensearch", "@pinecone-database/pinecone", "@planetscale/database", "@premai/prem-sdk", "@qdrant/js-client-rest", "@raycast/api", "@rockset/client", "@smithy/eventstream-codec", "@smithy/protocol-http", "@smithy/signature-v4", "@smithy/util-utf8", "@supabase/postgrest-js", "@supabase/supabase-js", "@tensorflow-models/universal-sentence-encoder", "@tensorflow/tfjs-converter", "@tensorflow/tfjs-core", "@upstash/redis", "@upstash/vector", "@vercel/kv", "@vercel/postgres", "@writerai/writer-sdk", "@xata.io/client", "@xenova/transformers", "@zilliz/milvus2-sdk-node", "better-sqlite3", "cassandra-driver", "cborg", "chromadb", "closevector-common", "closevector-node", "closevector-web", "cohere-ai", "convex", "couchbase", "discord.js", "dria", "duck-duck-scrape", "faiss-node", "firebase-admin", "google-auth-library", "googleapis", "hnswlib-node", "html-to-text", "interface-datastore", "ioredis", "it-all", "jsdom", "jsonwebtoken", "llmonitor", "lodash", "lunary", "mongodb", "mysql2", "neo4j-driver", "node-llama-cpp", "pg", "pg-copy-streams", "pickleparser", "portkey-ai", "redis", "replicate", "typeorm", "typesense", "usearch", "vectordb", "voy-search", "weaviate-ts-client", "web-auth-library", "ws"] }, "sha512-tib4UJNkyA4TPNsTNChiBtZmThVJBr7X/iooSmKeCr+yUEha2Yxly3A4OAO95Vlpj4Q+od8HAfCbZih/1XqAMw=="], + + "@langchain/core": ["@langchain/core@0.1.63", "", { "dependencies": { "ansi-styles": "^5.0.0", "camelcase": "6", "decamelize": "1.2.0", "js-tiktoken": "^1.0.12", "langsmith": "~0.1.7", "ml-distance": "^4.0.0", "mustache": "^4.2.0", "p-queue": "^6.6.2", "p-retry": "4", "uuid": "^9.0.0", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" } }, "sha512-+fjyYi8wy6x1P+Ee1RWfIIEyxd9Ee9jksEwvrggPwwI/p45kIDTdYTblXsM13y4mNWTiACyLSdbwnPaxxdoz+w=="], + + "@langchain/openai": ["@langchain/openai@0.0.14", "", { "dependencies": { "@langchain/core": "~0.1.13", "js-tiktoken": "^1.0.7", "openai": "^4.26.0", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" } }, "sha512-co6nRylPrLGY/C3JYxhHt6cxLq07P086O7K3QaZH7SFFErIN9wSzJonpvhZR07DEUq6eK6wKgh2ORxA/NcjSRQ=="], + + "@langchain/textsplitters": ["@langchain/textsplitters@0.0.3", "", { "dependencies": { "@langchain/core": ">0.2.0 <0.3.0", "js-tiktoken": "^1.0.12" } }, "sha512-cXWgKE3sdWLSqAa8ykbCcUsUF1Kyr5J3HOWYGuobhPEycXW4WI++d5DhzdpL238mzoEXTi90VqfSCra37l5YqA=="], + + "@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="], + + "@types/node-fetch": ["@types/node-fetch@2.6.13", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.4" } }, "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw=="], + + "@types/retry": ["@types/retry@0.12.0", "", {}, "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="], + + "@types/uuid": ["@types/uuid@10.0.0", "", {}, "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ=="], + + "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], + + "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="], + + "ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + + "base-64": ["base-64@0.1.0", "", {}, "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="], + + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], + + "binary-search": ["binary-search@1.3.6", "", {}, "sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], + + "charenc": ["charenc@0.0.2", "", {}, "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA=="], + + "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + + "commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="], + + "crypt": ["crypt@0.0.2", "", {}, "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow=="], + + "decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="], + + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + + "digest-fetch": ["digest-fetch@1.3.0", "", { "dependencies": { "base-64": "^0.1.0", "md5": "^2.3.0" } }, "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA=="], + + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + + "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], + + "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], + + "eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="], + + "expr-eval": ["expr-eval@2.0.2", "", {}, "sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg=="], + + "flat": ["flat@5.0.2", "", { "bin": { "flat": "cli.js" } }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="], + + "form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], + + "form-data-encoder": ["form-data-encoder@1.7.2", "", {}, "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A=="], + + "formdata-node": ["formdata-node@4.4.1", "", { "dependencies": { "node-domexception": "1.0.0", "web-streams-polyfill": "4.0.0-beta.3" } }, "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], + + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + + "humanize-ms": ["humanize-ms@1.2.1", "", { "dependencies": { "ms": "^2.0.0" } }, "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ=="], + + "is-any-array": ["is-any-array@2.0.1", "", {}, "sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ=="], + + "is-buffer": ["is-buffer@1.1.6", "", {}, "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="], + + "js-tiktoken": ["js-tiktoken@1.0.21", "", { "dependencies": { "base64-js": "^1.5.1" } }, "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g=="], + + "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + + "jsonpointer": ["jsonpointer@5.0.1", "", {}, "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ=="], + + "langchain": ["langchain@0.1.37", "", { "dependencies": { "@anthropic-ai/sdk": "^0.9.1", "@langchain/community": "~0.0.47", "@langchain/core": "~0.1.60", "@langchain/openai": "~0.0.28", "@langchain/textsplitters": "~0.0.0", "binary-extensions": "^2.2.0", "js-tiktoken": "^1.0.7", "js-yaml": "^4.1.0", "jsonpointer": "^5.0.1", "langchainhub": "~0.0.8", "langsmith": "~0.1.7", "ml-distance": "^4.0.0", "openapi-types": "^12.1.3", "p-retry": "4", "uuid": "^9.0.0", "yaml": "^2.2.1", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" }, "peerDependencies": { "@aws-sdk/client-s3": "^3.310.0", "@aws-sdk/client-sagemaker-runtime": "^3.310.0", "@aws-sdk/client-sfn": "^3.310.0", "@aws-sdk/credential-provider-node": "^3.388.0", "@azure/storage-blob": "^12.15.0", "@browserbasehq/sdk": "*", "@gomomento/sdk": "^1.51.1", "@gomomento/sdk-core": "^1.51.1", "@gomomento/sdk-web": "^1.51.1", "@google-ai/generativelanguage": "^0.2.1", "@google-cloud/storage": "^6.10.1 || ^7.7.0", "@mendable/firecrawl-js": "^0.0.13", "@notionhq/client": "^2.2.10", "@pinecone-database/pinecone": "*", "@supabase/supabase-js": "^2.10.0", "@vercel/kv": "^0.2.3", "@xata.io/client": "^0.28.0", "apify-client": "^2.7.1", "assemblyai": "^4.0.0", "axios": "*", "cheerio": "^1.0.0-rc.12", "chromadb": "*", "convex": "^1.3.1", "couchbase": "^4.3.0", "d3-dsv": "^2.0.0", "epub2": "^3.0.1", "fast-xml-parser": "*", "google-auth-library": "^8.9.0", "handlebars": "^4.7.8", "html-to-text": "^9.0.5", "ignore": "^5.2.0", "ioredis": "^5.3.2", "jsdom": "*", "mammoth": "^1.6.0", "mongodb": ">=5.2.0", "node-llama-cpp": "*", "notion-to-md": "^3.1.0", "officeparser": "^4.0.4", "pdf-parse": "1.1.1", "peggy": "^3.0.2", "playwright": "^1.32.1", "puppeteer": "^19.7.2", "pyodide": "^0.24.1", "redis": "^4.6.4", "sonix-speech-recognition": "^2.1.1", "srt-parser-2": "^1.2.3", "typeorm": "^0.3.12", "weaviate-ts-client": "*", "web-auth-library": "^1.0.3", "ws": "^8.14.2", "youtube-transcript": "^1.0.6", "youtubei.js": "^9.1.0" }, "optionalPeers": ["@aws-sdk/client-s3", "@aws-sdk/client-sagemaker-runtime", "@aws-sdk/client-sfn", "@aws-sdk/credential-provider-node", "@azure/storage-blob", "@browserbasehq/sdk", "@gomomento/sdk", "@gomomento/sdk-core", "@gomomento/sdk-web", "@google-ai/generativelanguage", "@google-cloud/storage", "@mendable/firecrawl-js", "@notionhq/client", "@pinecone-database/pinecone", "@supabase/supabase-js", "@vercel/kv", "@xata.io/client", "apify-client", "assemblyai", "axios", "cheerio", "chromadb", "convex", "couchbase", "d3-dsv", "epub2", "fast-xml-parser", "google-auth-library", "handlebars", "html-to-text", "ignore", "ioredis", "jsdom", "mammoth", "mongodb", "node-llama-cpp", "notion-to-md", "officeparser", "pdf-parse", "peggy", "playwright", "puppeteer", "pyodide", "redis", "sonix-speech-recognition", "srt-parser-2", "typeorm", "weaviate-ts-client", "web-auth-library", "ws", "youtube-transcript", "youtubei.js"] }, "sha512-rpaLEJtRrLYhAViEp7/aHfSkxbgSqHJ5n10tXv3o4kHP/wOin85RpTgewwvGjEaKc3797jOg+sLSk6a7e0UlMg=="], + + "langchainhub": ["langchainhub@0.0.11", "", {}, "sha512-WnKI4g9kU2bHQP136orXr2bcRdgz9iiTBpTN0jWt9IlScUKnJBoD0aa2HOzHURQKeQDnt2JwqVmQ6Depf5uDLQ=="], + + "langsmith": ["langsmith@0.1.68", "", { "dependencies": { "@types/uuid": "^10.0.0", "commander": "^10.0.1", "p-queue": "^6.6.2", "p-retry": "4", "semver": "^7.6.3", "uuid": "^10.0.0" }, "peerDependencies": { "openai": "*" }, "optionalPeers": ["openai"] }, "sha512-otmiysWtVAqzMx3CJ4PrtUBhWRG5Co8Z4o7hSZENPjlit9/j3/vm3TSvbaxpDYakZxtMjhkcJTqrdYFipISEiQ=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "md5": ["md5@2.3.0", "", { "dependencies": { "charenc": "0.0.2", "crypt": "0.0.2", "is-buffer": "~1.1.6" } }, "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g=="], + + "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + + "ml-array-mean": ["ml-array-mean@1.1.6", "", { "dependencies": { "ml-array-sum": "^1.1.6" } }, "sha512-MIdf7Zc8HznwIisyiJGRH9tRigg3Yf4FldW8DxKxpCCv/g5CafTw0RRu51nojVEOXuCQC7DRVVu5c7XXO/5joQ=="], + + "ml-array-sum": ["ml-array-sum@1.1.6", "", { "dependencies": { "is-any-array": "^2.0.0" } }, "sha512-29mAh2GwH7ZmiRnup4UyibQZB9+ZLyMShvt4cH4eTK+cL2oEMIZFnSyB3SS8MlsTh6q/w/yh48KmqLxmovN4Dw=="], + + "ml-distance": ["ml-distance@4.0.1", "", { "dependencies": { "ml-array-mean": "^1.1.6", "ml-distance-euclidean": "^2.0.0", "ml-tree-similarity": "^1.0.0" } }, "sha512-feZ5ziXs01zhyFUUUeZV5hwc0f5JW0Sh0ckU1koZe/wdVkJdGxcP06KNQuF0WBTj8FttQUzcvQcpcrOp/XrlEw=="], + + "ml-distance-euclidean": ["ml-distance-euclidean@2.0.0", "", {}, "sha512-yC9/2o8QF0A3m/0IXqCTXCzz2pNEzvmcE/9HFKOZGnTjatvBbsn4lWYJkxENkA4Ug2fnYl7PXQxnPi21sgMy/Q=="], + + "ml-tree-similarity": ["ml-tree-similarity@1.0.0", "", { "dependencies": { "binary-search": "^1.3.5", "num-sort": "^2.0.0" } }, "sha512-XJUyYqjSuUQkNQHMscr6tcjldsOoAekxADTplt40QKfwW6nd++1wHWV9AArl0Zvw/TIHgNaZZNvr8QGvE8wLRg=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "mustache": ["mustache@4.2.0", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="], + + "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], + + "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + + "num-sort": ["num-sort@2.1.0", "", {}, "sha512-1MQz1Ed8z2yckoBeSfkQHHO9K1yDRxxtotKSJ9yvcTUUxSvfvzEq5GwBrjjHEpMlq/k5gvXdmJ1SbYxWtpNoVg=="], + + "openai": ["openai@4.104.0", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" }, "peerDependencies": { "ws": "^8.18.0", "zod": "^3.23.8" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA=="], + + "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="], + + "p-finally": ["p-finally@1.0.0", "", {}, "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow=="], + + "p-queue": ["p-queue@6.6.2", "", { "dependencies": { "eventemitter3": "^4.0.4", "p-timeout": "^3.2.0" } }, "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ=="], + + "p-retry": ["p-retry@4.6.2", "", { "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" } }, "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ=="], + + "p-timeout": ["p-timeout@3.2.0", "", { "dependencies": { "p-finally": "^1.0.0" } }, "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg=="], + + "retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="], + + "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + + "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + + "undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + + "uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], + + "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], + + "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], + + "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + + "yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="], + + "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "zod-to-json-schema": ["zod-to-json-schema@3.25.0", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ=="], + + "@langchain/community/@langchain/openai": ["@langchain/openai@0.0.34", "", { "dependencies": { "@langchain/core": ">0.1.56 <0.3.0", "js-tiktoken": "^1.0.12", "openai": "^4.41.1", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" } }, "sha512-M+CW4oXle5fdoz2T2SwdOef8pl3/1XmUx1vjn2mXUVM/128aO0l23FMF0SNBsAbRV6P+p/TuzjodchJbi0Ht/A=="], + + "@langchain/textsplitters/@langchain/core": ["@langchain/core@0.2.36", "", { "dependencies": { "ansi-styles": "^5.0.0", "camelcase": "6", "decamelize": "1.2.0", "js-tiktoken": "^1.0.12", "langsmith": "^0.1.56-rc.1", "mustache": "^4.2.0", "p-queue": "^6.6.2", "p-retry": "4", "uuid": "^10.0.0", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" } }, "sha512-qHLvScqERDeH7y2cLuJaSAlMwg3f/3Oc9nayRSXRU2UuaK/SOhI42cxiPLj1FnuHJSmN0rBQFkrLx02gI4mcVg=="], + + "formdata-node/web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="], + + "langchain/@langchain/openai": ["@langchain/openai@0.0.34", "", { "dependencies": { "@langchain/core": ">0.1.56 <0.3.0", "js-tiktoken": "^1.0.12", "openai": "^4.41.1", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" } }, "sha512-M+CW4oXle5fdoz2T2SwdOef8pl3/1XmUx1vjn2mXUVM/128aO0l23FMF0SNBsAbRV6P+p/TuzjodchJbi0Ht/A=="], + + "langsmith/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="], + + "@langchain/textsplitters/@langchain/core/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="], + } +} diff --git a/backend/flow.db b/backend/flow.db new file mode 100644 index 0000000000000000000000000000000000000000..826907b05af418e0d57fe0c0797d4d527955c903 GIT binary patch literal 28672 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 QA|ymXd{^fjYP{&?zYUI61^@s6 literal 0 HcmV?d00001 diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 0000000..b612352 --- /dev/null +++ b/backend/package.json @@ -0,0 +1,12 @@ +{ + "name": "flow-backend", + "type": "module", + "scripts": { + "dev": "bun --watch src/index.ts", + "start": "bun src/index.ts" + }, + "dependencies": { + "@langchain/openai": "^0.0.14", + "langchain": "^0.1.0" + } +} diff --git a/backend/src/db.ts b/backend/src/db.ts new file mode 100644 index 0000000..ff3d015 --- /dev/null +++ b/backend/src/db.ts @@ -0,0 +1,25 @@ +import { Database } from "bun:sqlite"; + +const db = new Database("flow.db"); + +db.run(` + CREATE TABLE IF NOT EXISTS flows ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + schema_json TEXT NOT NULL, + created_at TEXT DEFAULT CURRENT_TIMESTAMP + ) +`); + +db.run(` + CREATE TABLE IF NOT EXISTS executions ( + id TEXT PRIMARY KEY, + flow_id TEXT NOT NULL, + status TEXT DEFAULT 'pending', + result TEXT, + start_time TEXT DEFAULT CURRENT_TIMESTAMP, + end_time TEXT + ) +`); + +export default db; diff --git a/backend/src/executors/base.ts b/backend/src/executors/base.ts new file mode 100644 index 0000000..d68cd62 --- /dev/null +++ b/backend/src/executors/base.ts @@ -0,0 +1,7 @@ +export interface NodeConfig { + [key: string]: any; +} + +export interface BaseExecutor { + execute(config: NodeConfig, input: Record): Promise>; +} diff --git a/backend/src/executors/index.ts b/backend/src/executors/index.ts new file mode 100644 index 0000000..4b98f71 --- /dev/null +++ b/backend/src/executors/index.ts @@ -0,0 +1,14 @@ +import type { BaseExecutor } from "./base"; +import { llmExecutor } from "./llm"; + +const executors: Record = { + llmAgentNode: llmExecutor, + toolAgentNode: { + async execute(config, input) { + // 简单的搜索模拟,可扩展接入真实工具 + return { output: `Tool ${config.tool_name} result for: ${input.output || input.input}` }; + }, + }, +}; + +export const getExecutor = (type: string) => executors[type]; diff --git a/backend/src/executors/llm.ts b/backend/src/executors/llm.ts new file mode 100644 index 0000000..1c3e9e7 --- /dev/null +++ b/backend/src/executors/llm.ts @@ -0,0 +1,20 @@ +import { ChatOpenAI } from "@langchain/openai"; +import { PromptTemplate } from "@langchain/core/prompts"; +import type { BaseExecutor, NodeConfig } from "./base"; + +export const llmExecutor: BaseExecutor = { + async execute(config: NodeConfig, input: Record) { + const llm = new ChatOpenAI({ + modelName: config.model || "gpt-4o", + openAIApiKey: process.env.OPENAI_API_KEY, + configuration: { baseURL: process.env.OPENAI_BASE_URL || undefined }, + }); + + const template = config.prompt_template || "{input}"; + const prompt = PromptTemplate.fromTemplate(template); + const chain = prompt.pipe(llm); + + const result = await chain.invoke(input.output ? { input: input.output } : input); + return { output: result.content }; + }, +}; diff --git a/backend/src/index.ts b/backend/src/index.ts new file mode 100644 index 0000000..a5106fd --- /dev/null +++ b/backend/src/index.ts @@ -0,0 +1,101 @@ +import db from "./db"; +import { socketManager } from "./services/socket"; +import { executeFlow } from "./services/executor"; + +const server = Bun.serve({ + port: 8000, + async fetch(req, server) { + const url = new URL(req.url); + + // CORS + if (req.method === "OPTIONS") { + return new Response(null, { headers: corsHeaders }); + } + + // WebSocket upgrade + if (url.pathname.startsWith("/ws/flows/")) { + const executionId = url.pathname.split("/").pop()!; + if (server.upgrade(req, { data: { executionId } })) return; + return new Response("Upgrade failed", { status: 500 }); + } + + // API routes + if (url.pathname === "/api/flows" && req.method === "POST") { + const { name, schema_json } = await req.json(); + const id = crypto.randomUUID(); + db.run("INSERT INTO flows (id, name, schema_json) VALUES (?, ?, ?)", [id, name, JSON.stringify(schema_json)]); + return json({ id, name }); + } + + if (url.pathname.match(/^\/api\/flows\/[\w-]+$/) && req.method === "PUT") { + const id = url.pathname.split("/").pop()!; + const { name, schema_json } = await req.json(); + db.run("UPDATE flows SET name = ?, schema_json = ? WHERE id = ?", [name, JSON.stringify(schema_json), id]); + return json({ id, name }); + } + + if (url.pathname.match(/^\/api\/flows\/[\w-]+$/) && req.method === "GET") { + const id = url.pathname.split("/").pop()!; + const row = db.query("SELECT * FROM flows WHERE id = ?").get(id) as any; + if (!row) return json({ error: "Not found" }, 404); + return json({ id: row.id, name: row.name, schema_json: JSON.parse(row.schema_json) }); + } + + if (url.pathname.match(/^\/api\/flows\/[\w-]+\/execute$/) && req.method === "POST") { + const flowId = url.pathname.split("/")[3]; + const { runtime_data } = await req.json().catch(() => ({})); + const row = db.query("SELECT * FROM flows WHERE id = ?").get(flowId) as any; + if (!row) return json({ error: "Not found" }, 404); + + const executionId = crypto.randomUUID(); + db.run("INSERT INTO executions (id, flow_id, status) VALUES (?, ?, 'running')", [executionId, flowId]); + + // 异步执行 + (async () => { + try { + const result = await executeFlow(executionId, JSON.parse(row.schema_json), runtime_data); + db.run("UPDATE executions SET status = 'success', result = ?, end_time = CURRENT_TIMESTAMP WHERE id = ?", [JSON.stringify(result), executionId]); + } catch (err: any) { + db.run("UPDATE executions SET status = 'error', result = ?, end_time = CURRENT_TIMESTAMP WHERE id = ?", [JSON.stringify({ error: err.message }), executionId]); + } + })(); + + return json({ execution_id: executionId }); + } + + if (url.pathname.match(/^\/api\/flows\/executions\/[\w-]+$/) && req.method === "GET") { + const id = url.pathname.split("/").pop()!; + const row = db.query("SELECT * FROM executions WHERE id = ?").get(id) as any; + if (!row) return json({ error: "Not found" }, 404); + return json({ ...row, result: row.result ? JSON.parse(row.result) : null }); + } + + if (url.pathname === "/health") return json({ status: "ok" }); + + return json({ error: "Not found" }, 404); + }, + websocket: { + open(ws) { + socketManager.add(ws.data.executionId, ws); + }, + close(ws) { + socketManager.remove(ws.data.executionId); + }, + message() {}, + }, +}); + +const corsHeaders = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type", +}; + +function json(data: any, status = 200) { + return new Response(JSON.stringify(data), { + status, + headers: { "Content-Type": "application/json", ...corsHeaders }, + }); +} + +console.log(`Server running at http://localhost:${server.port}`); diff --git a/backend/src/services/executor.ts b/backend/src/services/executor.ts new file mode 100644 index 0000000..f010928 --- /dev/null +++ b/backend/src/services/executor.ts @@ -0,0 +1,73 @@ +import { getExecutor } from "../executors"; +import { socketManager } from "./socket"; + +interface FlowSchema { + nodes: Array<{ id: string; type: string; data: any }>; + edges: Array<{ source: string; target: string }>; +} + +export async function executeFlow(executionId: string, schema: FlowSchema, runtimeData: Record = {}) { + const nodes = Object.fromEntries(schema.nodes.map((n) => [n.id, n])); + const adj: Record = {}; + const inDegree: Record = {}; + + for (const n of schema.nodes) { + adj[n.id] = []; + inDegree[n.id] = 0; + } + for (const e of schema.edges) { + adj[e.source].push(e.target); + inDegree[e.target]++; + } + + // 拓扑排序 + const queue = Object.keys(inDegree).filter((id) => inDegree[id] === 0); + const sorted: string[] = []; + while (queue.length) { + const id = queue.shift()!; + sorted.push(id); + for (const next of adj[id]) { + if (--inDegree[next] === 0) queue.push(next); + } + } + + const context: Record = { ...runtimeData }; + + for (const nodeId of sorted) { + const node = nodes[nodeId]; + socketManager.send(executionId, nodeId, "running", "开始执行"); + + try { + let result: Record; + + if (node.type === "startNode") { + result = { output: context[node.data?.input_key] || "" }; + } else if (node.type === "outputNode") { + const prev = schema.edges.find((e) => e.target === nodeId)?.source; + result = { output: prev ? context[prev]?.output : "" }; + } else if (node.type === "conditionalNode") { + const prev = schema.edges.find((e) => e.target === nodeId)?.source; + const output = prev ? context[prev] : {}; + try { + result = { output: eval(node.data?.check_expression || "true"), condition_result: true }; + } catch { + result = { output: false, condition_result: false }; + } + } else { + const executor = getExecutor(node.type); + if (!executor) throw new Error(`No executor for ${node.type}`); + const prev = schema.edges.find((e) => e.target === nodeId)?.source; + const input = prev ? context[prev] : context; + result = await executor.execute(node.data || {}, input); + } + + context[nodeId] = result; + socketManager.send(executionId, nodeId, "success", "执行完成", String(result.output || "")); + } catch (err: any) { + socketManager.send(executionId, nodeId, "error", err.message); + throw err; + } + } + + return context; +} diff --git a/backend/src/services/socket.ts b/backend/src/services/socket.ts new file mode 100644 index 0000000..df65c39 --- /dev/null +++ b/backend/src/services/socket.ts @@ -0,0 +1,25 @@ +import type { ServerWebSocket } from "bun"; + +const connections = new Map>(); + +export const socketManager = { + add(executionId: string, ws: ServerWebSocket<{ executionId: string }>) { + connections.set(executionId, ws); + }, + remove(executionId: string) { + connections.delete(executionId); + }, + send(executionId: string, nodeId: string, status: string, message = "", outputPreview = "") { + const ws = connections.get(executionId); + if (ws) { + ws.send(JSON.stringify({ + eventType: "status_update", + executionId, + nodeId, + status, + timestamp: new Date().toISOString(), + payload: { log_message: message, output_preview: outputPreview.slice(0, 200) }, + })); + } + }, +}; diff --git a/flow.md b/flow.md new file mode 100644 index 0000000..159dbe6 --- /dev/null +++ b/flow.md @@ -0,0 +1,40 @@ +1. 项目概览与架构设计1.1 核心目标提供基于 Vue Flow 的可视化流程编排界面。后端采用 Executor 模式 和 LangChain,确保 Agent 逻辑高度模块化和可扩展。通过 WebSocket 实现流程执行状态的实时监控。1.2 技术栈 (Technology Stack)领域技术/框架职责前端 (FE)Vue 3, Vue Flow, Axios流程图渲染、节点配置、API 通信。后端 (BE)FastAPI高性能 API 服务,路由,WebSocket 管理。Agent 核心LangChainAgent 定义、工具调用、Prompt 模板。数据库PostgreSQL/SQLite存储流程 Schema、Agent 配置和执行历史。1.3 核心架构前端 (Vue Flow): 用户设计流程,提交 Schema。FastAPI (API/WS Router): 接收请求,管理 WebSocket 连接。Flow Parser: 将 Vue Flow Schema 转换为内部 DAG (有向无环图) 结构。Flow Executor: 遍历 DAG,调度 Agent,并向 Socket Manager 推送状态。Agent Executors: LangChain 驱动的模块化 Agent 实例。2. 前端设计与实现 (Vue Flow)2.1 节点类型与配置组件所有自定义节点(Custom Nodes)必须包含一个用于配置其后端参数的组件。节点 Type ID描述核心配置字段 (Node Data)startNode流程的输入/触发器。{"input_key": "user_query"}llmAgentNode基础 LLM 任务。{"model": "gpt-4o", "prompt_template": "...", "input_map": {...}}toolAgentNode调用外部工具。{"tool_name": "Search", "tool_config": {...}}conditionalNode逻辑路由判断。{"check_expression": "output.type == 'sales'"} outputNode流程结果输出。{"output_key": "final_result"}2.2 数据契约:Schema 到后端前端将 Vue Flow toObject() 结果发送给后端。JSON{ + "flowId": "uuid_flow_1", + "nodes": [ + // ... Node Definition (包含 type 和 data) + ], + "edges": [ + // ... Edge Definition (包含 source, target, label/condition) + ], + // 增加运行时数据,方便流程重启或监控 + "runtime_data": {} +} +2.3 状态监控逻辑 (WebSocket Client)连接建立: 流程执行 API 成功调用后,前端立即使用返回的 execution_id 建立 WS 连接:ws://backend_url/ws/flows/{execution_id}。状态映射: 监听 WebSocket 消息,根据消息中的 nodeId 和 status 实时更新 Vue Flow 节点的外观样式 (CSS Class)。running $\rightarrow$ 节点边框闪烁/黄色success $\rightarrow$ 绿色边框/实心error $\rightarrow$ 红色边框/错误图标3. 后端设计与实现 (FastAPI + LangChain)3.1 核心数据模型 (Pydantic/ORM)模型/类描述关键字段FlowSchema存储 Vue Flow 结构。id, name, schema_json, created_atExecution存储流程运行实例。id, flow_id, status, start_time, end_timeExecutionLog存储运行时日志。execution_id, node_id, status, message, timestamp3.2 API 接口规范接口方法路径描述创建/更新流程POST / PUT/api/flows存储前端设计的流程 Schema。流程启动POST/api/flows/{flow_id}/execute启动流程执行,返回 execution_id。流程历史GET/api/executions/{exec_id}获取流程历史状态和最终输出。实时监控WS/ws/flows/{execution_id}实时推送节点状态和日志。3.3 Agent 执行器与扩展性所有 Agent 逻辑必须遵循统一的执行器接口,保证 Flow Executor 不关心底层细节。Python# Base Agent Executor Interface +from typing import Dict, Any + +class BaseAgentExecutor: + # 核心执行方法 + async def execute(self, node_config: Dict[str, Any], input_data: Dict[str, Any]) -> Dict[str, Any]: + """执行 Agent 任务,返回结构化输出。""" + # 内部应调用 LangChain Components (Chains, Agents, Tools) + raise NotImplementedError + +# 扩展示例:新增 Database Agent +class DBQueryExecutor(BaseAgentExecutor): + async def execute(self, node_config, input_data): + # 1. 解析 node_config 获取 SQL 模板 + # 2. 调用 LangChain SQL ToolChain + # 3. 返回结果 + pass +3.4 WebSocket 消息契约 (Backend -> Frontend)所有状态更新都通过这个统一的 JSON 格式推送。JSON{ + "eventType": "status_update", + "executionId": "...", + "nodeId": "node_A", + "status": "success", // running, success, error, skipped + "timestamp": "2025-12-11T...", + "payload": { + "log_message": "Agent finished successfully.", + "output_preview": "Summary: The project is highly scalable." + } +} +4. 部署与环境规范4.1 环境依赖后端: Python 3.11+ (FastAPI, LangChain, Uvicorn)前端: Node.js 18+ (Vue 3+vite+ts, Vue Flow)4.2 部署建议分离部署: 前后端应分开部署。CORS 配置: 确保 FastAPI 允许前端 URL 访问 API 和 WebSocket 端口。密钥管理: 使用环境变量 (.env 或 secrets manager) 管理 OPENAI_API_KEY \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..8322e59 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,12 @@ + + + + + + 流程编排 + + +
+ + + diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..3eb1f87 --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,3070 @@ +{ + "name": "flow-orchestration-frontend", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "flow-orchestration-frontend", + "version": "1.0.0", + "dependencies": { + "@element-plus/icons-vue": "^2.3.0", + "@iconify/json": "^2.2.417", + "@iconify/vue": "^5.0.0", + "@vue-flow/background": "^1.3.0", + "@vue-flow/controls": "^1.1.0", + "@vue-flow/core": "^1.33.0", + "@vue-flow/minimap": "^1.4.0", + "axios": "^1.6.0", + "element-plus": "^2.5.0", + "pinia": "^2.1.0", + "vue": "^3.4.0" + }, + "devDependencies": { + "@types/node": "^25.0.1", + "@vitejs/plugin-vue": "^5.0.0", + "sass-embedded": "^1.96.0", + "typescript": "^5.3.0", + "vite": "^5.0.0", + "vue-tsc": "^1.8.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bufbuild/protobuf": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.10.2.tgz", + "integrity": "sha512-uFsRXwIGyu+r6AMdz+XijIIZJYpoWeYzILt5yZ2d3mCjQrWUTVpVD9WL/jZAbvp+Ed04rOhrsk7FiTcEDseB5A==", + "dev": true, + "license": "(Apache-2.0 AND BSD-3-Clause)" + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@element-plus/icons-vue": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz", + "integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" + }, + "node_modules/@iconify/json": { + "version": "2.2.417", + "resolved": "https://registry.npmjs.org/@iconify/json/-/json-2.2.417.tgz", + "integrity": "sha512-/MzthgckJ4vEwdHmAbAn6Bph5WnR4tzVcHMs/nZl3v5hOVRw80SK28UPnG7jjsCB41WWjWPnWdMEdOZfUMZS5w==", + "license": "MIT", + "dependencies": { + "@iconify/types": "*", + "pathe": "^2.0.3" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/vue": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@iconify/vue/-/vue-5.0.0.tgz", + "integrity": "sha512-C+KuEWIF5nSBrobFJhT//JS87OZ++QDORB6f2q2Wm6fl2mueSTpFBeBsveK0KW9hWiZ4mNiPjsh6Zs4jjdROSg==", + "license": "MIT", + "dependencies": { + "@iconify/types": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + }, + "peerDependencies": { + "vue": ">=3" + } + }, + "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/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@popperjs/core": { + "name": "@sxzz/popperjs-es", + "version": "2.11.7", + "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", + "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/node": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.1.tgz", + "integrity": "sha512-czWPzKIAXucn9PtsttxmumiQ9N0ok9FrBwgRWrwmVLlp86BrMExzvXRLFYRJ+Ex3g6yqj+KuaxfX1JTgV2lpfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@volar/language-core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", + "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "1.11.1" + } + }, + "node_modules/@volar/source-map": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", + "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "muggle-string": "^0.3.1" + } + }, + "node_modules/@volar/typescript": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", + "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "1.11.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@vue-flow/background": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@vue-flow/background/-/background-1.3.2.tgz", + "integrity": "sha512-eJPhDcLj1wEo45bBoqTXw1uhl0yK2RaQGnEINqvvBsAFKh/camHJd5NPmOdS1w+M9lggc9igUewxaEd3iCQX2w==", + "license": "MIT", + "peerDependencies": { + "@vue-flow/core": "^1.23.0", + "vue": "^3.3.0" + } + }, + "node_modules/@vue-flow/controls": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vue-flow/controls/-/controls-1.1.3.tgz", + "integrity": "sha512-XCf+G+jCvaWURdFlZmOjifZGw3XMhN5hHlfMGkWh9xot+9nH9gdTZtn+ldIJKtarg3B21iyHU8JjKDhYcB6JMw==", + "license": "MIT", + "peerDependencies": { + "@vue-flow/core": "^1.23.0", + "vue": "^3.3.0" + } + }, + "node_modules/@vue-flow/core": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/@vue-flow/core/-/core-1.48.0.tgz", + "integrity": "sha512-keW9HGaEZEe4SKYtrzp5E+qSGJ5/z+9i2yRDtCr3o72IUnS0Ns1qQNsIbGGz0ygpKzg6LdtbVLWeYAvl3dzLQA==", + "license": "MIT", + "dependencies": { + "@vueuse/core": "^10.5.0", + "d3-drag": "^3.0.0", + "d3-interpolate": "^3.0.1", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + }, + "peerDependencies": { + "vue": "^3.3.0" + } + }, + "node_modules/@vue-flow/minimap": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@vue-flow/minimap/-/minimap-1.5.4.tgz", + "integrity": "sha512-l4C+XTAXnRxsRpUdN7cAVFBennC1sVRzq4bDSpVK+ag7tdMczAnhFYGgbLkUw3v3sY6gokyWwMl8CDonp8eB2g==", + "license": "MIT", + "dependencies": { + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + }, + "peerDependencies": { + "@vue-flow/core": "^1.23.0", + "vue": "^3.3.0" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz", + "integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.25", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz", + "integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz", + "integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.25", + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz", + "integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/@vue/language-core": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", + "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "~1.11.1", + "@volar/source-map": "~1.11.1", + "@vue/compiler-dom": "^3.3.0", + "@vue/shared": "^3.3.0", + "computeds": "^0.0.1", + "minimatch": "^9.0.3", + "muggle-string": "^0.3.1", + "path-browserify": "^1.0.1", + "vue-template-compiler": "^2.7.14" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.25.tgz", + "integrity": "sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.25.tgz", + "integrity": "sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.25.tgz", + "integrity": "sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.25", + "@vue/runtime-core": "3.5.25", + "@vue/shared": "3.5.25", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.25.tgz", + "integrity": "sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25" + }, + "peerDependencies": { + "vue": "3.5.25" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz", + "integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==", + "license": "MIT" + }, + "node_modules/@vueuse/core": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.11.1.tgz", + "integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.11.1", + "@vueuse/shared": "10.11.1", + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/metadata": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.11.1.tgz", + "integrity": "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.11.1.tgz", + "integrity": "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==", + "license": "MIT", + "dependencies": { + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-builder": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", + "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==", + "dev": true, + "license": "MIT/X11" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/computeds": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", + "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dayjs": { + "version": "1.11.19", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "license": "MIT" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/element-plus": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.12.0.tgz", + "integrity": "sha512-M9YLSn2np9OnqrSKWsiXvGe3qnF8pd94+TScsHj1aTMCD+nSEvucXermf807qNt6hOP040le0e5Aft7E9ZfHmA==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^3.4.1", + "@element-plus/icons-vue": "^2.3.2", + "@floating-ui/dom": "^1.0.1", + "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", + "@types/lodash": "^4.17.20", + "@types/lodash-es": "^4.17.12", + "@vueuse/core": "^9.1.0", + "async-validator": "^4.2.5", + "dayjs": "^1.11.19", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.3", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.2.0" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/element-plus/node_modules/@types/web-bluetooth": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", + "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==", + "license": "MIT" + }, + "node_modules/element-plus/node_modules/@vueuse/core": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz", + "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "9.13.0", + "@vueuse/shared": "9.13.0", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/element-plus/node_modules/@vueuse/metadata": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz", + "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/element-plus/node_modules/@vueuse/shared": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz", + "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==", + "license": "MIT", + "dependencies": { + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/immutable": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash-unified": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz", + "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", + "license": "MIT", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "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/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/muggle-string": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", + "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/normalize-wheel-es": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", + "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==", + "license": "BSD-3-Clause" + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pinia": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz", + "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rollup": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/sass": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.96.0.tgz", + "integrity": "sha512-8u4xqqUeugGNCYwr9ARNtQKTOj4KmYiJAVKXf2CTIivTCR51j96htbMKWDru8H5SaQWpyVgTfOF8Ylyf5pun1Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-embedded": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.96.0.tgz", + "integrity": "sha512-z9PQ7owvdhn7UuZGrpPccdkcH9xJd9iCv+UQhcPqppBslYEp0R9LRQVyyPTZg7jfA77bGxz/I8V48LXJR5LjXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bufbuild/protobuf": "^2.5.0", + "buffer-builder": "^0.2.0", + "colorjs.io": "^0.5.0", + "immutable": "^5.0.2", + "rxjs": "^7.4.0", + "supports-color": "^8.1.1", + "sync-child-process": "^1.0.2", + "varint": "^6.0.0" + }, + "bin": { + "sass": "dist/bin/sass.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "optionalDependencies": { + "sass-embedded-all-unknown": "1.96.0", + "sass-embedded-android-arm": "1.96.0", + "sass-embedded-android-arm64": "1.96.0", + "sass-embedded-android-riscv64": "1.96.0", + "sass-embedded-android-x64": "1.96.0", + "sass-embedded-darwin-arm64": "1.96.0", + "sass-embedded-darwin-x64": "1.96.0", + "sass-embedded-linux-arm": "1.96.0", + "sass-embedded-linux-arm64": "1.96.0", + "sass-embedded-linux-musl-arm": "1.96.0", + "sass-embedded-linux-musl-arm64": "1.96.0", + "sass-embedded-linux-musl-riscv64": "1.96.0", + "sass-embedded-linux-musl-x64": "1.96.0", + "sass-embedded-linux-riscv64": "1.96.0", + "sass-embedded-linux-x64": "1.96.0", + "sass-embedded-unknown-all": "1.96.0", + "sass-embedded-win32-arm64": "1.96.0", + "sass-embedded-win32-x64": "1.96.0" + } + }, + "node_modules/sass-embedded-all-unknown": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.96.0.tgz", + "integrity": "sha512-UfUHoWZtxmsDjDfK+fKCy0aJe6zThu7oaIQx0c/vnHgvprcddEPIay01qTXhiUa3cFcsMmvlBvPTVw0gjKVtVQ==", + "cpu": [ + "!arm", + "!arm64", + "!riscv64", + "!x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "sass": "1.96.0" + } + }, + "node_modules/sass-embedded-android-arm": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.96.0.tgz", + "integrity": "sha512-0mwVRBFig9hH8vFcRExBuBoR+CfUOcWdwarZwbxIFGI1IyH4BLBGiX85vVn6ssSCVNydpE6lFGm45CN8O0tQig==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-arm64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.96.0.tgz", + "integrity": "sha512-TJiebTo4TBF5Wrn+lFkUfSN3wazvl8kkFm9a1nA9ZtRdaE0nsJLGnMM6KLQLP2Vl+IOf6ovetZseISkClRoGXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-riscv64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.96.0.tgz", + "integrity": "sha512-7AVu/EeJqKN3BGNhm+tc1XzmoqbOtCwHG2VgN6j6Lyqh1JZlx0dglRtyQuKDZ7odTKiWmotEIuYZ6OxLmr2Ejg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-x64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.96.0.tgz", + "integrity": "sha512-ei/UsT0q8rF5JzWhn1A7B0M1y/IiWVY3l4zibQrXk5MGaOXHlCM6ffZD+2j7C613Jm9/KAQ7yX1NIIu72LPgDQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-arm64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.96.0.tgz", + "integrity": "sha512-OMvN5NWcrrisC24ZR3GyaWJ1uFxw25qLnUkpEso9TSlaMWiomjU82/uQ/AkQvIMl+EMlJqeYLxZWvq/byLH5Xg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-x64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.96.0.tgz", + "integrity": "sha512-J/R5sv0eW+/DU98rccHPO1f3lsTFjVTpdkU9d3P1yB7BFmQjw5PYde9BVRlXeOawPwfgT3p/hvY4RELScICdww==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.96.0.tgz", + "integrity": "sha512-XuQvV6gNld5Bz3rX0SFLtKPGMu4UQdXNp//9A+bDmtVGZ6yu8REIqphQBxOMpgkAKsA4JZLKKk1N97woeVsIlA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.96.0.tgz", + "integrity": "sha512-VcbVjK0/O/mru0h0FC1WSUWIzMqRrzuJ8eZNMXTs4vApfkh28pxNaUodwU81f1L1nngJ3vpFDBniUKpW6NwJhw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.96.0.tgz", + "integrity": "sha512-qK7FrnczCVECZXtyYOoI3azFlMDZn70GI1yJPPuZLpWvwIPYoZOLv3u6JSec5o3wT6KeKyWG3ZpGIpigLUjPig==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.96.0.tgz", + "integrity": "sha512-lVyLObEeu8Wgw8riC6dSMlkF7jVNAjdZ1jIBhvX1yDsrQwwaI60pM21YXmnZSFyCE6KVFkKAgwRQNO/IkoCwMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-riscv64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.96.0.tgz", + "integrity": "sha512-Y+DuGVRsM2zGl268QN5aF/Y6OFYTILb3f+6huEXKlGL6FK2MXadsmeoVbmKVrTamQHzyA2bWWMU1C0jhVFtlzg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-x64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.96.0.tgz", + "integrity": "sha512-sAQtUQ8fFNxnxSf3fncOh892Hfxa4PW4e5qrnSE0Y1IGV/wsTzk7m5Z6IeT7sa3BsvXh5TFN6+JGbUoOJ5RigA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-riscv64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.96.0.tgz", + "integrity": "sha512-Bf6bAjuUm6sfGHo0XoZEstjVkEWwmmtOSomGoPuAwXFS9GQnFcqDz9EXKNkZEOsQi2D+aDeDxs8HcU9/OLMT9g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-x64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.96.0.tgz", + "integrity": "sha512-U4GROkS0XM6ekqs/ubroWwFAGY9N35wqrt5q6Y+MJCpTK5bHPHlgFo7J75ZUSaEObL+UrDqvMDQkCdYEFiiQbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-unknown-all": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.96.0.tgz", + "integrity": "sha512-OHzGEr2VElK2SaQdkkTX0O0KwTbiv1N/EhnHgzXYaZWOTvv0gxEfR7q7x/oScCBIZc2x8dSfvThfBnohIClo/w==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "!android", + "!darwin", + "!linux", + "!win32" + ], + "dependencies": { + "sass": "1.96.0" + } + }, + "node_modules/sass-embedded-win32-arm64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.96.0.tgz", + "integrity": "sha512-KKz1h5pr45fwrKcxrxHsujo3f/HgVkX64YNJ9PRPuOuX7lU8g18IEgDxoTGQ64PPBQ5RXOt6jxpT+x2OLPVnCw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-x64": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.96.0.tgz", + "integrity": "sha512-MDreKaWcgiyKD5YPShaRvUBoe5dC2y8IPJK49G7iQjoMfw9INDCBkDdLcz00Mn0eJq4nJJp5UEE98M6ljIrBRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/sync-child-process": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/sync-child-process/-/sync-child-process-1.0.2.tgz", + "integrity": "sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sync-message-port": "^1.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/sync-message-port": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sync-message-port/-/sync-message-port-1.1.3.tgz", + "integrity": "sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.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==", + "dev": true, + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.25.tgz", + "integrity": "sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-sfc": "3.5.25", + "@vue/runtime-dom": "3.5.25", + "@vue/server-renderer": "3.5.25", + "@vue/shared": "3.5.25" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/vue-tsc": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", + "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "~1.11.1", + "@vue/language-core": "1.8.27", + "semver": "^7.5.4" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": "*" + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..8a358b4 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,31 @@ +{ + "name": "flow-orchestration-frontend", + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@element-plus/icons-vue": "^2.3.0", + "@iconify/json": "^2.2.417", + "@iconify/vue": "^5.0.0", + "@vue-flow/background": "^1.3.0", + "@vue-flow/controls": "^1.1.0", + "@vue-flow/core": "^1.33.0", + "@vue-flow/minimap": "^1.4.0", + "axios": "^1.6.0", + "element-plus": "^2.5.0", + "pinia": "^2.1.0", + "vue": "^3.4.0" + }, + "devDependencies": { + "@types/node": "^25.0.1", + "@vitejs/plugin-vue": "^5.0.0", + "sass-embedded": "^1.96.0", + "typescript": "^5.3.0", + "vite": "^5.0.0", + "vue-tsc": "^1.8.0" + } +} diff --git a/frontend/src/App.vue b/frontend/src/App.vue new file mode 100644 index 0000000..cf171a0 --- /dev/null +++ b/frontend/src/App.vue @@ -0,0 +1,498 @@ + + + + + diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts new file mode 100644 index 0000000..0a26d11 --- /dev/null +++ b/frontend/src/api/index.ts @@ -0,0 +1,23 @@ +import axios from 'axios' + +const api = axios.create({ baseURL: '/api' }) + +export interface FlowSchema { + flowId: string + nodes: any[] + edges: any[] + runtime_data?: Record +} + +export const flowApi = { + create: (name: string, schema: FlowSchema) => api.post('/flows', { name, schema_json: schema }), + update: (id: string, name: string, schema: FlowSchema) => api.put(`/flows/${id}`, { name, schema_json: schema }), + get: (id: string) => api.get(`/flows/${id}`), + execute: (id: string, runtimeData?: Record) => api.post(`/flows/${id}/execute`, { runtime_data: runtimeData }), + getExecution: (execId: string) => api.get(`/flows/executions/${execId}`) +} + +export const createWebSocket = (executionId: string): WebSocket => { + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:' + return new WebSocket(`${protocol}//${window.location.host}/ws/flows/${executionId}`) +} diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css new file mode 100644 index 0000000..7aa9795 --- /dev/null +++ b/frontend/src/assets/main.css @@ -0,0 +1,54 @@ +* { margin: 0; padding: 0; box-sizing: border-box; } +html, body, #app { width: 100%; height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; } + +.layout { display: flex; height: 100%; } + +/* 左侧边栏 */ +.sidebar { width: 200px; background: #f5f5f5; border-right: 1px solid #e0e0e0; display: flex; flex-direction: column; } +.sidebar-header { padding: 16px; border-bottom: 1px solid #e0e0e0; } +.sidebar-header h2 { color: #333; font-size: 16px; font-weight: 600; } +.sidebar-section { padding: 12px; } +.sidebar-section-title { color: #666; font-size: 12px; margin-bottom: 10px; font-weight: 500; } +.node-list { display: flex; flex-direction: column; gap: 6px; } +.node-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 6px; cursor: grab; color: #333; font-size: 13px; background: #fff; border: 1px solid #e0e0e0; transition: all 0.2s; } +.node-item:hover { border-color: #1890ff; box-shadow: 0 2px 8px rgba(24,144,255,0.15); } +.node-item:active { cursor: grabbing; } +.node-item .icon { width: 28px; height: 28px; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 14px; color: #fff; } +.sidebar-stats { margin-top: auto; padding: 12px; border-top: 1px solid #e0e0e0; display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: #666; } + +/* 主画布区域 */ +.main-area { flex: 1; display: flex; flex-direction: column; background: #fafafa; } +.toolbar { display: flex; align-items: center; padding: 10px 16px; background: #fff; border-bottom: 1px solid #e0e0e0; } +.toolbar-left { display: flex; gap: 8px; } +.flow-canvas { flex: 1; position: relative; } + +/* 右侧配置面板 */ +.config-panel { width: 280px; background: #fff; border-left: 1px solid #e0e0e0; display: flex; flex-direction: column; } +.config-header { padding: 14px 16px; border-bottom: 1px solid #e0e0e0; display: flex; align-items: center; justify-content: space-between; } +.config-header h3 { color: #333; font-size: 14px; font-weight: 600; } +.config-body { flex: 1; padding: 16px; overflow-y: auto; } +.config-row { margin-bottom: 16px; } +.config-row label { display: block; color: #666; font-size: 12px; margin-bottom: 6px; } + +/* Vue Flow */ +.vue-flow { background: #fafafa !important; } +.vue-flow__node { border-radius: 8px; font-size: 13px; } +.vue-flow__edge-path { stroke: #b0b0b0; stroke-width: 2; } +.vue-flow__handle { + width: 10px !important; + height: 10px !important; + background: #1890ff !important; + border: 2px solid #fff !important; + border-radius: 50% !important; + box-shadow: 0 0 4px rgba(0,0,0,0.2) !important; +} + +/* 节点状态 */ +.vue-flow__node.running { box-shadow: 0 0 0 2px #faad14, 0 4px 12px rgba(250,173,20,0.3); animation: pulse 1s infinite; } +.vue-flow__node.success { box-shadow: 0 0 0 2px #52c41a, 0 4px 12px rgba(82,196,26,0.3); } +.vue-flow__node.error { box-shadow: 0 0 0 2px #f5222d, 0 4px 12px rgba(245,34,45,0.3); } + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.7; } +} diff --git a/frontend/src/components/ContextMenu.vue b/frontend/src/components/ContextMenu.vue new file mode 100644 index 0000000..6c363e9 --- /dev/null +++ b/frontend/src/components/ContextMenu.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/frontend/src/components/ContextMenuList.vue b/frontend/src/components/ContextMenuList.vue new file mode 100644 index 0000000..1098b2f --- /dev/null +++ b/frontend/src/components/ContextMenuList.vue @@ -0,0 +1,187 @@ + + + + + diff --git a/frontend/src/components/PropertyPanel.vue b/frontend/src/components/PropertyPanel.vue new file mode 100644 index 0000000..54db8b9 --- /dev/null +++ b/frontend/src/components/PropertyPanel.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/frontend/src/components/nodes/AggregationNode/index.scss b/frontend/src/components/nodes/AggregationNode/index.scss new file mode 100644 index 0000000..2277e96 --- /dev/null +++ b/frontend/src/components/nodes/AggregationNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-aggregationNode) { + min-width: 230px; +} diff --git a/frontend/src/components/nodes/AggregationNode/index.ts b/frontend/src/components/nodes/AggregationNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/AggregationNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/AggregationNode/index.vue b/frontend/src/components/nodes/AggregationNode/index.vue new file mode 100644 index 0000000..80fda6c --- /dev/null +++ b/frontend/src/components/nodes/AggregationNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/AggregationNode/types.ts b/frontend/src/components/nodes/AggregationNode/types.ts new file mode 100644 index 0000000..b8e1389 --- /dev/null +++ b/frontend/src/components/nodes/AggregationNode/types.ts @@ -0,0 +1,10 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface AggregationNodeData { + metric?: string + dimension?: string + window?: string + status?: string +} + +export type AggregationNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/ConditionalNode/index.scss b/frontend/src/components/nodes/ConditionalNode/index.scss new file mode 100644 index 0000000..5364184 --- /dev/null +++ b/frontend/src/components/nodes/ConditionalNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-conditionalNode) { + min-width: 240px; +} diff --git a/frontend/src/components/nodes/ConditionalNode/index.ts b/frontend/src/components/nodes/ConditionalNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/ConditionalNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/ConditionalNode/index.vue b/frontend/src/components/nodes/ConditionalNode/index.vue new file mode 100644 index 0000000..f254c0f --- /dev/null +++ b/frontend/src/components/nodes/ConditionalNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/ConditionalNode/types.ts b/frontend/src/components/nodes/ConditionalNode/types.ts new file mode 100644 index 0000000..88d93d7 --- /dev/null +++ b/frontend/src/components/nodes/ConditionalNode/types.ts @@ -0,0 +1,11 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface ConditionalNodeData { + expression?: string + trueLabel?: string + falseLabel?: string + mode?: string + status?: string +} + +export type ConditionalNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/ContainerNode/index.scss b/frontend/src/components/nodes/ContainerNode/index.scss new file mode 100644 index 0000000..74a8545 --- /dev/null +++ b/frontend/src/components/nodes/ContainerNode/index.scss @@ -0,0 +1,91 @@ +.container-node { + position: relative; + border: 2px dashed rgba(91, 143, 249, 0.6); + border-radius: 16px; + background: rgba(91, 143, 249, 0.04); + padding: 16px; + min-width: 320px; + min-height: 200px; + display: flex; + flex-direction: column; + gap: 12px; + transition: border-color 0.2s; +} + +.container-node.is-selected { + border-style: solid; +} + +.container-node__header { + display: flex; + align-items: center; + justify-content: space-between; + font-weight: 600; + color: #1f2329; +} + +.container-node__header .title { + display: inline-flex; + align-items: center; + gap: 6px; +} + +.container-node__header .actions { + display: flex; + gap: 6px; +} + +.ghost-btn { + border: none; + padding: 4px; + background: rgba(0, 0, 0, 0.04); + border-radius: 6px; + cursor: pointer; + transition: background 0.2s; +} + +.ghost-btn:hover { + background: rgba(0, 0, 0, 0.08); +} + +.container-node__body { + flex: 1; + background: rgba(255, 255, 255, 0.8); + border-radius: 12px; + padding: 12px; + font-size: 12px; + color: #4a4a4a; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.container-node__stats { + display: flex; + justify-content: space-between; + color: #8c8c8c; + font-size: 11px; +} + +.container-node__resize { + position: absolute; + right: 8px; + bottom: 8px; + width: 20px; + height: 20px; + border-radius: 6px; + background: rgba(0, 0, 0, 0.05); + display: flex; + align-items: center; + justify-content: center; + cursor: se-resize; +} + +.container-node.is-resizing .container-node__resize { + background: rgba(91, 143, 249, 0.2); +} + +:global(.vue-flow__node-containerNode .vue-flow__handle) { + background: #fff; + border-color: rgba(91, 143, 249, 0.8); +} diff --git a/frontend/src/components/nodes/ContainerNode/index.ts b/frontend/src/components/nodes/ContainerNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/ContainerNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/ContainerNode/index.vue b/frontend/src/components/nodes/ContainerNode/index.vue new file mode 100644 index 0000000..78656ce --- /dev/null +++ b/frontend/src/components/nodes/ContainerNode/index.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/frontend/src/components/nodes/ContainerNode/types.ts b/frontend/src/components/nodes/ContainerNode/types.ts new file mode 100644 index 0000000..56a183f --- /dev/null +++ b/frontend/src/components/nodes/ContainerNode/types.ts @@ -0,0 +1,16 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface ContainerNodeSize { + width: number + height: number +} + +export interface ContainerNodeData { + title?: string + description?: string + color?: string + autoSize?: boolean + size?: ContainerNodeSize +} + +export type ContainerNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/DataInputNode/index.scss b/frontend/src/components/nodes/DataInputNode/index.scss new file mode 100644 index 0000000..4df2d1f --- /dev/null +++ b/frontend/src/components/nodes/DataInputNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-dataInputNode) { + min-width: 200px; +} diff --git a/frontend/src/components/nodes/DataInputNode/index.ts b/frontend/src/components/nodes/DataInputNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/DataInputNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/DataInputNode/index.vue b/frontend/src/components/nodes/DataInputNode/index.vue new file mode 100644 index 0000000..85b558e --- /dev/null +++ b/frontend/src/components/nodes/DataInputNode/index.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/frontend/src/components/nodes/DataInputNode/types.ts b/frontend/src/components/nodes/DataInputNode/types.ts new file mode 100644 index 0000000..40c9d42 --- /dev/null +++ b/frontend/src/components/nodes/DataInputNode/types.ts @@ -0,0 +1,10 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface DataInputNodeData { + sourceType?: string + filePath?: string + format?: string + status?: string +} + +export type DataInputNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/DataOutputNode/index.scss b/frontend/src/components/nodes/DataOutputNode/index.scss new file mode 100644 index 0000000..88bfffe --- /dev/null +++ b/frontend/src/components/nodes/DataOutputNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-dataOutputNode) { + min-width: 220px; +} diff --git a/frontend/src/components/nodes/DataOutputNode/index.ts b/frontend/src/components/nodes/DataOutputNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/DataOutputNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/DataOutputNode/index.vue b/frontend/src/components/nodes/DataOutputNode/index.vue new file mode 100644 index 0000000..6b572fa --- /dev/null +++ b/frontend/src/components/nodes/DataOutputNode/index.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/frontend/src/components/nodes/DataOutputNode/types.ts b/frontend/src/components/nodes/DataOutputNode/types.ts new file mode 100644 index 0000000..165c5fa --- /dev/null +++ b/frontend/src/components/nodes/DataOutputNode/types.ts @@ -0,0 +1,10 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface DataOutputNodeData { + destination?: string + format?: string + strategy?: string + status?: string +} + +export type DataOutputNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/DataTransferNode/index.scss b/frontend/src/components/nodes/DataTransferNode/index.scss new file mode 100644 index 0000000..34bec7c --- /dev/null +++ b/frontend/src/components/nodes/DataTransferNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-dataTransferNode) { + min-width: 230px; +} diff --git a/frontend/src/components/nodes/DataTransferNode/index.ts b/frontend/src/components/nodes/DataTransferNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/DataTransferNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/DataTransferNode/index.vue b/frontend/src/components/nodes/DataTransferNode/index.vue new file mode 100644 index 0000000..dce9ff9 --- /dev/null +++ b/frontend/src/components/nodes/DataTransferNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/DataTransferNode/types.ts b/frontend/src/components/nodes/DataTransferNode/types.ts new file mode 100644 index 0000000..a20a599 --- /dev/null +++ b/frontend/src/components/nodes/DataTransferNode/types.ts @@ -0,0 +1,10 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface DataTransferNodeData { + source?: string + target?: string + protocol?: string + status?: string +} + +export type DataTransferNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/DelayNode/index.scss b/frontend/src/components/nodes/DelayNode/index.scss new file mode 100644 index 0000000..10ee9a0 --- /dev/null +++ b/frontend/src/components/nodes/DelayNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-delayNode) { + min-width: 190px; +} diff --git a/frontend/src/components/nodes/DelayNode/index.ts b/frontend/src/components/nodes/DelayNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/DelayNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/DelayNode/index.vue b/frontend/src/components/nodes/DelayNode/index.vue new file mode 100644 index 0000000..71cc5f7 --- /dev/null +++ b/frontend/src/components/nodes/DelayNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/DelayNode/types.ts b/frontend/src/components/nodes/DelayNode/types.ts new file mode 100644 index 0000000..4d7fee2 --- /dev/null +++ b/frontend/src/components/nodes/DelayNode/types.ts @@ -0,0 +1,9 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface DelayNodeData { + duration?: number + mode?: string + status?: string +} + +export type DelayNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/HttpNode/index.scss b/frontend/src/components/nodes/HttpNode/index.scss new file mode 100644 index 0000000..f46866c --- /dev/null +++ b/frontend/src/components/nodes/HttpNode/index.scss @@ -0,0 +1,11 @@ +:global(.vue-flow__node-httpNode) { + min-width: 260px; +} + +.url-row .row-value { + max-width: 140px; + display: inline-block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/frontend/src/components/nodes/HttpNode/index.ts b/frontend/src/components/nodes/HttpNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/HttpNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/HttpNode/index.vue b/frontend/src/components/nodes/HttpNode/index.vue new file mode 100644 index 0000000..039813f --- /dev/null +++ b/frontend/src/components/nodes/HttpNode/index.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/frontend/src/components/nodes/HttpNode/types.ts b/frontend/src/components/nodes/HttpNode/types.ts new file mode 100644 index 0000000..e975fc4 --- /dev/null +++ b/frontend/src/components/nodes/HttpNode/types.ts @@ -0,0 +1,9 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface HttpNodeData { + method?: string + url?: string + status?: string +} + +export type HttpNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/ImageNode/index.scss b/frontend/src/components/nodes/ImageNode/index.scss new file mode 100644 index 0000000..b17f568 --- /dev/null +++ b/frontend/src/components/nodes/ImageNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-imageNode) { + min-width: 220px; +} diff --git a/frontend/src/components/nodes/ImageNode/index.ts b/frontend/src/components/nodes/ImageNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/ImageNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/ImageNode/index.vue b/frontend/src/components/nodes/ImageNode/index.vue new file mode 100644 index 0000000..30ec116 --- /dev/null +++ b/frontend/src/components/nodes/ImageNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/ImageNode/types.ts b/frontend/src/components/nodes/ImageNode/types.ts new file mode 100644 index 0000000..8673897 --- /dev/null +++ b/frontend/src/components/nodes/ImageNode/types.ts @@ -0,0 +1,9 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface ImageNodeData { + operation?: string + resolution?: string + status?: string +} + +export type ImageNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/IntentNode/index.scss b/frontend/src/components/nodes/IntentNode/index.scss new file mode 100644 index 0000000..5632da3 --- /dev/null +++ b/frontend/src/components/nodes/IntentNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-intentNode) { + min-width: 210px; +} diff --git a/frontend/src/components/nodes/IntentNode/index.ts b/frontend/src/components/nodes/IntentNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/IntentNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/IntentNode/index.vue b/frontend/src/components/nodes/IntentNode/index.vue new file mode 100644 index 0000000..5e3b035 --- /dev/null +++ b/frontend/src/components/nodes/IntentNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/IntentNode/types.ts b/frontend/src/components/nodes/IntentNode/types.ts new file mode 100644 index 0000000..5255bee --- /dev/null +++ b/frontend/src/components/nodes/IntentNode/types.ts @@ -0,0 +1,10 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface IntentNodeData { + intents?: string[] + confidence?: number + domain?: string + status?: string +} + +export type IntentNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/LLMNode/index.scss b/frontend/src/components/nodes/LLMNode/index.scss new file mode 100644 index 0000000..4368184 --- /dev/null +++ b/frontend/src/components/nodes/LLMNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-llmNode) { + min-width: 220px; +} diff --git a/frontend/src/components/nodes/LLMNode/index.ts b/frontend/src/components/nodes/LLMNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/LLMNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/LLMNode/index.vue b/frontend/src/components/nodes/LLMNode/index.vue new file mode 100644 index 0000000..5a738bb --- /dev/null +++ b/frontend/src/components/nodes/LLMNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/LLMNode/types.ts b/frontend/src/components/nodes/LLMNode/types.ts new file mode 100644 index 0000000..ea830eb --- /dev/null +++ b/frontend/src/components/nodes/LLMNode/types.ts @@ -0,0 +1,9 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface LLMNodeData { + model?: string + temperature?: number + status?: string +} + +export type LLMNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/LoopNode/index.scss b/frontend/src/components/nodes/LoopNode/index.scss new file mode 100644 index 0000000..62043f0 --- /dev/null +++ b/frontend/src/components/nodes/LoopNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-loopNode) { + min-width: 210px; +} diff --git a/frontend/src/components/nodes/LoopNode/index.ts b/frontend/src/components/nodes/LoopNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/LoopNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/LoopNode/index.vue b/frontend/src/components/nodes/LoopNode/index.vue new file mode 100644 index 0000000..8b3943c --- /dev/null +++ b/frontend/src/components/nodes/LoopNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/LoopNode/types.ts b/frontend/src/components/nodes/LoopNode/types.ts new file mode 100644 index 0000000..83f2ec3 --- /dev/null +++ b/frontend/src/components/nodes/LoopNode/types.ts @@ -0,0 +1,10 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface LoopNodeData { + iterations?: number + iterator?: string + mode?: string + status?: string +} + +export type LoopNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/MCPNode/index.scss b/frontend/src/components/nodes/MCPNode/index.scss new file mode 100644 index 0000000..8af4ff1 --- /dev/null +++ b/frontend/src/components/nodes/MCPNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-mcpNode) { + min-width: 210px; +} diff --git a/frontend/src/components/nodes/MCPNode/index.ts b/frontend/src/components/nodes/MCPNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/MCPNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/MCPNode/index.vue b/frontend/src/components/nodes/MCPNode/index.vue new file mode 100644 index 0000000..2f24055 --- /dev/null +++ b/frontend/src/components/nodes/MCPNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/MCPNode/types.ts b/frontend/src/components/nodes/MCPNode/types.ts new file mode 100644 index 0000000..4f5eea4 --- /dev/null +++ b/frontend/src/components/nodes/MCPNode/types.ts @@ -0,0 +1,9 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface MCPNodeData { + service?: string + action?: string + status?: string +} + +export type MCPNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/ScriptNode/index.scss b/frontend/src/components/nodes/ScriptNode/index.scss new file mode 100644 index 0000000..86e56d0 --- /dev/null +++ b/frontend/src/components/nodes/ScriptNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-scriptNode) { + min-width: 220px; +} diff --git a/frontend/src/components/nodes/ScriptNode/index.ts b/frontend/src/components/nodes/ScriptNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/ScriptNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/ScriptNode/index.vue b/frontend/src/components/nodes/ScriptNode/index.vue new file mode 100644 index 0000000..137cab6 --- /dev/null +++ b/frontend/src/components/nodes/ScriptNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/ScriptNode/types.ts b/frontend/src/components/nodes/ScriptNode/types.ts new file mode 100644 index 0000000..23d446f --- /dev/null +++ b/frontend/src/components/nodes/ScriptNode/types.ts @@ -0,0 +1,10 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface ScriptNodeData { + language?: string + entry?: string + dependencies?: number + status?: string +} + +export type ScriptNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/UdpNode/index.scss b/frontend/src/components/nodes/UdpNode/index.scss new file mode 100644 index 0000000..7ed0f92 --- /dev/null +++ b/frontend/src/components/nodes/UdpNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-udpNode) { + min-width: 210px; +} diff --git a/frontend/src/components/nodes/UdpNode/index.ts b/frontend/src/components/nodes/UdpNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/UdpNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/UdpNode/index.vue b/frontend/src/components/nodes/UdpNode/index.vue new file mode 100644 index 0000000..b321251 --- /dev/null +++ b/frontend/src/components/nodes/UdpNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/UdpNode/types.ts b/frontend/src/components/nodes/UdpNode/types.ts new file mode 100644 index 0000000..83bf123 --- /dev/null +++ b/frontend/src/components/nodes/UdpNode/types.ts @@ -0,0 +1,9 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface UdpNodeData { + host?: string + port?: number + status?: string +} + +export type UdpNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/WebhookNode/index.scss b/frontend/src/components/nodes/WebhookNode/index.scss new file mode 100644 index 0000000..1fb9c0c --- /dev/null +++ b/frontend/src/components/nodes/WebhookNode/index.scss @@ -0,0 +1,3 @@ +:global(.vue-flow__node-webhookNode) { + min-width: 240px; +} diff --git a/frontend/src/components/nodes/WebhookNode/index.ts b/frontend/src/components/nodes/WebhookNode/index.ts new file mode 100644 index 0000000..336ce12 --- /dev/null +++ b/frontend/src/components/nodes/WebhookNode/index.ts @@ -0,0 +1 @@ +export {} diff --git a/frontend/src/components/nodes/WebhookNode/index.vue b/frontend/src/components/nodes/WebhookNode/index.vue new file mode 100644 index 0000000..8efc8fc --- /dev/null +++ b/frontend/src/components/nodes/WebhookNode/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/src/components/nodes/WebhookNode/types.ts b/frontend/src/components/nodes/WebhookNode/types.ts new file mode 100644 index 0000000..bba0905 --- /dev/null +++ b/frontend/src/components/nodes/WebhookNode/types.ts @@ -0,0 +1,10 @@ +import type { BaseNodeProps } from '../shared/types' + +export interface WebhookNodeData { + endpoint?: string + method?: string + retries?: number + status?: string +} + +export type WebhookNodeProps = BaseNodeProps diff --git a/frontend/src/components/nodes/index.ts b/frontend/src/components/nodes/index.ts new file mode 100644 index 0000000..0fd4884 --- /dev/null +++ b/frontend/src/components/nodes/index.ts @@ -0,0 +1,36 @@ +import { markRaw } from 'vue' +import AggregationNode from './AggregationNode/index.vue' +import ConditionalNode from './ConditionalNode/index.vue' +import ContainerNode from './ContainerNode/index.vue' +import DataInputNode from './DataInputNode/index.vue' +import DataOutputNode from './DataOutputNode/index.vue' +import DataTransferNode from './DataTransferNode/index.vue' +import DelayNode from './DelayNode/index.vue' +import HttpNode from './HttpNode/index.vue' +import ImageNode from './ImageNode/index.vue' +import IntentNode from './IntentNode/index.vue' +import LLMNode from './LLMNode/index.vue' +import LoopNode from './LoopNode/index.vue' +import MCPNode from './MCPNode/index.vue' +import ScriptNode from './ScriptNode/index.vue' +import UdpNode from './UdpNode/index.vue' +import WebhookNode from './WebhookNode/index.vue' + +export const nodeTypes = { + dataInputNode: markRaw(DataInputNode), + dataTransferNode: markRaw(DataTransferNode), + dataOutputNode: markRaw(DataOutputNode), + llmNode: markRaw(LLMNode), + intentNode: markRaw(IntentNode), + mcpNode: markRaw(MCPNode), + httpNode: markRaw(HttpNode), + udpNode: markRaw(UdpNode), + conditionalNode: markRaw(ConditionalNode), + delayNode: markRaw(DelayNode), + loopNode: markRaw(LoopNode), + scriptNode: markRaw(ScriptNode), + imageNode: markRaw(ImageNode), + aggregationNode: markRaw(AggregationNode), + webhookNode: markRaw(WebhookNode), + containerNode: markRaw(ContainerNode) +} diff --git a/frontend/src/components/nodes/shared/StandardNode.vue b/frontend/src/components/nodes/shared/StandardNode.vue new file mode 100644 index 0000000..bbc3bd8 --- /dev/null +++ b/frontend/src/components/nodes/shared/StandardNode.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/frontend/src/components/nodes/shared/standard-node.scss b/frontend/src/components/nodes/shared/standard-node.scss new file mode 100644 index 0000000..70ebc03 --- /dev/null +++ b/frontend/src/components/nodes/shared/standard-node.scss @@ -0,0 +1,114 @@ +.standard-node { + position: relative; + min-width: 160px; + min-height: 96px; + padding: 12px 14px; + background: #fff; + border: 2px solid rgba(0, 0, 0, 0.08); + border-radius: 10px; + box-shadow: 0 4px 16px rgba(24, 39, 75, 0.08); + display: flex; + flex-direction: column; + gap: 8px; + transition: border-color 0.2s, box-shadow 0.2s; +} + +.standard-node.is-selected { + border-color: var(--node-accent, #409eff); + box-shadow: 0 8px 20px rgba(64, 158, 255, 0.25); +} + +.standard-node__header { + display: flex; + align-items: center; + gap: 10px; +} + +.standard-node__icon { + width: 32px; + height: 32px; + border-radius: 8px; + background: rgba(64, 158, 255, 0.08); + color: var(--node-accent, #409eff); + display: flex; + align-items: center; + justify-content: center; +} + +.standard-node__meta { + display: flex; + flex-direction: column; + flex: 1; +} + +.standard-node__title { + font-size: 14px; + font-weight: 600; + color: #1f2329; +} + +.standard-node__subtitle { + font-size: 11px; + color: #8c8c8c; +} + +.standard-node__badge { + font-size: 11px; + padding: 2px 6px; + border-radius: 999px; + background: rgba(64, 158, 255, 0.12); + color: var(--node-accent, #409eff); +} + +.standard-node__body { + display: flex; + flex-direction: column; + gap: 4px; + font-size: 12px; + color: #4a4a4a; +} + +.standard-node__row { + display: flex; + justify-content: space-between; + gap: 8px; +} + +.row-label { + color: #8c8c8c; +} + +.row-value { + color: #1f2329; + font-weight: 500; +} + +.standard-node__footer { + font-size: 11px; + color: #8c8c8c; +} + +.node-status { + display: inline-flex; + align-items: center; + gap: 4px; +} + +.node-status .dot { + width: 6px; + height: 6px; + border-radius: 999px; + background: var(--node-accent, #409eff); + display: inline-flex; +} + +.standard-node__handles { + pointer-events: none; +} + +:deep(.vue-flow__handle) { + background: #fff; + border: 2px solid var(--node-accent, #409eff); + width: 10px; + height: 10px; +} diff --git a/frontend/src/components/nodes/shared/types.ts b/frontend/src/components/nodes/shared/types.ts new file mode 100644 index 0000000..077f6ac --- /dev/null +++ b/frontend/src/components/nodes/shared/types.ts @@ -0,0 +1,42 @@ +import type { Position } from '@vue-flow/core' + +export interface NodeBodyItem { + label: string + value: string +} + +export interface NodeHandleConfig { + inputs?: Position[] + outputs?: Position[] + both?: Position[] +} + +export interface StandardNodeProps { + icon: string + title: string + subtitle?: string + badge?: string + accent?: string + status?: string + bodyItems?: NodeBodyItem[] + handles?: NodeHandleConfig + selected?: boolean +} + +export interface BaseNodeProps> { + id: string + label?: string + selected?: boolean + data: T +} + +export interface StandardNodeOptions { + icon: string + title: string + subtitle?: string + accent?: string + handles?: NodeHandleConfig + badge?: string | ((props: BaseNodeProps) => string | undefined) + status?: (props: BaseNodeProps) => string | undefined + body?: (props: BaseNodeProps) => NodeBodyItem[] +} diff --git a/frontend/src/components/nodes/shared/useStandardNode.ts b/frontend/src/components/nodes/shared/useStandardNode.ts new file mode 100644 index 0000000..f2b267b --- /dev/null +++ b/frontend/src/components/nodes/shared/useStandardNode.ts @@ -0,0 +1,28 @@ +import { computed } from 'vue' +import type { BaseNodeProps, StandardNodeOptions } from './types' + +export function useStandardNode( + props: BaseNodeProps, + options: StandardNodeOptions +) { + const bodyItems = computed(() => { + return options.body ? options.body(props) : [] + }) + + const badge = computed(() => { + if (typeof options.badge === 'function') { + return options.badge(props) + } + return options.badge + }) + + const status = computed(() => options.status?.(props)) + + return { + props, + definition: options, + bodyItems, + badge, + status + } +} diff --git a/frontend/src/data/nodeCatalog.ts b/frontend/src/data/nodeCatalog.ts new file mode 100644 index 0000000..d1c03da --- /dev/null +++ b/frontend/src/data/nodeCatalog.ts @@ -0,0 +1,197 @@ +export interface NodeSize { + width: number + height: number +} + +export interface NodeDescriptor { + type: string + label: string + icon: string + color: string + subtitle?: string + size?: NodeSize + defaults?: Record +} + +export interface NodeCategory { + key: string + label: string + icon: string + nodes: NodeDescriptor[] +} + +const dataNodes: NodeDescriptor[] = [ + { + type: 'dataInputNode', + label: '数据输入', + icon: 'mdi:database-import', + color: '#52c41a', + subtitle: 'Input Stream', + size: { width: 200, height: 120 }, + defaults: { sourceType: '文件', format: '自动检测' } + }, + { + type: 'dataTransferNode', + label: '数据转接', + icon: 'mdi:swap-horizontal', + color: '#1890ff', + subtitle: 'Transfer Hub', + size: { width: 230, height: 120 }, + defaults: { protocol: '自动' } + }, + { + type: 'dataOutputNode', + label: '数据输出', + icon: 'mdi:database-export', + color: '#f5222d', + subtitle: 'Output Sink', + size: { width: 220, height: 120 }, + defaults: { strategy: '即时', format: 'JSON' } + }, + { + type: 'aggregationNode', + label: '聚合节点', + icon: 'mdi:sigma-lower', + color: '#08979c', + subtitle: 'Metrics', + size: { width: 230, height: 130 }, + defaults: { metric: 'count', dimension: 'global' } + } +] + +const aiNodes: NodeDescriptor[] = [ + { + type: 'llmNode', + label: '大模型', + icon: 'mdi:robot', + color: '#722ed1', + subtitle: 'LLM Inference', + size: { width: 220, height: 130 }, + defaults: { model: 'gpt-4o-mini', temperature: 0.7 } + }, + { + type: 'intentNode', + label: '意图识别', + icon: 'mdi:target', + color: '#13c2c2', + subtitle: 'Intent Parser', + size: { width: 210, height: 120 }, + defaults: { domain: '通用', confidence: 80 } + }, + { + type: 'imageNode', + label: '图像处理', + icon: 'mdi:image-filter-center-focus', + color: '#d4380d', + subtitle: 'Vision Ops', + size: { width: 220, height: 130 }, + defaults: { operation: '增强', resolution: 'Auto' } + }, + { + type: 'scriptNode', + label: '脚本节点', + icon: 'mdi:code-tags', + color: '#177ddc', + subtitle: 'Custom Logic', + size: { width: 220, height: 120 }, + defaults: { language: 'TypeScript', entry: 'main' } + } +] + +const integrationNodes: NodeDescriptor[] = [ + { + type: 'httpNode', + label: 'HTTP 请求', + icon: 'mdi:web', + color: '#fa8c16', + subtitle: 'REST Hook', + size: { width: 260, height: 130 }, + defaults: { method: 'GET', url: '' } + }, + { + type: 'webhookNode', + label: 'Webhook', + icon: 'mdi:webhook', + color: '#52c41a', + subtitle: 'Outbound Hook', + size: { width: 240, height: 130 }, + defaults: { method: 'POST', endpoint: '' } + }, + { + type: 'mcpNode', + label: 'MCP 调用', + icon: 'mdi:power-plug', + color: '#eb2f96', + subtitle: 'Service Bridge', + size: { width: 210, height: 120 }, + defaults: { service: '默认服务', action: 'invoke' } + }, + { + type: 'udpNode', + label: 'UDP 发送', + icon: 'mdi:broadcast', + color: '#2f54eb', + subtitle: 'Realtime Push', + size: { width: 210, height: 120 }, + defaults: { host: '127.0.0.1', port: 9000 } + } +] + +const controlNodes: NodeDescriptor[] = [ + { + type: 'conditionalNode', + label: '条件判断', + icon: 'mdi:help-rhombus', + color: '#faad14', + subtitle: 'Flow Control', + size: { width: 240, height: 130 }, + defaults: { expression: 'score > 0.8', trueLabel: '通过', falseLabel: '拦截' } + }, + { + type: 'delayNode', + label: '延迟节点', + icon: 'mdi:timer-sand', + color: '#722ed1', + subtitle: 'Wait / Backoff', + size: { width: 190, height: 110 }, + defaults: { duration: 5, mode: '固定' } + }, + { + type: 'loopNode', + label: '循环节点', + icon: 'mdi:repeat-variant', + color: '#fa541c', + subtitle: 'Iteration', + size: { width: 210, height: 130 }, + defaults: { iterations: 3, iterator: 'item', mode: '次数' } + } +] + +const layoutNodes: NodeDescriptor[] = [ + { + type: 'containerNode', + label: '容器节点', + icon: 'mdi:shape-outline', + color: '#5b8ff9', + subtitle: 'Grouping', + size: { width: 360, height: 240 }, + defaults: { title: '容器', autoSize: true, size: { width: 360, height: 240 } } + } +] + +export const nodeCategories: NodeCategory[] = [ + { key: 'data', label: '数据层', icon: 'mdi:database', nodes: dataNodes }, + { key: 'ai', label: '智能层', icon: 'mdi:robot-happy-outline', nodes: aiNodes }, + { key: 'integrations', label: '集成层', icon: 'mdi:link-variant', nodes: integrationNodes }, + { key: 'control', label: '控制层', icon: 'mdi:axis-arrow', nodes: controlNodes }, + { key: 'structure', label: '结构节点', icon: 'mdi:arrange-bring-forward', nodes: layoutNodes } +] + +export const nodePalette = nodeCategories.flatMap(category => category.nodes) + +export const nodePaletteMap = nodePalette.reduce>((acc, node) => { + acc[node.type] = node + return acc +}, {}) + +export const getNodeDescriptor = (type: string) => nodePaletteMap[type] diff --git a/frontend/src/main.ts b/frontend/src/main.ts new file mode 100644 index 0000000..876d3fa --- /dev/null +++ b/frontend/src/main.ts @@ -0,0 +1,19 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import ElementPlus from 'element-plus' +import 'element-plus/dist/index.css' +import * as ElementPlusIconsVue from '@element-plus/icons-vue' +import App from './App.vue' +import '@vue-flow/core/dist/style.css' +import '@vue-flow/core/dist/theme-default.css' +import './assets/main.css' + +const app = createApp(App) +app.use(createPinia()) +app.use(ElementPlus) + +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component) +} + +app.mount('#app') diff --git a/frontend/src/stores/flow.ts b/frontend/src/stores/flow.ts new file mode 100644 index 0000000..086d6d1 --- /dev/null +++ b/frontend/src/stores/flow.ts @@ -0,0 +1,161 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import type { Edge, Node, XYPosition } from '@vue-flow/core' +import { getNodeDescriptor, nodePaletteMap } from '../data/nodeCatalog' + +interface AddNodeOptions { + data?: Record + parentId?: string +} + +const defaultSize = { width: 200, height: 120 } +const containerPadding = 32 + +export const useFlowStore = defineStore('flow', () => { + const nodes = ref([]) + const edges = ref([]) + const selectedNode = ref(null) + const nodeStatuses = ref>({}) + + const getNodeSize = (type: string) => nodePaletteMap[type]?.size ?? defaultSize + + const addNode = (type: string, position: XYPosition, options: AddNodeOptions = {}) => { + const descriptor = getNodeDescriptor(type) + const id = `${type}_${Date.now()}` + const data = { ...(descriptor?.defaults ?? {}), ...(options.data ?? {}) } + const size = descriptor?.size + const node: Node = { + id, + type, + position, + label: descriptor?.label ?? type, + data, + style: size ? { width: size.width, height: size.height } : undefined + } + + if (options.parentId) { + node.parentNode = options.parentId + node.extent = 'parent' + } + + nodes.value.push(node) + return id + } + + const updateNodeData = (nodeId: string, data: Record) => { + const node = nodes.value.find(n => n.id === nodeId) + if (node) { + node.data = { ...node.data, ...data } + } + } + + const setNodeStatus = (nodeId: string, status: string) => { + nodeStatuses.value[nodeId] = status + updateNodeData(nodeId, { status }) + } + + const clearStatuses = () => { + nodeStatuses.value = {} + } + + const countNodesInContainer = (containerId: string) => { + return nodes.value.filter(n => n.parentNode === containerId).length + } + + const deleteNode = (nodeId: string) => { + const node = nodes.value.find(n => n.id === nodeId) + if (!node) return + if (node.type === 'containerNode') { + const children = nodes.value.filter(n => n.parentNode === nodeId) + children.forEach(child => { + child.parentNode = undefined + child.extent = undefined + child.position = { + x: child.position.x + node.position.x, + y: child.position.y + node.position.y + } + }) + } + + nodes.value = nodes.value.filter(n => n.id !== nodeId) + edges.value = edges.value.filter(e => e.source !== nodeId && e.target !== nodeId) + if (selectedNode.value?.id === nodeId) { + selectedNode.value = null + } + } + + const deleteEdge = (edgeId: string) => { + edges.value = edges.value.filter(e => e.id !== edgeId) + } + + const copyNode = (nodeId: string) => { + const node = nodes.value.find(n => n.id === nodeId) + if (!node) return + const newId = `${node.type}_${Date.now()}` + const newNode: Node = { + ...node, + id: newId, + position: { + x: node.position.x + 40, + y: node.position.y + 40 + }, + data: { ...node.data } + } + nodes.value.push(newNode) + return newId + } + + const autoSizeContainer = (containerId: string) => { + const container = nodes.value.find(n => n.id === containerId) + if (!container) return + const children = nodes.value.filter(n => n.parentNode === containerId) + if (!children.length) { + const fallback = container.data.size ?? nodePaletteMap.containerNode?.size ?? { width: 360, height: 240 } + updateNodeData(containerId, { size: fallback }) + return + } + let maxX = 0 + let maxY = 0 + children.forEach(child => { + const size = getNodeSize(child.type) + maxX = Math.max(maxX, child.position.x + size.width) + maxY = Math.max(maxY, child.position.y + size.height) + }) + updateNodeData(containerId, { + size: { + width: maxX + containerPadding, + height: maxY + containerPadding + } + }) + } + + const findContainerByPoint = (point: XYPosition) => { + return nodes.value.find(node => { + if (node.type !== 'containerNode') return false + const size = (node.data?.size as { width: number; height: number }) ?? nodePaletteMap.containerNode?.size ?? { width: 360, height: 240 } + return ( + point.x >= node.position.x && + point.x <= node.position.x + size.width && + point.y >= node.position.y && + point.y <= node.position.y + size.height + ) + }) + } + + return { + nodes, + edges, + selectedNode, + nodeStatuses, + addNode, + updateNodeData, + setNodeStatus, + clearStatuses, + deleteNode, + deleteEdge, + copyNode, + countNodesInContainer, + autoSizeContainer, + findContainerByPoint + } +}) diff --git a/frontend/src/types/context-menu.ts b/frontend/src/types/context-menu.ts new file mode 100644 index 0000000..747c804 --- /dev/null +++ b/frontend/src/types/context-menu.ts @@ -0,0 +1,8 @@ +export interface ContextMenuItem { + label: string + icon: string + action?: string + disabled?: boolean + payload?: Record + children?: ContextMenuItem[] +} diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts new file mode 100644 index 0000000..b6a7768 --- /dev/null +++ b/frontend/src/vite-env.d.ts @@ -0,0 +1,6 @@ +/// +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..0380b37 --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "jsx": "preserve", + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + "noEmit": true, + "paths": { "@/*": ["./src/*"] } + }, + "include": ["src/**/*", "src/**/*.ts", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/frontend/tsconfig.node.json b/frontend/tsconfig.node.json new file mode 100644 index 0000000..42872c5 --- /dev/null +++ b/frontend/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts new file mode 100644 index 0000000..1e6f657 --- /dev/null +++ b/frontend/vite.config.ts @@ -0,0 +1,26 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import path from 'path' + +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': path.resolve(__dirname, './src') + } + }, + css: { + preprocessorOptions: { + scss: { + api: 'modern-compiler' + } + } + }, + server: { + port: 3000, + proxy: { + '/api': 'http://localhost:8000', + '/ws': { target: 'ws://localhost:8000', ws: true } + } + } +}) diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..8299b31 --- /dev/null +++ b/run.bat @@ -0,0 +1,11 @@ +@echo off +echo 启动开发环境: Client (Vite) + Server (Bun)... + +:: %~dp0 是一个特殊变量,代表当前 .bat 文件所在的文件夹路径 +:: 这使得此脚本可以被移动,只要它和 client/server 文件夹保持相对位置不变 + +set "CLIENT_DIR=%~dp0client-threejs" +set "SERVER_DIR=%~dp0server" + +:: 使用 -d 参数指定每个标签页的工作目录 +wt.exe --title "Client" -d "%CLIENT_DIR%" powershell -NoExit -Command "vite --host" ; new-tab --title "Server" -d "%SERVER_DIR%" powershell -NoExit -Command "bun run index.ts" \ No newline at end of file diff --git a/start.bat b/start.bat new file mode 100644 index 0000000..2874e47 --- /dev/null +++ b/start.bat @@ -0,0 +1,7 @@ +@echo off +chcp 65001 >nul + +set "BACKEND_DIR=%~dp0backend" +set "FRONTEND_DIR=%~dp0frontend" + +wt.exe --title "Backend" -d "%BACKEND_DIR%" cmd /k "bun install & bun dev" ; new-tab --title "Frontend" -d "%FRONTEND_DIR%" cmd /k "npm install & npm run dev" diff --git a/编排.png b/编排.png new file mode 100644 index 0000000000000000000000000000000000000000..3392cb1657f62cdbeb273b04565d4eb45222fcda GIT binary patch literal 130607 zcmd?Rby!s0_co3Rs34L`igZgiC<-Vkh;&GIcMPDEbcu9GN(?!4Np}oGr!>RR-Mri9 z^Lh09i|hUK{pUT`cri!ioPG9Qd#!uj>s}}Dotz}rJ>q+4XlPh(-@H~tLqqpQL%WrX zaTELvs$;DK{J^w%qh^nWhTZ!6&y5%+Y!WoIr)Y0qzf^Kb+L$rcj5eOSyTjz;ON~>p zk@fi*-#dlr1rvhu$vkL=S*&I1XiZIylMuuVN&qc~j*ci#sTmrIMckSx!i0;VfeLdu%+wWog_ZWnaKXm)|1pM6D_C+K9d)|BV z2G`%SxH~sZ{+>O*e|zxn*+)W*v>Sg;e=_5|xb^4ETkWa$-9Kk&WiQaM{+=0q`oH^z z#)s=8WG;NwnyisZ8ft+d-^{rZU@+KyBG&fS_CrjJUv||j2hlGT*1YA2g+Lx7<>Jg5Pj9kJDQSqF{{G?&AvBuGYc}jVB zbaG}~#Dao?Ez(3!TsLENJnPBv7Ez1(mXi!=s~HqBh=r zdQ+2=c6_9G?p@0qpI!`}__cP>CGp$yFbOiHIa?D38-}s}S!Hjva?;zCDH0i{M^j&- zbL3cEFAsB4Q!F2QcN>%zjTY2H&UsP?9CS*zCHa9X@;>Mf0edi9YSX5M0=r?y)*Z%nZ2jLx4)u>o3 z5}pcV468=PLACh(M2*Cl7;u-cprCtmTMd;~Ge+OQ`0w7i(`{f^uWbywpE_V{H-C0^ zW<4hPT2g0j|9m^Kac*gQTRxU4rkm5apOBEy&BZO`F?*8s$l4l8zdgk0=H*^c(01dT zrn)lEWgwk0^enE+l9Pk;n1b&qVQ`Kdrn9}hxzI{YjX;*-M0POvJ69p{eJ%lkGoOc| z&wLBC54&Kd@1vumc`Z)lpvu?B!2>NVbiA&L`TIF_}` zfFt7-q}1#%l1eg1Ht}pCCm)4EHL6t>rl)_#v0LsQVNxk1PO;rxh@JI7S>`I4Ioz&c zqkLU7c6~V30H)PL7H?|2?)VD*^6V&?*Sc{2h$G(OcuTnP;w)bbUVIQr1MEKy zX{l_a>?(eT(x5XUg69KP(WQ~rqO^hf>()wriSX?3a`nxuo>)hLXTWp1Y) zqQ)@ AQnUOtO_zM6bG{N5KQf$SkB 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

p;R>5>pg|09|9P=pY@HE{ zo${%hUNNgD+L&@0$W8DmGEKwAEXx$N7?-}v6GB9><&s%I%xiq@ z=j(Wy3Ltvtbq@4OCCnThMQp~4qoU9zC^rXE^1MBPDCAtDqgG)W(BwCFa1eg;HSmg5 z2GCJ;>urEkVnaiNLV!4Ee${JEfPHk5w10)a^-Jmjn;PUV?3Z(=sYsVU7ObMB$lMI$ z&Acd|myYqk)u=U-YDXpA024!@-v8EnqON8`F;j4Rb#)BTg+Pxp@@%ZH0}0X7APnIr zXlUifAYRu79vW~oE8eaBDb*+gwHAPc^bQdqY5<6bt)h95S5xx`u%SyWf1-gwfNVVs za{)c=H@kMi>F*{_!C%6`f-cI+%4$l2fX0HUkj`7(0pH-bL`p!=?04;9mIVhPEc`am zO#Yb=sV*Fu~@*C0emOC8B5S)Ey459vhQc|I1Wwsez zC^MU2=t?pWAQ1F2$BpvIQpNqZz|R5)Ul2%fZaQ((!x2LTIYtB37g{b990c6RKV zz_H#wD=Vwx@y1}5@1I_9)SE~|R1pZ2%^&W-Sk)#j;ZBns=Z6TfVzyZ){44?w84s0w z0xknB0#usCY_T9Ph^cOqV9_WjC=@AWRW=9#DPKA|I!a3ThmHaCL7rkj*$&+3A07_4 zILgV$FaQjWR3RA~n^J8iAWDz-7bY?W!zujQet4yP`jp#JJ%URN`Upq@NAGy#2w#B) z+Y?u@e3UH!Da4=%b5c^$AgP3<{~Jt1a5-V9v8n0Uzf1rI0Hm`o*Ic|nT@djctKJs? zRN~;^0G#(CiUkX?E+ z_M)E4Gr53Tg#PcvLpcBO7ydP;wxQtwsMB|J_{$+WdwN>V;QGCYcsQ8fk}wv%CSrRd zYGRV>B*4mAbp{6-Y;&GnmkfgbAkwMLWcFS%s9P^YFYK#RK>&E(edmVj#ad3i8g;mc+RKO|n<>ATD(7UWwo`4mL{xDI1 zVdMsicsxKN6)gHeC1-bcA*W^0{kAVDDKj9h2Ao?BeA42Z|8W6$Pz*9(5?}s^CMu-` zFe0in*iKb00NLa>Z{GMB z%LAEGFyrFl;`*XN*#|)Al=2dIxKSO#f1H1QI8)PAprc*qn+^b*l_BHb1O%A)|48{S zm6V1#Er+;PCDu|Ordf8^-^u!L4{!usR;;b5ud1nO*z2q>-Sa3rT080G^W8LjqSRC? zQ?-}>eFykYQKCdG^$iiaXVv8?CEb&=qEsdV{1g!Td}Sx|b(|2%n)ehb(TUB|qR>3b z(g%O=zZZ;u9VbzT52NCN)LLI%j4kRDCQ)A94bwK!)~4$3^V+g>fcM3 z_FfFGW*DMiV!=>d!!{V83>$ej9{4Yf;o)Dbl5Pi*s|kFr3m^jp<_-;9>MJS}zL;HrFaOJt$i{9; zAoJs<-MLy7u|4D%HevW=dc}Kta)r>xcKnRmT7A!EwJM*GE51_q~G{ zN7bd(w{3k2lx@tX!RK^fzD`EYwNY@?{zxi+#c07C+gI9>{KfffUMCHkkeE`y<#HaF z>Ioi8Ddw~aVO~+xoPQY}v$$Ps5@yCfh3L#(BL(N!gl-yAMRMN5Xe)%OO*=Nvlj0Uq*YSgf;BbpQgVd z`SUyVwIX3Ox&hq7?hOVdG+|q?(P2JFmHQ>M8arFpd41I&pu+k`I6Vd{aa;T4_e|8e z7jz_Ut8l#x;bGpNwKQTVLF^tzuVK+ca=C70=dI~Xjk%r1dqT=@aTVzwbG45nD%LmR z_u*bWz^GLk<3r^)6{&0TJsC*kGw9wr9N7X&xJZe&tD4ZQrBpy#-_5fT)Dn*PAN40ZVM zyWDmCyf;+hM2>-(aB}ZiO9azQhAW@69!KZl`8he!Nx5sYb~maBJxWL? z@b#H+c><<~?*Hv5R;u{Sm(e-Q2h9kqEwyi8WpcS^Lrx{8(1&=A1KHcD08!~r)PD7M z$!TlCey4ixo=!Ad+%Io?Sx)-Z+;3SLr8w#nTa6~cncdV_SbiEX9*EFT^VSmTF#6gA zt23~j{C=SAS!4NDc^FTsNrFtV#VN53aZ>PH_9kn6jol_6eWU`BF*^j2g!|h{9O1&52oUl)~v!T?Rk#aCp!ohJ{8tF)M`yv$VXICS|$~Cp}b_49j<*>>Zv3M^b)A z%kR_~+(Fepu)TVaxD{Q$ll&VMVgqS@`*-F<*Y7;1drRkxg_Z8U<|`d7N=R^V{~9fV zi@D=GC(YC9aTMWM#fG-@AZuqNOtZl8j0|>N-zB^b4Pkz&E|)bMqtCrLc@q}=GfVZ+ z(oy~eb8W+BFjIz@v}byop>_$YGcm9E9T9^NKSQl4bk1X0wxRsf3H4LbVW=Qaw}E)4 zx8I61$z8JpY$6PvUZ+MDE6wZikiTus7cE?$qjO)El;?#5!l+cFoQ3Fe^Uk|N`;TfG zkWbEe+eBDsj1RsNf{NasgJmZE^+wpaIlt_ys!7y4j{1?FxKZM=J! ztH+uaa@TvISkfwo5c0M1*C`{K_Uk$Px)az@YFT6N=FXlNX=RjaLgE+}L^@k!fle&Pe3 zuJF%#Y3BwhHC;;Lg_Bhre&?VtEB)ab;Utt$Om;NNIGL9JB5ZkHfa7?=?fh``AGRwY zQTGP+`dm`_6P6awPr0-d97_rBS(lFf?WF6s^EAJzI>yF9PvmG;sLk$S`&`iGFW z-6OiARaLktV;Ha4t;%p)Nvqu^=bKbtm^QUnbae17Qz>fs$G;ftzaLJL2hHyZH^-qL6FQiUhQ zH@N9EAj{+M3SH^4v9`w$-o1{*3~`F>@60s^I4Z@b)5|#5tSrqutDhrZT>lCCv+<6Z zD8gT5#S-@Z@oCTV5MZE|m-BSzxvX18%A@}iDb5d{QKlVL%g(3p*QpYIkQ3;gN#riw ztoRl}P4PIh(4re{H|2NdzOyCfkl@suI4(&~oV!?U2ks)oFL-xlwkG~rnPO3NJg&bt z{bT&C61$7!B@e@PR{U=>!nHdJ@u!FEB)AD+E(E3{b(mspN8q8`v~MtBx|bR)n~y9ZdbKBjw6xEwcckc7_rbVg%3WsBHdy1g~~ z?%?dHM6(I;*mKXw@Ct&zuDzM3TBcU>92Rbb?jP27e8UwFD(;F zo%fxCHhddv_d&-!?WWOVJ;6+MSMOh}`JOe-j^7~=t0ud)3z@u1GvUdYqop!DilM+9 zn_iOswTir$mlkQ3A6vYU+DQc)Z=cwyxYWITS)=CN@sw8H`9`2fd>qXCQ;vfDp1s`nsvcW8`g52lam?}VW0~|g16uXS;ePUxWUAK{tz4E z&^?im7+Rk|7<1UGE95C&Xr};~Wt#oX92I|$*Sa4so|v*yr+nqh+6)!GHesPUi0qD- z=j8XpZCj_>R1=_LiC+cp63zDK7`>xdZy*(*=nzOpt1gks$L~Y&@)f#b-T?A ze1d_y{~1dR(N?Ks4_LczIK$Q%RL>YE`4t$@^H$((&z&VYX8i1NMfcjdBC2fO+6nn7)CvT(lnMVvCX~;;PD%q{5nf zRMOr3j$^K0Ih-)~k{S-4(HQrrNNG zeRFn?M9bh>WkKKyV{__GsyR1cHyj`T^Q6Qn-lKd-m{Y$*AL@I2$v#^0-H>G5ei+*| zSwP#xytyu3?wiEnHt|i}c!W8Fsa+sJ{`i)r$s4M{@pR5iwT!H7Td?upl9pJGV;uf&^URoKmvp1gDg${q$q7+LJhLGZ!OZ4cg$8brYhqKg;PrvU{PjQ{)TvbhhGOx^4QCaV@|4SSfvLla ze<vI^|I*~Ym2f; z$`?$=85zW}J?iz%FW0Y@dI?XCJnpNbAzvi1>kRB8BC3{~PgzG@q~gu-@jZe587FyM zDc)}&YC1T$7S`s^My<(m)pJSKl6r%XYE#9j;St8bX~~H8&-QFgfWzfT0bkAGeina@Gx_7JQn+XK60I@8uv8EUpph; zo~NJum@^}`P*}ccQHW6}$FflOhpki&orx4%ibwS4@t#ig5)scaJ6c-cDETp)w&&^6 z)GPUBs8YWD&dn`4$?GbYRNix^6X>v_F)vLX`%yzH$bZ7n3a`3$Dj#k~X_nf5BA^1^ zPlGdR_^)2QO6zcSY+y9gM$%4Z+8XtILrMZn%bG0>*JNt!lZ!Vr)rk1D5)m6X9X$4#D$ul>^;FDmX!RN92j!aYBU->*VVq3IXIm@#NWAKM`x8xX-UQ3 zC1S5;I5YWKCj8L9cQ-%6n;NcfeKzwZd)Fz7>JM-KtYqmp|LfNST0ET9SdCBJPs8t# z?e1O)mk{*oEHqRfh5J;Kaxua63@A89klgFdIfMuD->_rsw^b)vG zELE*!IjvSXF1Prz|KaR=L8%sNsb3Ch+U>f=DBoPdjDL;G((5K3NRDj@1Y>c7C1~#u zj6=xp^>qX1#&g5dzs`59x$B$94t+x@cI`%8C$R$&1xj7vVg`HpX?FQ_Lm5Rkc^eei7l^CeBU-9>_Ozc8P9(xJ+9rQa^GC47~L z3XEfpeHj`65jiv(-Lln2-F;I3Wa)MVUfJDgTAXL^ zkcDZnKB^Zq*cc`)tze~7)O76c4SA;>P&$E$?3(?r@U$H@?&9fTM^$R*Yc>N=iQAHc zXWYI99LiA&e>PP}T0p2fY>30uNF0MF?Ht#t-=wKwOgv$`=-FC77E7wV zcZAuR_3(^dNjl!!=~GSDe zn^^jdRz{2|GPC^kMq+EJE_CIE0BYU!sn?n}ISq&QDNKyzd=TT@@k<50+EDlFm|`C4 zG*-kj4}FnjqwD;=SVjSNfCL8%1mgZf>4sH!a#Dp@l;||y3qm}Kh=kpwt;q4&|Jyvou9($wQYfY1+nq1x}#7_M$waBkCdyVC!Gze10`IEiy z!dKfTlkBlh-w)f_PgT#p3@=%qwz9B?f6MH*uOAwij-+QY=xoTQ(u>+dB|aHvlPTV* zs8@xfMt@g&AI|R7QMydCdsQ1tG)H=Sn*<)r^!c)piwhn3IByBw*_Fp8!|Iwie4S@b zW<=e$*Eq_0O}PZ4&RW)YNPnCclx=^fh?)`IPXYNz!_(3x4pnQKS3(5nGFiyFMjQg? ze1n*adXCvjhtmP$5JtsY!N$xZ~ZwvEAj#mKLfrg_YsxB98D*V_Ki>r@qeSy^A%Q zkj80w<0AF_864^0dxXc*?s)MT|HpkY(q)O*Ik=OU~_*+saWKwv@q%5Aa%W|H5xU zaB`x4SL@XYA^irws}Duwov9HNu-NdAwi3fAyxK*UXexIyw--52Z)bZ}L#gjTl34^) z6!qp8bhq?NCqZZB`uF9IQ?kAy(lO)ZVbUw-elBX?_Ob+z=Xhd%$M!bXe3IpB*B6-7&xK8^ne`ry0&Na|GwzFC=sv%3F;C@yH_Ya#&CJ z&}aL)iGssg_;+SLqAkXp;latgZ0-p#d~8G=?gzn!cGtPcH60HN3|sCSD(1^Mg_4sY z5DDOOpD-e9_XGsmHooSFnP;1&6jLV)hH4Ok&jtjFg0bs3BxB5wc)go6--rX>HCn?56x8|2TyC|&g3ipc6GXDMUSnI{{ zpqVe{Q}Ax_?gD7^&*y|eZlsDzXu^`WG~ViS+_yzY^6vI6P-M)L*vk;r8S0R4(KmdR z9I{Xkk`kZ;9zc&MFyz8uE<1Wg(J#or`#djX{{X$DOS;tRWMD%RT8|FWWzL{GKcKmF z`5<2vzcOZD6>sF4wB*IECMYb1Aw2BZ=>cTGEc!>@n}>6grr!We1GxUe!b0k!W3j=4 z{Cuv&-sCN&x4YIEP0s9V=Gg5yymnN2T@+j}q#GIiV2$AY6%!4nc3IZC6~Sz5 z*`13gEkQ?P@)_+X|J%5`fDqp~IFz;;+U+dC0li-vfcOyT@B(@`{1xYLH1BqcP<2!N z9GQCK8Y1HUY~&W=7X)%`U{3PuRo7m+!^gE-8>y%Pq?Nx zj!j}XhWw)k8IrK^ctL6RefLm%%#bhmi@41KIuHEx5pzF&=kIa{FK)yD?V0{QCGJpN z1N(QEVz8+Y$Syk#)hNYjjJM{4HK%?)I25gi`q=#AL|<#4V9RbIwVy4&`B@o1isQ}b}4os^V4Rd)3}E( z6cd}KBu$n##jKH=^lO_(iTzU{XCS5}RN!6pGMJHxt=VJc3izJRD?+R(-*{}VAei0% z_0!d|hJySkPp7wgihaILa^RRBsJLp=f`1u+Zh?J-Ks zXTL8eX7I2mVv@4Qk2gGrv-Sk&Vj`DE?ZIyP6d8bG0PyvEf|#0zl)~b{4B97d644iK zUz5Saz{APAB$?g`MQfy+G(`hG3;4d33bxSV!s%fwugta(V4p6PkCJ(Oo?tV{mz?hn z#w;-S>h||cDn>_{UnF5_5&=@-JYL0ZgkxgbX~#i;PZ7xel(==N9TvB5Bq8JJc;t=V zARiA&#ogs420zzdpk^kwZNCu2TKv&pqr)W}*xCLzxm@lqA2e9UHC1+Gdnoyd{(;Im zU(I2nPEhzrdY~rvixLA}7Vu?A>UC^Q%7D^l!eQMrt0A*j75RueZ|7uFkYD|3*tQzu zdFirv(C4J+><0G+>=zEr02KlPP{1P`+kHd2L_{gIjH|rzl{VtX+G0~ju68kqy)R4W+)!t3PRVYD zntF?A#qlM+P~>0`_@}!!FA3a7rfc(XkmDT1C9+#&?W%HGz!s+Qe6DpN;3-sn1phi( z-0^#G)2FNViT)T0=f9KT18X=u&R}L$gF3L^zX>jcd5sUCnNP{Vi-O`6c)isAa#u%5 zMa859jH8>Gr+kAIa?y)!WUVS_n24Zu8mzxu;8&`wT3hvZ1J_LX(T*x}y-jr;u{I%- zsx;Dzw6nt-(#-jzC|Ef%02L!W^sKX}`vm?z<_NIKoWN7*CK9O8_ejIT0ZWDM^&p5> z;Crkb6N@7vC*MSEK<@5NfaIpF-X#i?fr&{LV-zJABDp?DP(Leo`7DE4CiIdlrvVOV z*4)NXf)CP_VZ#|q$91-H7yU}JvMJ|(Cv87|@T=$1V4o|pvN+tjGRxWLM5Y&8L1tsF zxGlYsgwiBS!e5AciWQ+J4rIw7i;fdc1?ch^%&Wgm&i$0NXVj&%#uCg$Ot#egPYS2Q z`agQd6Z}vNc+JvQ^K>b15xpOMpuwhP`v#r8A!u(bJ`d#;W;JrJMR0B=IxU0*FWFG7 z8NM58upXUJgxlvt8lrbgFLg%rVkdT?vb>4C<2;AS=|)+d8PjzdHz1Cw%gV2tcVE;O zU4hITZ$AcX2RKu0-E;U$6U)-!A6in}hF@CodOC12%fZ?R^yFb0j29Xg#>X>pVv&|p4#~Lc*nY;RHdzlYg{XWh;?KJ-Q=6`AddZ}_X zuBBQB-WjGMc50U(i*x7^C`xMW5?G{##yW0UCd%9=iOnz8j`ZTLJiY}ar?|o;hl}f( zMA^$kd%WjOtoJSqzG|J4gPB?~^h{A1r{^b}i`?=w5OFp9P(`9J^hcVCdf}Ibe`W*+ z+l~I@aR;H8$Q-wf`-_7vD?nrn0}pQw}S!pJt*FnJoV1+aG!pHW=IjyjR6p<@d;BHA?Yt;PEyKWL?;`ZtG{rtDsxc5^dJDyFd! zREz;w9GL8B*Wv!!+Xnecx%EP{QilY>m5tOW9bznuLMO9i%xjW%$cqRY&HwdDQ`zK2a2j85bH)5IUoT_9k&LIU2uh!1Av3~{M}_Ac0tFI6)>pe}&_ zzl4mBw3hLr3X0^-Lq6rI$)%m+I6?U!jufEZ?QO{JpJn$6qI$) zZfYgY5A;s{!dNa3$em&bs|f}?@+h<&PvoeV(F>osimt4`IR|w6^-vbNYgA&8!1dli zQkPsnc^lpFnUmDFiKO*w^+U0DKc!#QsnUb5|G0~_HB-$1hb+O4I_<#E_5+{{4sh&< z$nO<#ArmkFsY*ZK^*A9g(<906EVx>dvexMAQK-v0;=O7%RQ1bu9mFS^FVgMdd ze0+p^GYY0N&+{=LxM}l7`IL4Dtp4p1Zj@+-)a^UtM;X)H;T6+%%|}e*3~*|j`KMS5 zC22`S6#Re}{#4Y9-OL|G|58>=OAzX6<;XR1T98eQ$p4B!bL5%ZLZ9)c9*0upc)-T8 z+shk}PWWa{cg4L=d0M}IY;t{;kotRlE|&;wy3Ie%RU74Iu9QfjR_ntX<<(hTxV}`r z!6HXfL`HYmJLuQ9D@AAIc+5R3A{Y5KuRLEp<$=q@)7Ab{`VH;63n2wy9lZ;-PE37G z94*{&vlA6W&YWKg)2`(6Vs+9y&WkfulvRB&~x$gSnWpu1gnu(gDYhz!LvFE)(`q;5iS&zO&y&a zW$@6~_I5<`pMNN#PMj8U!Vz_7eJA3bI40{-4__5l8|RHKTXF^W1>VrkNij88^iHnD z(4u|0yG`>dNmB0c=e@2<^JzsZp*(+61bUDytkxjpqE-P&hiTW@=WQMjAYL{zk3uOj zRn#_YTeE^~y-IymcC&@+>J@;A5o`DBySsT4;Iawmj>mk|;eI#!Dg5p~+XyQAv3wh< zrOwC{)L#$Aw*1=0_$64-c|s(KZKLRYiBq$XW@@r$QRKD+tDoG^_yFnv@KvBkVn5OE&U!}$Nh3!RQ z-Np>D|A()&w!Sw^NBmWj)zgJ$J*4}vIxFkQReJJ!L`&__)85`*lHk_5aKu}A6|Bq> zbex2c`w#-cNr5hxPd0y6o@bRlko?%h-%GYp9{DN~31?weZqQ4w zy2-A9-}nmnW-9J*T0v%E+L`nI8$Ld3(W2ArFV(fw^i*_6#d<6-0y_qf-V|P-6+}0_ zasV9z@DB`_OQjJ?<;Was^89>2%)9qWrSaP>7G2N#IaZRD)xV9CY_Y$WPQkfW-w{xp zw<&n#Lng?U!NZgqa^%7`u+wPB>;m!c;Yk_>QwnOTv1$aUExtn4CPZtBd8C zse_}ktNMqV3e(n-nzz5!U}OzQ#P*hZZn6#KVvK0A=f^8n0=6Rsoy_sC>qX8 z6Hx~}e#QDY5OK^4Y{cj8O<9KXEy-3Xr;P<6hRrcM5#4(}VgLId9?`x$?CB-9t!4?6 zB?nUI_`Nhlu=z7!`SWYo0I2xFo1j5BLP$v8w#v&b>a#21%@Z8(Adq!JS9YLP?!Gg9 zV%~d5uyej57jy?P>JD-Id>ttKE7X_YPOV;J?tSaXanS%9KWP%p!4+pzF9t%o_;RJ! z$fL@(-9v+{xK5BPPAv~p{yRX(-HFehI$(K_S{w0Vuex_y1W#GtkVF~cuKz5lFTxYY zy}XFezl;3*WS|L+fdxYbc)&(O?&e$?2v?L|1qU%Z{#2DK47#cKGCI=GQ-|1x;BxJ$ zmumDT_YUbs3oTUlkFY4e_JQPP1)lcg?OiMdfd}|^k@h0P^AvVv-9330G^hwrCjJ>kj#nzwq z*dO-2fZ7BT{Md-#6da$wNW+Rvzw0t&(L`@dTe^W}b=khNA!X<;tS_**W>T!r*O;}Yw#LeGB1!9F$OMkb16L{)t zy8qmne&f^Q`)1hEeMI+_sseEA0Ao2KKm5xGrJdz0DjJ5SnKJ=aa5$-?Ejg zo*ljv!TG9|H0`>nZP2+@9{*$9i-g z0ZTFa=%?Ax=r*|}0fXQblM;QQrq4(`?9rpIVI|c<_*QPvo^P+IkcVzc%y)uVgmP$Z zn#Q@1Q$(hjHP4spxv4$)N-@eCvPob45Ia(G-a-ps@J`vHI*oam1eK*ZDn7Pw)76g# zl*lp==c)p#k8AzEZ{V^;7Q2V}vf>U+`8dsyJ!Wt&s2XrvQT-czQUR*Zk1?NzUYj!> zrFnWpjA*21VgnJTii@Ra{EgfQbE1y|22Hvo_!VmL?}!-NrQ%THL3_k;&i z=i3m~_aV)`P|b9jfLnFDuL|4s*7!zvq=z~lW`!N~`9an4TbvMHk`=j-6wSYFxnzPxrg|5ptlu^P^P8*XLXuK4ix{;Z&U;9x!5V85Sw ztw6tDljf=1j_gAS2yocomM!_!7jb8K>;E165v$cU8Bj)9qF)nyecIvjAfH`sF#C_@ z0&mQSrJsgFByi*J1Rpv7i>qK%3kWq~`@in#p3|>6k;a2I~gw4fn&g-G(J#?#_p9U2$*72hxfX~{7e{d~x zqy&BRveobHP^rM`J{-S}ff80bPFSKp+wvLt5qs=scd-I%mlX9pzqSwMeXLF|7d{@o ziiWddc)6PJqk7&RHq+x+4&6OJNsLsU)OU9Z&n+(>rT%zi#;VR&tnYz?PXd8>zXGfW zS@1x8Xbixc6V$ghkI6hO+Ospbuo-~ph-uPL9ejvPjH**rNQE=JaM8_e*iurBF!>u( z7|20d-#0JTFy8;!i2}dErC9${qpFfe{m+W}w6xr;^3fU^_IO!_;7Lkya!N8H5;Bg) zV6Lm@ltQV1jr59jMy96F$3`U5d`~>q5SutVeJmn^=bJ>9Ia`rC+MdZ6uMuPKYIGID zyg?H@^!l`rda<~;pqhrm;Ylti=bnP2S7S+FFpI?Av6-Rwz!Xr`bpwBLh~b$_qFJxR zN<*J;0pw3%Z3E_fE@`+y2#f_mR}?br^0Uet-Jp%^HM}x0a5IZudT3k8wEcO0LzX71 zI@n+jTzrz7&+mlFwaWl#zp=84DNQX8&&L$u_7%TYU8OZ%87V1SVF#u9B7kwJ zSk)itk0jafn}}FoAWY2m;u1hnzp;Jy?e%*H2N`e=D;=m)uiK8OwMBj*fEmjy^K_kQ z+{H=TmNP7!43YtjLTV}q6Q8vDF>(GL zH#uSwQy9hcjrDCyXcG1fA&EVTGaHF%o=6{odGy7tev@b`84Z$xHTB{;pX>P7zJ6_E z@IX^O5YT^T866=sef_$|=g+J}iw3@i8O(hu9wJ{WCM~lI%!vQs`hUIVay)Y^)-hL& z;L^&Mi|n*S{|Od}ym9+x&0ZVAOjo3(#_7t%WyJjCx<}^dh+)+Imnp^8w|Eh8d@OWo zi3e=nwuWV1&t*zC=%?i#lVW@;t6!fB_ZT+02V9@V2dA#jujAZz64&?b#URHZQ4%HD zed9oidlcmNJb$Kl)$jm`J#4Zj$>3 zJ89{ri>o{JiB4Mx80nn5jD&<)1JT{*mvq7|P_eX3tC%d4n2Ts%XFolB5rMdRFWu?% z+WFGR92;vRsNp+RC~p0H#71JdvtEf$vOB{l7XLTVPKy^ty_kQcPh||u8E||8t>7X! zaKAA-G-O}&i-DKn7Yi=%#In^bQ4F)46Di2bzLAyvE`pe{qOqE4uuu=L=Q9 zk}f*3v{KHDSABQjKlJww*J^~b)ka5j-+aSum2^6uc~PRMYjeXY`aT&)>VeT5=21=A z;mA-{C4gU-nMyd)wcbuXA!>4elQ~3;+x#2nhM=+y!g1??{IuJ<2F$FjNjZG5sK`WSEJerN_`}wybOWad@jl@ z+!6KxlrQ80U$Q*n{e9IyvS&X}M2m`~tYBgz)W62mD4 z;2y_u*9LC7YO`JYpM=_t4EDrn;3WdYV_*fn`87}pQgI{&jD)ui8Aw=74jq9tGuNI3 zGQRP{YR0jLjU#vN$VJjNx6BC5B8i0zqDKP%L`GGpY7KQ{2DkG~Xj(-v>KV+Gsk25X zMm%n6YLkoVhOLEBt>FE#YhTe44@Hx||y zs@c1GJ%(oDgQ&*?fv`a0DO-&+}jU# z7p{W14*$Rj{nnC#b98Jnd=V{!l(|QI59JlJb0mo4{R)`$wtBX<#cQ8lySnlNhj@VW zi@(3ecMYH{bXz`Wg-}0hX(2n4=xnR8@xIWnG03JKAf|zyh9A>U+Jse^Ic$rFD24B- zQ1GE`9?poC5XYUP6f`Euq9(bGJM>RGKsOyd4=->1{$?Aeg~r>it?1}Ul!yQR#&t9< zR%e5kPh;6pM7)+zt;46KP`^>{nbN666smk!OucGtZT!gCDG7vqFUGbvevxv@y?MCT zO6nn>%nD$bY$?TTcfTDuPU^74hSSXdoaR608&DXyOyB|jeE!Un&86R34dY?`X*l8u z#ZGcPZK*_xD96&a*pF|k?Aj;WEee({{D!Af8)ARU#+fU>_eLfp&Tj1?QGrRt+S|eR z@$l%h+qxpaX#2s4KxsVrB}SRI8MJhDIt&Xgm)1OZd~{8QKcT#)ZN@7J_gSU>XA|g- zDTS@8NV<*W`{d-TxoLZxN|Y;iI@(SGN{)&nQ7(eWAWmefjRGcSSL-@0Wo3^( zp2IBs#hmqi^7W_0E&V0>!P+`m%qH0d-1^dH5fAU~165E)l3rek`9AW4ZV+pX&`*-gEwH(Bmd%SdZuIM%lDXux+K}6c^nxx>S(y8Vj zeWkE2h7r|->1qOJ2DC#avC;yF$qo@#PCB}bVEo@j2$m-RRT0`72mK8IXHYcSWJ@~i zqoMQoJ~Wf{PWdD=yz_3ZfcyDi)M>;3?Cw}MDDw^@rr2=x@Ik!DU?)GPp-<*!!htpS zFjz`%k-+?`Cr;L@qg+Kl>|0UDl&$&s)u6DoJ{7^aGe;@;#l`eQn|eEmGh5g=-U$U8 zw&`qO31ECMC?pFzZ%u3`e+QxpO#g_C9BN(Sv!3C1+g~oCv3aAQ;C;}`$L=xl%cPsv zazeiWv|UDj`*wG-$j$&@gM!eNqvIiHJERKddkNG{*~y7(_8#geIyTnS*x1kC-vvR6 zv&G591@N6hXaF`CU6o?!~WS0Z5_AcgL~ zh$RsbtIVhgr{;fdH}tSGAX7-VXZl8)L~>z4F25QTAAN-uqw0@*l=TzS(vSMGYKc7T zwMVf)LF!=+D1hX5Xe#7Ol>Mn?Q~h^L%ewxZ*6Y@>f@4A&QBJ!*Cjv~Rby|!IDVNLx zrxz1zfU2&%mzC`SV@|f*LL)AEQpCi#xDMjYlI;X1Ix@E?9iGyiSA#J-f`RtGN=pGk zR)}YBvItpwWq1tOMM`|^UTrn~P^z-r`eG^eC#Sghxv1z|E-#(-bg@ATcvHJBd;+aD zMa!x_E@ZG*8Edlc?r6}dxdm(4-Q5id2?6IMMFTx-!lelb3#)*s(wS@pNPuGN=l@x>I;XILEaG>Wft6eZ+ZnHNK5drjA>901C^nrK50mHZdz8F&Jw%S_gJR8lZf3)p9ZfnotRlynqy zS)0cB3t?13hK7cKMyCdQ0F*S~X#h2@3uKk6>j|KLBSXWV@=2O%YR4@!7rVG(C!a+2 zI3mmc9;~?}!<-aBceqFgFYPlr9ZpX4>2^(j$G{F8QG`q5IY4cXQ`cf%E_$-yo12^4 zhIr1yGrHmQked49WGP(i{1Ei%rZ}HI9)s!4cP1NV`-Yyk0+|vnie69PvDk_+Hp9LE zVt%KV#qT|0)}>b&a5!8|4?4;r$VV_;>sC6fS+Uc>TVVs!sw~RPT%I&b2@MXGk(0A( zfK75V^D-EhT)p_X=uoXtZc*@9dU{;m`}YwOUOuME%!x2=)THHWTWoY}N^VZ%NX%{c zue>q-iC|fV;o`K}>CaXr>ehN?wukGAH7?%O-k7F3J)I8<_aBhO3tRV`xgD(6e)9T) zH62sUkP{_z92_Mz=X?dKh}GUiwF31)#Z;qAOR$Z+plQWDsZWYKAdq8Ju6YhbAkO3|#Go~+}AE#~g!$w*7P zp(f1$aS!_W`K4SOX1D23@LB>f=HgBzAJ6%Oi)(nUaN>k}9c%+~A#JL7hey=wtZJB? zBV8+dY2F=C2)-8`9StTeO!9%Y)wf=uB2&nQX9gb{swbGVog<^70FL3%;F>y^V*q09 zmY5A?aJWXCpwAs}!an$(0MgKFBP)*AYHIleLD6(LRcGSm^ z*{>`!smaGGyKg$Wx%~|w+Vj0ZaA@r&p3->P(C_{&f^J$%B{MslQSY#atABZUSvE;< zv}(g~wzzW6z59e0DmBceSFb%(+Am5$O>OO|F*k8b2T*NX!`aGSJI#*jYK`UOFIwF0 z*k=}Ee_U&o@{*I1>Wn)hfB*h%mh9Gcfe!%9%K?Rfi2k!@p%%BB5kQ^-MH14;M@QFk z@)sNjkF{X^1)t@_T^gE(4}-M%qf>*UD0oM*DA1gojEwE|;y}ItW}1QtWn5M8^z@XM z2WT2{0QJBqT*UOpK5E*A@yV0AbJTQOZ#%U|&)#ovAfR#Z^bEiOND7^xe3O*5l#~uO z^I^{W0K>9;oVfOrZUT>tY!fG052ofqP zt26U(5!ClVuivxTl#u(PkGLOu+1lE^v(h;qZ&gLaI{-rh#X`)>S2;2^s@4DF6h5&z zdk9L#uH)i9`AtYbb9Zx5d9TG^uG*e+gA08bhw-6~j*DB1rW3kegF5Wmdzj&CCFKws z6Z1^3z7~LAd?D3+ZkV*YYfHD7AP8FebCtk^!fe_2NC2;I)OOp0#FE>mBD+Q2&Bf&b z2}xgynD;E)sZG8USO%3~%o;cg`G)ann+C8WHtp^0Q7%hP;lBh$!(oM+4c8 zq7vBBN(K_y`zT*eV6Ge>YVp-m3_b(B{{ZX6VYR1Z2e-0R??u_UzqI^D>0>swZ7}2m z)U`SFq=JDyYDL=dGqDkd6o92`cIs=~%jZ3#Xv9+<0Gj4BSa1CPrgTzSOU=8>9fdHo z7%UkAlevvi*kS)To1^gO&%FW-JM$^zIG~z15_4x{?Ncc4r}r|v{QOs!xstMy0JjtT5D=1 zMD#cx6Cp*OZpn#-WR+M=SDXF;ZF+>KHG#tw-D`ZXaORK|~ne=qTd|_ppg+OQI zC@IaNaAHMD>}Sdol9P2cHK%6vaL(TW6p)j>B>?^gn0X6ku+;KhzVBB90a7Hjrh6`+ zrRt;S&wIqgOJ#NwD|$YFCoKWSOm`f6ihzUZniIT<3ByC}-W3fJ@|H{QbHZ>Z*dwO? zmbD4$l$wSbQO^$g7HO2Wofv=tZ2*!)U^)fIRmb=@WXK@ZChgzJGXavK^X%;E(yVbt z4y3(GY6BuO#cefSo^7q%dKP|iasp%kkobMyIgG}ObdU{HHfs}yOTRuP4RZjrIWXZz z0f>HJs)klj?=)b%T)cbxXuvTEnPb;!P)#%TkqCi>8hf2w(h(iDT4g@wTuwN;~yo3S02?$K)-p(I| z192$b^7W2`dljg8#SSLx_qE$8`#7xYx!0c$oMI3;H{dm#(N0tav+F8Nk}B`nRAD!ml(bV^Z*P+ zpf<&*1niB$iGtcMprD<%DgelPy?)b`b_pI}Y_12+1OiLnBOhQD-Oh;m3JshT%Pd(d zl=sHj8Yk%O>@3kN1h)q$BLEsGrVQvstTx7+tpUrWO^RJo<`~6OM)O0=+e*r6B2M;DKN{?rXG3Oj!avo847-_st78ShqiL;x)-A;+8J6A2h?s#9; zt){9utZ18C97d~#DWv+T@FAOW1GE3AN?0@UNS-^oaP?_S84 z*l*vyMMQ9z_B`~6U}9nde?>U~bQd$qNw4DI>k9FlEA^+_TwVwekOPF??bZ3{*|S0* z%j}d&b%2-r@@4Z-mJAh)pPZO@STrwL(8(P54;#bTHR_C@CQKL`X@YoJ0lESkKvmw6 z12Bob3!8zV5A;7F7_L_n9`jG+kL!9o6UDwRfUd{%xzrE4EnV@z4+En;0Ikw9GS?U>f z4`m%yTa|Z!&w?zp1jaDjv^OC=J-wSZltXljLvXo3uR)ZN(G0aU3FrcB12|R#X=!QT zGMwu#kq5@z38+yoUMfrCo9588#k$`W6=Ns93$C?BYQ)($r~jGAZB1OJJrgx9Hl*0X zsB@glumQ{+F#fcQ@wU6)a%73ya7Pkw+C$F+`DPuJ#?79)lY;!6^>jt=oIX}a!5S{m z0KICx?1hks$gFEBAHXLnX{TmkW`?iCY5~^s)}KGIv|+&R5lp?Lxx@+$_F9f13TnL6 z7CJaMDCzysh@OoNT+xck$;a+&PF!BT4}F9PT^Vpo{J7M8OH#kiYMK|YyMEJWq3x;+ zVA)nwIJX8p0B}w&mbJq|TNab+I96rf`g(do0s_{TS&fwb0_3vLunE*K7(fd!_?&m< zM69N`muUUKdY_|QT%g&Yl;EZ?$h1SMV4$c2j8Xt7jZrfdA_r>yf-?mZ^;Nn02=AEdvVx!m8*@5~`-6q5`ZX5CoX!D%P*-o49Y; z5TBBQ`MZ`Px{CY}nb^0VScJpwO^&U4V)VKa)iYKyQfv$ENL` z48RBixy-JvUz&wl6_zD@;PCaEOoTE$`qsq_&#o84Ogy|d65=ezYJ5K;fCUO8pmX8berwXC@v+Gb4US_=sE3R^4OONN=5zkI_x3De? z&_@(})>~s}`#)t9I$l(Z9T9W@Fw0`BU}LPOt!NF{dJpmHp-R=~?1_78-N-JGHjCwS zFAMqoTcT0{o4US?aY{)12C+yWQ-tGc6COG_%pi3hkDb;wvk0Pm6i<;Mpmkz z7$Y@p)IyxD`^Vv*avU5SfVFv@C8))`X5O5K6yyafyaa(40PF@=k0AupEGJr?*|4g! zZ?0e80nrRGK|%Mei4vf3fSD4OjWxV?oAC*ScN?)Q!JLF+ataE{8r*@%pn?`QNlQw$ z0XaJ@whb-_u-NL;(`lFT(jtL35YjuY1H=3xw8A{^+{3@sCMAbT1V@25<6>O050h^w z7;Kz6QPQVztj-Btoua;A1L6J4U~SYe&ZC8ROWs77#k$Dr_P0?|?WdrZXq^ir(CKf} zEF+ljE`(Ilg3K#;0bLAUi6~87vAew7+AzIU#DciZ>0#BFsm%M;Kkz0Z)8JM^Pz`Ka zN*~p^jM#L)iqHG5dMj;kyhMNS^#7NWuk-#C`#)VqkVA`EG#05yyz)ErvIqkk_kHyI zG8u;b72!Rasau7Dn(iuZtzG>lCyz*@QzsIF2mO6@pZ3qYxIe4{{dVN-y0@b%WEVpIgUM zL(`QQN`yaVg>l+lv!R5RL>*3oXWQ9e$EEH?2-NI#mOfPxZd#Lgwa{0dj5lB>inmW%e*}CWuAw9 zV))Zw2`O*kN($=Z3vr?As?y|C!-g|k{ShSiW5heu-lKKM9ty%DG3bRWq4NFjmq~KG z%Otr6O1sgRQ;u@v9@P-@hIiOsIBVkzCtp!fHfgmx7IvPk=qgq{{U-PH%!+jzJe_^v3__sTa@g8+3Ym z*rVfCrU_NH_jCntf^-thL+Dzo*o)ATqGu5e0b zUT%6p{cnnuYmcyXOI}Yq#sP6dIyibb6MK0RK{lA@JRu?5SrV#3Qd|B`@5hLk{Al6Q zed;a5%Rw8^Bolkp{dnL@B1X7;yG>Ef)ZyEtr8B6!VI(Q==t3yCnIs3HhhMeatL0Q_ z1XS}0Y5OJYhl(3jiXF<}F$rjcp7=!0*D;=zI*ui8Z26?Bq9TXoMDfIgdL<*%)2BB< zGD=?lXNZ^9*G}VKla}%n%)O=u5iPjefrQi~qJPg}xat;1DMHwH=ps2;22Q5tItOne zb04ULZ)af-`RzAVFH~-74Kmr5cAhaL_wW0C`4URO*N1Ee6*0s_k2R0(NSgz+?=C;N z!lTHrq~Wobu%2=M5`Cr?g|3H!jycoW84eHD%9s2;_q+`m8{z+=?x}NkW^^Kb{{ZxA zTs7lnl=i)G0)KQ!3#iHGG$ApOf}C7aQ+UcBjMLj${7K(+GlX+%KAe|VdCIcl=TFe| z7L5vp$G4DIQsVWC5wmXOE1|oDgl>N7#^;5W${5Nth{ulH1=LGhf2iJWT2#O`o%F)5L;~hjocow>lSfV*d}yAuyRw z?Jrq_!j(NU>x)J_{GAZ|oaS_Ug ze*UK&=L+1wIPNiZP*?vx&Gk-FKiZ%s=O}%1(_Fdv}Gu__#1o@tN9f^8}IfkK)Ch#_+qQ0^Sy|Od zEY-SPo#LOcb{viyvDdlK4kJGzli{e)7ildR=hPzw53L#%NteGEvHKuPc_K}Qy>a3i z8hzu~5Em3;3=RG1WWV=qP9T#=F|!|M9q~4)U<^s@se=nIsIHzgEU7xSIRJI5XCJRZ zs@VDYCtNF$fgn@^YQ=o_zP8oBddAG02P$YgDnQV4;!~j!?ifXUoc{_=QfXx{k39=r zqxt_K>#f70e4_sURa8_EFpv%>6Xr=bLs9-QYl$VK|+@9?hp|WkY-s}Nn%SmaBQfuho)q?UB`Z z%lr%)4ZFw|@qFx+r0Qml!dXB2pBQ$tLaU@z0SHm_=5h2~$IntVU* zh$ATlHL5hu)MNyD7Mn<>yDO-)@|(2;;iN+K0nafHra{#sZ!eS9M>I5C4ruKaV!DqOU!U=|t8dIR)&6+5@zlh=w#yXL`A3Q=I~`Q9 z*LxU?zu6N}^7{K>%sOIkyt%6;&7}4EcC#$SJtU}u$5PnOx3zPY77u!-kU}vK6DEDr z;B>rRiL9rJR^s8i2};x9MH>nEk-5yiY<`#55BY`C#X4QK5|e!6Hz|DUXsoNu(#-V` zKdSxTgyUN#%H(x@pi>o3+%X1j{JbX>=1R#45&A%+O9b>`3lk<(vLA>qP$n$}HiE;) zF`D;M{g=kDLxUn&?cl=hQO~f!)KfVtv~gDjQbknX%hho0$H&65C{21!HzKlNeGA@~WP&Lah;o=cTn_SfB{adJqntH^OXP@0BIPF8sgWNE+qPmwcN;=CE zGYEzNJk-t4@9Y&D*A{;?^o^u37BdN=-i+EZfl)YBFCBFE9 z4%@HP`)pD%nql1I@M0*Ww_qY9=2An`(loarGCi+9fo-O_cAH`^FgE}KqDnk7|zq^`}PqFt!zCAQcptIX5t@3*%EavGna^N|vlj=*%f?(zHv5-hhpWn;bj$obgqxWoeO1&*EKc9(s zdaPwErL78p3I|^erWBWz?5<4e-K@Q1P$l`BkwOqL8EcDWDI>P`$5?_`08vm`p;3k) zoY=u?zo)+1zV^N2o=U#UK)$h+#upW&xnSRsXOf?Y%F34299O-2=16Am*2=Vw%!f$j zjr&b5;&6J&9-TZMVN}9vA^){tX9_-B;VfE5oJofFap%5xU4dZ1B`;ge<$S3a)3HInA&96@pb&ZSZy109Zqlv}2lc7c z6|}+F;Z1!I!I)A^w6{hL#VQ)llCJ19I<#i`{3m*XnNquaXA^q{y8V4~jbEf6KUm8p z%h|#Eg)d&&^4Zg~<+~qAh=E$-o$p%CY8YqbYo{2F2~MY7^<`*9*wCaEx4MXUFOZ zf>1CYim|cOPza|zJHY8(ee2JQHSc=SeokrMh(HW|IF{wKOI-UMI_)ohgZ01Hnzg7g zb;yI{)+hDcrQ&i3U;$cXDq91Av->CK%Yn9svJ>{q9<$~5tErsj)BLN%M3M@uA2Lt6 zVyuPy%gFraczbVySbgQA0!Ox0*%>@gM#n)~pkO~ZZe%cfnI0*7zYofR9`ltY&DS=! zO`w&C82&)Y6L7Det-O{T(e|Q+?Lve2e&V!i_iwZeFFzAiw3dC}FX}SOGjfm>&_L zHPvLcsCNk4bith%ckYr#;;vMna%w->a$jzDeCpf|$FfxtISwTZPm7<|KJSrEqe?0= ztN=ByFC4)jQ|2#t<}MAYXb~%D%Isq-*W$$?BX>VlcQn>q_)hWsrd5jS0f_=}=8Hgb zN`da#2mbrr%)_6=H;Unzf!Oh^I`)kP(Hq!c(t6?bH$62ePr(2-O+Z&)KR46&Kt`4# zr?CxPt{HA`iDIbNi}uMiCdyfzXW82!>I-~n2a7fC#7k&;c+_`>rekV;jTJeuR5d8! zPm~TSR4y&?H;4aJNuska^hN;0WlFWdIn9ZDSr#WMuzyN;zK)wF`j<_zG0V1Hd{c*X znm?};JbX_Z{*I80kxP#>H*Y9=3jGIGJr;xU?aoT>*j&lmA@VZI?2uFF7V({(ZdB2p zC%?X|%5SNlUrVSPp;IOxh4~r&wtPKIkQ^aTo5ImdcxbLS*F^La_d*bW?EB{7(!DJ(+nE8;B7>7y-xx^HJ~7PH#YlVhuuIsdqTzfP9DOuW{Y{ zP_7e=V1-@hcsro)DA-!TcX ziYV|@jO#|b(Q<3RVee>P{54(|Fb{f+H#8oLR-5pPs_x#GEqjznI7}iMKR*2c~ z6LJjREmK%PAAK&*rw!k1lEJwpGX&?gJ<_qKwVt*TDpOi|SIN*ZOP*6SOr+~jSYGq{ zV}u;nb?8+f1%Wij2uiyvsV-_Z7h{R0TcP|-fP^gCayEl;YP}Ru*91_9Z2TG~w-|mF zQuQgzs-XI;Mh9gh>s}xF70qmE7#B8kY1#YaM(b7@XY1()uzLG9F#m$nE(z9YFTq^? zSeqrv4u$Y=ZLMyevU4}ZAdIa#F6_6a=Mjusrxz_2^s#M!q+efuGE4mQ`Flb^YPC1G z8iHysrjSD!qxH%0`9%f*sw8JtrDZmrrdu;L)N5CR9HJ_iz}(bjEEZ?V2z#1Ke&aRd zErGN&^&LK{#gk47`q<9`M(m$W@jQj7e7B{GClBNMBb;-(yo*nqq1mT6ClC7?RT6E6 z`lirvSvQIP?u9(Ww0EMXskKdOa+#_dnD&2ZC+*~qHs!f0npvzqtB7}eLTzLHCQvoj z>);um(;IlUx$8c$BcHqe&Yi_*Qisc=9QXtl*DG7$#qMC6TdpmYYpZKK49bV#VlS}x z%pWXO*|dSY=199c^Ng2K)9xr0bpPkq)D!H3hMQ7j9!~oHQNlUTc$OVP^gkhP@+^Oo zEb>;RYF{%9T-3`eiQ*JlnZV&1wmCgcoa82sL(A^-q{+e=;VzwwzOE7HyEGJn*@2z3 zc?~n6pEvBSp@DN8d(gx7J{gQ#6s1t+#bn|A8kl(@ZM(&blZPo31@;C-8zt5$CyZs7 zOp*3fQ>h%*0FB}kEhJ#c8^Kjb+a&mHDS6E(N-o>SICUyjg9Ji@H zIuiEp&$yze0D#Kv3HEAoWVRUEP0!j6HR2LGpVp#IxQ}*g^!|Y!S23Xad`VN06i>Jh zb{pH?zH|T^aIfzPg&+&va)Eg-4{nQA$ptIfVVLtq>|UFP zLf6Q+(*E)j1rih?@8MVw>#Lh2vfH12=D{BnHe&lsYU3VpUuCqgKydWPB*)D-#4}4uaZ== zV?(_rzs2G^Gs*wa0^|wgaL*_)LpCAB0VDFpYDFJoYK^t1}2d=2ja0)H($zCL6g{mBe7?nT_#N~ z=H}pzmi{dZ=k9-0S({QWyT_-nJDosI?=Iliaf>rRgd zV=*|#W1z5X?74_~EEhjA6bqCu;$M_2lq7M<`nn`+ejyF= zg5bXWtIE~e%XHq3rhlUO-QY;8#$fJZrE^UU<+Ib4?P*i6v<~ZK%==qQI>a@&b}y>heB(mTBfLahXyKg7dM?n4%Hj0&T91&b^{_aw8LW{kbV|xKVIdWwUoG6%t;dQ$Rsv1^E_?w zaf#Wdpucd_XmvkoeyRy6SYPm>T%z8m0WP@E;I79^BD&K%c#(u;Q3~_3k_G#>z`w}1 zw${1VYc~upRoSWvufcWmbd3SJi1a&HWo#cuj%4T2xK4TWCg-xf7t>>bNJ9m%nRnKH zu^kpp+~0PB;QkkjIXGI7?pGWtbhxX3x-kGhH!5b9QT1Bh4*{uEV%bqcqRYpFJel3r zZgP8bfoT@zxB80&X}7Y^5nG%BT0=ygF~XoCuk`BVgm0_|EoKZwqZaD?YDEcA#jQb> zP`-{ozb832^7hC-KMFhZ;#o&2)wud&x>1}@nIXeqzw`#hRnk9Tw!kAapG*il`U{uH z(U8kV-pB&N)hxT1xF~Ps1GnzO%Z?`c_vH7p>Yxj*{MscSyiy8LdAkfH!?llupoUJ{ zf7D_j^@WKLjP+>f2J3doxvc%OIC;D3E`>^8$LID9y%)3t|01A35-q^!jp`YldPh zR@wXO->?6BK7a+USBr)hguVLP~*zY&|e@zbCO*YGY(YZ_S1CICiOd%>yPU@?(){; z8fS_LuY z8=!r4W;}aMPhA4DJ@1(xJPSxoDsH(j)|9&!I#p61Iyn+kzx82LY5ser4TM-N&#~UK zd|IHm`OI*f7;stsMgG?j)!Gw1>dGatt_&rb5>2oq z+Ld4lAq_e*FWqRL{Atqx1h!?8nD+Z_c{SO>u2zzr`i%$vRAL|HN%CIM1VV2>f>K9# zr~KaIA(ywcH-w8u!OOYfFEJ6fIPgb}-yT=$-+g?XFpYhj`PniSq+B$r^QwaQyvjKi z)t|m-jT?ePM1LIqg_6qO8lK-D;3AF9WP48<`|~a@gjipi>22vhqF%aY{5?!78UJu@ zeFEkD%t?j}WNIQ~k;D9RdCV(K{Ua6QO7@3b^n;n#DrZX?$(+I9r2g}-8{6cZ8-#hk zawz0mjeM3=H#j<^@HqY$=ce{Yp7IAnBA@zVQFI#sR8Aa|sUnnuPP;^c%E zT!i4(l_)zPOl5o^{soG2rQBs9+mrGQDudAe^B1itOZHC$Ma0QEjb3)CY{33%O{-iP zm=tL!WL=+6eN_u(-pFd$Np$k@07pYXZvRKq8nd=Uy6dYd#P)F=5??eF$X{QcPGZsI z`5c|oxh9^nWN3eF4=3EGfEawI4eM%b5@b|UX!?e)GM|<-OSl%*`@OSk`LX-+$Z}Vb zgsaK4`$bu*va9{ebh=*B0(3&LM6VTIq|0+I#n12k1gZD(>y(P^342xX_)t({jMWv}*yaI_taU&eY3>_C=tCQJc&dRfQ*&3|KK1MIz0Q0S+; zIze3J-a+j)_`!{3PxUt-+-E4^NYcrav4U^9cMAkWmAw$wxmT1rPZ`OsXO`Li`Nlw# zD^km^$vA_P{}mi$<-rFiC5DC?>s^l+3oj5sh9nde6h%+oNQPZ8E4~_Zh=NM)FbhZi zl-6RSpPxUHtTRBUZQ|1MyGT>eo!7u=+n`-;4MGgv7w(*(_^C+4+Qz1EhT~t` zZq!7CXsGk#)hi<-r>K040LK&NG|JSXUZJVt*r|4wrcICSzk9K|>zo>hGPOb`%6A{_ zGpFQh=8J)G627(?KP!ib2s@2_;AUnsHe+&gug4#mN`U0HNxKY8N?*3w)sTThB6wxhy_8Tz%F!4&04n-avO0E@>`@~%I>sUhyX7Xgou|>;*TCnOXO$3 zC9uw%aCeJ$JlT?0EYtdhwY=v+QL<0IUUd9dTFM3rT!0sAa)q7uRjs-(u<2M~MM{A|9q{{Vq5f@KWjJ%Squ75Q;d*u> z)@1s*YF0lPCM)^YKohwSk~oVmZu8A*Ff&OU{keTd;OTgZs!3z4*YbEId%OdzOji-f08@0&d<4u3nV1##q#jX=#r=e zIVPgfZz+e!T`-_MG4HRI{7-VqUv>7aY->{p;}zmz ze0=WU9Y)@pkf6so!&YTl@1Qp!d%s=yv3dVZCLw)aNqzkkrTV~2qf9e#3g|UX6;2Z_ zQPy{?aEGKkDEOnFv@{L3o=(Do1P~04k6TrYUtMEhe4Ota$<>U=S}QD6B(gp{Si!F` zVRAaC{b3(t%PG+11OMw43&DJl_g&J7ba8Qo9oUtFIJ34?ixJDf{5Iqo&vr7$)fEVc zpRN9ypLbS3JB^s0?m8#24>_|6)OF@qfj)b|@#_5`Jx7GxXsv0iBY1^T?Zzw1%jr1S z0UzgF_yq(65E-}Po?HQ!z9~Ih1+gA>for->Xg+c*`$8x8J&hnfS(>q5y(c6kGt>em zpV2{k;PsTiGoQ@0vG`>8zo{_bi8-TxwNBAL^B!A(h$bE!xD_B_r=R|MKe!A|0$5Ay z_9=#Mw)V=$A1i(ex<+#Qru=p~d((JPQh~Dmf;LFkias^EmHtbdr0V$ zVG+956fe7MCZHg*K>=LkO`H5X;s9e~T%{A)Fx8cQ?FQ7_+Z%`vkubVTjX;9J|>^Qnuz@5kC+poi_59DNm2$WFSl{LoU8P`D^okv=*|h zWRsd%`M(ifpWW25Z5amT8cyAzfsi0V8ap?$0pKGv3XtX%_k50@K=k4qu_dLXLak>j zcG@g{i}?R{$6C{(+E*fDyz zO-vwTZvIk8U;W;-RPK&!UFJL6Um&mF-rocDtq7XX!Kk(s7t--Jr3F|7Wf4@ul9S|w zgl4C=NqFsp-YyMDId!v8+?8eoHYEd?<8fXy24vTl>% z{~9>wz%2g}T_U-k6VKCqqS-w@?{#Bfkb5C|DBk22W+T9enMXn76C!6CZ!G9No7Vw- z``C5vCjkVenIeigv5RDo5Up?i>sL-61?1akG?0ltq}Zt994FmjJX^v3OP!Xc0VqXOWFK}i{qI8w)gY{qXOSG!!2 z&zg|z40KO)?qniU_E89_SO0qk#H#bDvcp&=5qpDh$j762&Js= zKzY7CzKkBiO4)A#nv1yLgvj~4$gPHuug(XP$0Kn+41pTK2yyPCs`6To3fslSMXP8O zh*#e-Vl1t!-bY6($;$rqz6E^itVTx|Z=}+oE*8c_8>vw5`=QI@b(;0h*V|XoNg_Mr zVUoljgkIKVT;hB#>YH+QiY@{cF}p8$ds z1QVZ5+OaWd*CzYYV)N6c@_D_f<*qv@OZCB4sE~80kf1s%OwGivlO@RQn_v~2l&l*@ z0r>_!&Lh1ffkA?@uuDc45GTF~Q`syF%S1J6B3rb+x851f-DYZOO?#+ny#LE*$O1&G ze*cC(9GMZ%!_Yezt-2V2LYJ&!JG)w8s2|@-w?{<|qgb|PUMOn_akTiOz?qGrVOPHR zw&r`b=Hjr^zmJN};i>h?Bs*ft!~xA`y|}&0{X!W33kihfav6}$Y{tZ$vwTI29eXWc~n5EGxA}`lvT{Nni;G@8M#i88f?9`^md_;FnG8&NI6=b~*&Bz{%b&%)MG^ z2YmbVx#*(#<(LFy`B`}7+%2Z#Kv+^ec8j3IF8!?v2G9i2DpVUPV2wLb}^>3L9XZh4~X#(%Is!cd^uu>GCn7$Fnnn_*9++ozK(6 z1CLNuue^3>edaeMEFo8t&?Y=`N%XuC#5Hy)`1(er)QpVY8+X|Ia=yb<<&LKz1M#Uj zcqnu(S+Y{mAVM)P)0BT^5t4D)eF6XOD#GGZxbf_iZ^y9eeE;kl3M<{<+&agvs)DLB zEqD0P0CkNW_+o;Pe`8O+-Sf;m@gnD9C%`QY&r}G4F&lnzb`a~AraqIOW}_^3k{$;- zgVp0olK47tcm>z(&ewM1GHLYoxaiV&slhSg2giD^N66b&)rms?iOr?DPS}1A{{EEq zHRd}Ih~b;drDMRy`IHav*m?_uJq5|K8eQoAp@EuBoQK`L;-%4jn~&o71SK!=i#135 zw?>aOE|#=g4BYke@4T3kIp{FMfrwgOMu|ryVCKutHXq4V26}csrSkvQSYOD2dMH}Z z4Ai>-J#86DtkMX7e@%CEdRBAu`RVa)S63HaDB{Ax{RIn4&BO+%Tl4ED$Yn21PD&8y zcKlPwKz5p%J@G7ulS7xQHzB(FWM?F#uj2kUc1C#HCV6b`&I>0qtq!@eEx~Y{(S`^B zPVkI4p@d6LSIjDh>^NbDU$t0l{9RIEYSL*ItoeFsbE6cOYDScl9wgUq6h!RpxwHV8 zaMn!P#TQ;J!{pEZ#=ngAtK_mdMVfRSjYL8 z#3VzI?zlo7twd{ZNPXXjl=;w^j?k`8~wVKlzwamDPE z3G~{Y1eFzVJ8zkQgRWUattxZz){heO#uhBnhSwAo>clnKf5HlrX zaVE1xw-uujZdi6WXrMA^EcT7+^jTEJ3b?7N*Yiuy4WpdBvWKf4p#_dfQ;7<(Q4LZ+ zyAN{26&1U0A{Q2#5^AE*lToDIJv`#m4XetMuU#~I_G9fDpx zk9mdfytze5qPc@Zr8~O08I@WQ%gL=BWpqI**XU5kg-a%LJtzzk*ba+Kg zAr?=);Hv`2Hua~B@^mxe8w^{4ji>f-qs{&-%%jHcBOKT zm&6dryAGimC;pWFX6pjGa%mlIU4zsI>vOM>M{f_6xEFW)8?vPzlVyD`;N*h7oL2MB zN%ck5FIM-B)HaX4!q=rll?<==m=|mmAv9#%k~jN?dt>8M9<4Ko$yfG<2KuBf!8w^) zgjpX-1{^9aN1yCZJNoKdzwl~1I2)(nS#V(qUYu)paL$!fYAUKwxV9{SPu<8_V{H&0 zg@jGn2{{JRA0kzqmxF!^0i?g7mNS3K#ZJurn@EWvM1^$P2|PJFPL%OovyU2t{=J%W z=UNvTU0(g*-z|XJ{rO7M2uDOWPuW@JZa$inc5ecThdc28NfA*k8Z!zR}*dS(QF(+lQ-77#{<|(kqj(W9Pg+?wbv_ zAy4LQV$bzR*PmWGEYUZ$IS^p&6N*}Ny(A@!o8yPALHFxl_FoL+(66kDW*XjSp_k=R zO2|Bn(gjOf=)9>GWiQX@R!z05>`T_ z-%tM~O^BPHU zE>X>PgEP|$AvKdcSfz9l&+pMcZ9gg_u1&RW*J$1<|8zTnvP9d2&T8p}&a$D$*Aos1 z{?~1jD`_Pzm*!nV+Ut?F(0l23Bv0ss^!u5XWwm_Rn8Yre!kx4cXsY5OQZlsH4Xrl8 zE~l+)8)%)gzsj$Q86p^)(EaMaW|E6u&|n!TWwP5nd?8?+b;%rVmAJCh2=QO6GSdR=+GD0_Cw9jQQBkA50OH+D1VMznkM7ex!#*mjQ>q-5ORr9_wqs?L6; zQ+>{xz;3*@QVRe4++pzePcCGggf?Z*4x?t$oat≷M;ofIlbkj|#QtLbR!I~=} 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 literal 0 HcmV?d00001