diff --git a/kevisual.json b/kevisual.json new file mode 100644 index 0000000..ca52328 --- /dev/null +++ b/kevisual.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://kevisual.xiongxiao.me/root/ai/kevisual/tools/kevisual-sync/schema.json?v=2", + "metadata": { + "share": "public" + }, + "checkDir": { + "src/query": { + "url": "https://kevisual.xiongxiao.me/root/ai/code/registry/query", + "enabled": true + } + }, + "syncDirectory": [ + { + "files": [ + "src/query/**/*" + ], + "ignore": [], + "registry": "https://kevisual.xiongxiao.me/root/ai/code/registry", + "replace": { + "src/": "" + } + } + ], + "sync": {} +} \ No newline at end of file diff --git a/package.json b/package.json index 629f536..b5813bb 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@kevisual/codemirror": "workspace:*", "@kevisual/components": "workspace:*", "@kevisual/container": "1.0.0", - "@kevisual/query": "^0.0.28", + "@kevisual/query": "^0.0.29", "@kevisual/query-config": "workspace:*", "@kevisual/query-login": "workspace:*", "@kevisual/query-upload": "workspace:*", @@ -34,9 +34,9 @@ "@monaco-editor/react": "^4.7.0", "@mui/material": "^7.1.1", "@stackblitz/sdk": "^1.11.0", - "@tailwindcss/vite": "^4.1.8", + "@tailwindcss/vite": "^4.1.10", "@uiw/react-textarea-code-editor": "^3.1.1", - "antd": "^5.25.4", + "antd": "^5.26.1", "clsx": "^2.1.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.13", @@ -52,9 +52,9 @@ "react": "19.1.0", "react-dom": "19.1.0", "react-dropzone": "^14.3.8", - "react-hook-form": "^7.57.0", - "react-i18next": "^15.5.2", - "react-resizable-panels": "^3.0.2", + "react-hook-form": "^7.58.1", + "react-i18next": "^15.5.3", + "react-resizable-panels": "^3.0.3", "react-router": "^7.6.2", "react-router-dom": "^7.6.2", "react-toastify": "^11.0.5", @@ -62,35 +62,35 @@ "zustand": "^5.0.5" }, "devDependencies": { - "@eslint/js": "^9.28.0", + "@eslint/js": "^9.29.0", "@kevisual/ssl": "^0.0.1", "@types/js-yaml": "^4.0.9", "@types/lodash-es": "^4.17.12", - "@types/node": "^22.15.30", + "@types/node": "^24.0.3", "@types/path-browserify": "^1.0.3", "@types/qrcode": "^1.5.5", - "@types/react": "^19.1.6", + "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", "@vitejs/plugin-basic-ssl": "^2.0.0", - "@vitejs/plugin-react": "^4.5.1", + "@vitejs/plugin-react": "^4.5.2", "autoprefixer": "^10.4.21", "cross-env": "^7.0.3", - "eslint": "^9.28.0", + "eslint": "^9.29.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.2.0", - "lucide-react": "^0.513.0", + "lucide-react": "^0.516.0", "path-browserify": "^1.0.1", - "postcss-import": "^16.1.0", + "postcss-import": "^16.1.1", "pretty-bytes": "^7.0.0", "react-is": "19.1.0", - "tailwind-merge": "^3.3.0", - "tailwindcss": "^4.1.8", + "tailwind-merge": "^3.3.1", + "tailwindcss": "^4.1.10", "tailwindcss-animate": "^1.0.7", "turbo": "^2.5.4", "typescript": "^5.8.3", - "typescript-eslint": "^8.33.1", + "typescript-eslint": "^8.34.1", "vite": "^6.3.5" }, - "packageManager": "pnpm@10.11.1" + "packageManager": "pnpm@10.12.1" } \ No newline at end of file diff --git a/packages/resources/package.json b/packages/resources/package.json index 4786cf0..42e32fe 100644 --- a/packages/resources/package.json +++ b/packages/resources/package.json @@ -21,23 +21,23 @@ "@emotion/styled": "^11.14.0", "@kevisual/components": "workspace:*", "@kevisual/query-upload": "workspace:*", - "@kevisual/router": "^0.0.18", - "@kevisual/store": "^0.0.4", - "@mui/material": "^7.1.0", + "@kevisual/router": "^0.0.22", + "@kevisual/store": "^0.0.9", + "@mui/material": "^7.1.1", "@vitejs/plugin-basic-ssl": "^2.0.0", "dayjs": "^1.11.13", "immer": "^10.1.1", "lodash-es": "^4.17.21", - "lucide-react": "^0.510.0", + "lucide-react": "^0.516.0", "nanoid": "^5.1.5", "nprogress": "^0.2.0", "pretty-bytes": "^7.0.0", "react": "19.1.0", - "react-datepicker": "^8.3.0", + "react-datepicker": "^8.4.0", "react-dom": "19.1.0", "react-dropzone": "^14.3.8", "react-toastify": "^11.0.5", - "zustand": "^5.0.4" + "zustand": "^5.0.5" }, "devDependencies": { "@kevisual/types": "^0.0.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 12d4714..36037b2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,10 +13,10 @@ importers: version: 6.0.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@19.1.6)(react@19.1.0) + version: 11.14.0(@types/react@19.1.8)(react@19.1.0) '@emotion/styled': specifier: ^11.14.0 - version: 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) + version: 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) '@kevisual/cache': specifier: ^0.0.3 version: 0.0.3 @@ -28,10 +28,10 @@ importers: version: link:packages/components '@kevisual/container': specifier: 1.0.0 - version: 1.0.0(@emotion/css@11.13.4)(@types/react@19.1.6)(crypto-js@4.2.0)(eventemitter3@5.0.1)(immer@10.1.1)(react@19.1.0)(rollup@4.41.1)(typescript@5.8.3) + version: 1.0.0(@emotion/css@11.13.4)(@types/react@19.1.8)(crypto-js@4.2.0)(eventemitter3@5.0.1)(immer@10.1.1)(react@19.1.0)(rollup@4.41.1)(typescript@5.8.3) '@kevisual/query': - specifier: ^0.0.28 - version: 0.0.28(ws@8.18.1)(zod@3.24.4) + specifier: ^0.0.29 + version: 0.0.29(ws@8.18.1)(zod@3.24.4) '@kevisual/query-config': specifier: workspace:* version: link:submodules/query-config @@ -49,19 +49,19 @@ importers: version: 4.7.0(monaco-editor@0.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@mui/material': specifier: ^7.1.1 - version: 7.1.1(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 7.1.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@stackblitz/sdk': specifier: ^1.11.0 version: 1.11.0 '@tailwindcss/vite': - specifier: ^4.1.8 - version: 4.1.8(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) + specifier: ^4.1.10 + version: 4.1.10(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) '@uiw/react-textarea-code-editor': specifier: ^3.1.1 - version: 3.1.1(@babel/runtime@7.27.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 3.1.1(@babel/runtime@7.27.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) antd: - specifier: ^5.25.4 - version: 5.25.4(date-fns@4.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^5.26.1 + version: 5.26.1(date-fns@4.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -108,14 +108,14 @@ importers: specifier: ^14.3.8 version: 14.3.8(react@19.1.0) react-hook-form: - specifier: ^7.57.0 - version: 7.57.0(react@19.1.0) + specifier: ^7.58.1 + version: 7.58.1(react@19.1.0) react-i18next: - specifier: ^15.5.2 - version: 15.5.2(i18next@25.2.1(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3) + specifier: ^15.5.3 + version: 15.5.3(i18next@25.2.1(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3) react-resizable-panels: - specifier: ^3.0.2 - version: 3.0.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^3.0.3 + version: 3.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react-router: specifier: ^7.6.2 version: 7.6.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -127,14 +127,14 @@ importers: version: 11.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) vite-plugin-tsconfig-paths: specifier: ^1.4.1 - version: 1.4.1(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) + version: 1.4.1(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) zustand: specifier: ^5.0.5 - version: 5.0.5(@types/react@19.1.6)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) + version: 5.0.5(@types/react@19.1.8)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) devDependencies: '@eslint/js': - specifier: ^9.28.0 - version: 9.28.0 + specifier: ^9.29.0 + version: 9.29.0 '@kevisual/ssl': specifier: ^0.0.1 version: 0.0.1 @@ -145,8 +145,8 @@ importers: specifier: ^4.17.12 version: 4.17.12 '@types/node': - specifier: ^22.15.30 - version: 22.15.30 + specifier: ^24.0.3 + version: 24.0.3 '@types/path-browserify': specifier: ^1.0.3 version: 1.0.3 @@ -154,17 +154,17 @@ importers: specifier: ^1.5.5 version: 1.5.5 '@types/react': - specifier: ^19.1.6 - version: 19.1.6 + specifier: ^19.1.8 + version: 19.1.8 '@types/react-dom': specifier: ^19.1.6 - version: 19.1.6(@types/react@19.1.6) + version: 19.1.6(@types/react@19.1.8) '@vitejs/plugin-basic-ssl': specifier: ^2.0.0 - version: 2.0.0(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) + version: 2.0.0(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) '@vitejs/plugin-react': - specifier: ^4.5.1 - version: 4.5.1(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) + specifier: ^4.5.2 + version: 4.5.2(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.3) @@ -172,26 +172,26 @@ importers: specifier: ^7.0.3 version: 7.0.3 eslint: - specifier: ^9.28.0 - version: 9.28.0(jiti@2.4.2) + specifier: ^9.29.0 + version: 9.29.0(jiti@2.4.2) eslint-plugin-react-hooks: specifier: ^5.2.0 - version: 5.2.0(eslint@9.28.0(jiti@2.4.2)) + version: 5.2.0(eslint@9.29.0(jiti@2.4.2)) eslint-plugin-react-refresh: specifier: ^0.4.20 - version: 0.4.20(eslint@9.28.0(jiti@2.4.2)) + version: 0.4.20(eslint@9.29.0(jiti@2.4.2)) globals: specifier: ^16.2.0 version: 16.2.0 lucide-react: - specifier: ^0.513.0 - version: 0.513.0(react@19.1.0) + specifier: ^0.516.0 + version: 0.516.0(react@19.1.0) path-browserify: specifier: ^1.0.1 version: 1.0.1 postcss-import: - specifier: ^16.1.0 - version: 16.1.0(postcss@8.5.3) + specifier: ^16.1.1 + version: 16.1.1(postcss@8.5.3) pretty-bytes: specifier: ^7.0.0 version: 7.0.0 @@ -199,14 +199,14 @@ importers: specifier: 19.1.0 version: 19.1.0 tailwind-merge: - specifier: ^3.3.0 - version: 3.3.0 + specifier: ^3.3.1 + version: 3.3.1 tailwindcss: - specifier: ^4.1.8 - version: 4.1.8 + specifier: ^4.1.10 + version: 4.1.10 tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@4.1.8) + version: 1.0.7(tailwindcss@4.1.10) turbo: specifier: ^2.5.4 version: 2.5.4 @@ -214,11 +214,11 @@ importers: specifier: ^5.8.3 version: 5.8.3 typescript-eslint: - specifier: ^8.33.1 - version: 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + specifier: ^8.34.1 + version: 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) vite: specifier: ^6.3.5 - version: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) + version: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) packages/codemirror: dependencies: @@ -257,10 +257,10 @@ importers: version: 6.36.5 '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@19.1.6)(react@19.1.0) + version: 11.14.0(@types/react@19.1.8)(react@19.1.0) '@emotion/styled': specifier: ^11.14.0 - version: 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) + version: 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) '@kevisual/components': specifier: workspace:* version: link:../components @@ -272,7 +272,7 @@ importers: version: 0.0.4 '@mui/material': specifier: ^7.0.1 - version: 7.1.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 7.1.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@types/lodash-es': specifier: ^4.17.12 version: 4.17.12 @@ -287,7 +287,7 @@ importers: version: 4.23.10(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.5) '@vitejs/plugin-basic-ssl': specifier: ^2.0.0 - version: 2.0.0(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) + version: 2.0.0(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) codemirror: specifier: ^6.0.1 version: 6.0.1 @@ -341,7 +341,7 @@ importers: version: 11.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) zustand: specifier: ^5.0.3 - version: 5.0.5(@types/react@19.1.6)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) + version: 5.0.5(@types/react@19.1.8)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) devDependencies: '@kevisual/types': specifier: ^0.0.6 @@ -351,16 +351,16 @@ importers: dependencies: '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@19.1.6)(react@19.1.0) + version: 11.14.0(@types/react@19.1.8)(react@19.1.0) '@emotion/styled': specifier: ^11.14.0 - version: 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) + version: 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) '@kevisual/query-login': - specifier: ^0.0.5 - version: 0.0.5(@kevisual/query@0.0.28(ws@8.18.1)(zod@3.24.4))(rollup@4.41.1)(typescript@5.8.3) + specifier: ^0.0.6 + version: 0.0.6(@kevisual/query@0.0.29(ws@8.18.1)(zod@3.24.4))(rollup@4.41.1)(typescript@5.8.3) '@mui/material': - specifier: ^7.1.0 - version: 7.1.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^7.1.1 + version: 7.1.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) re-resizable: specifier: ^6.11.2 version: 6.11.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -374,18 +374,18 @@ importers: specifier: ^4.4.6 version: 4.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react-hook-form: - specifier: ^7.56.3 - version: 7.56.3(react@19.1.0) + specifier: ^7.58.1 + version: 7.58.1(react@19.1.0) react-i18next: - specifier: ^15.5.1 - version: 15.5.1(i18next@25.2.1(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3) + specifier: ^15.5.3 + version: 15.5.3(i18next@25.2.1(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3) devDependencies: clsx: specifier: ^2.1.1 version: 2.1.1 tailwind-merge: - specifier: ^3.3.0 - version: 3.3.0 + specifier: ^3.3.1 + version: 3.3.1 packages/kevisual-official: dependencies: @@ -404,7 +404,7 @@ importers: devDependencies: '@tailwindcss/vite': specifier: ^4.0.15 - version: 4.1.6(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) + version: 4.1.6(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) '@types/react': specifier: ^19.0.0 version: 19.1.4 @@ -413,13 +413,13 @@ importers: version: 19.1.5(@types/react@19.1.4) '@vitejs/plugin-react': specifier: ^4.3.4 - version: 4.4.1(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) + version: 4.4.1(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) tailwindcss: specifier: ^4.0.15 version: 4.1.6 vite: specifier: ^6.2.3 - version: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) + version: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) packages/mark: dependencies: @@ -507,10 +507,10 @@ importers: dependencies: '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@19.1.6)(react@19.1.0) + version: 11.14.0(@types/react@19.1.8)(react@19.1.0) '@emotion/styled': specifier: ^11.14.0 - version: 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) + version: 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) '@kevisual/components': specifier: workspace:* version: link:../components @@ -518,17 +518,17 @@ importers: specifier: workspace:* version: link:../../submodules/query-upload '@kevisual/router': - specifier: ^0.0.18 - version: 0.0.18 + specifier: ^0.0.22 + version: 0.0.22 '@kevisual/store': - specifier: ^0.0.4 - version: 0.0.4 + specifier: ^0.0.9 + version: 0.0.9 '@mui/material': - specifier: ^7.1.0 - version: 7.1.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^7.1.1 + version: 7.1.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@vitejs/plugin-basic-ssl': specifier: ^2.0.0 - version: 2.0.0(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) + version: 2.0.0(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)) dayjs: specifier: ^1.11.13 version: 1.11.13 @@ -539,8 +539,8 @@ importers: specifier: ^4.17.21 version: 4.17.21 lucide-react: - specifier: ^0.510.0 - version: 0.510.0(react@19.1.0) + specifier: ^0.516.0 + version: 0.516.0(react@19.1.0) nanoid: specifier: ^5.1.5 version: 5.1.5 @@ -554,8 +554,8 @@ importers: specifier: 19.1.0 version: 19.1.0 react-datepicker: - specifier: ^8.3.0 - version: 8.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^8.4.0 + version: 8.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react-dom: specifier: 19.1.0 version: 19.1.0(react@19.1.0) @@ -566,8 +566,8 @@ importers: specifier: ^11.0.5 version: 11.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) zustand: - specifier: ^5.0.4 - version: 5.0.5(@types/react@19.1.6)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) + specifier: ^5.0.5 + version: 5.0.5(@types/react@19.1.8)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) devDependencies: '@kevisual/types': specifier: ^0.0.10 @@ -666,7 +666,7 @@ importers: devDependencies: tsup: specifier: ^8.4.0 - version: 8.4.0(@microsoft/api-extractor@7.52.2(@types/node@22.15.30))(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.3)(yaml@2.5.1) + version: 8.4.0(@microsoft/api-extractor@7.52.2(@types/node@24.0.3))(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.3)(yaml@2.5.1) submodules/query-login: dependencies: @@ -720,6 +720,9 @@ importers: submodules/store: devDependencies: + '@kevisual/context': + specifier: ^0.0.3 + version: 0.0.3 '@kevisual/load': specifier: ^0.0.6 version: 0.0.6 @@ -770,7 +773,7 @@ importers: version: 6.2.1(rollup@4.41.1)(typescript@5.8.3) ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@22.15.30)(typescript@5.8.3) + version: 10.9.2(@types/node@24.0.3)(typescript@5.8.3) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -779,7 +782,7 @@ importers: version: 5.8.3 zustand: specifier: ^5.0.5 - version: 5.0.5(@types/react@19.1.6)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) + version: 5.0.5(@types/react@19.1.8)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) submodules/wallnote: dependencies: @@ -1041,69 +1044,136 @@ packages: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.26.8': resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.27.5': + resolution: {integrity: sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==} + engines: {node: '>=6.9.0'} + '@babel/core@7.26.10': resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} engines: {node: '>=6.9.0'} + '@babel/core@7.27.4': + resolution: {integrity: sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.26.10': resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==} engines: {node: '>=6.9.0'} + '@babel/generator@7.27.5': + resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.26.5': resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.25.9': resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.26.0': resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-plugin-utils@7.26.5': resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.25.9': resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + '@babel/helpers@7.26.10': resolution: {integrity: sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.27.6': + resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.26.10': resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.27.5': + resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-transform-react-jsx-self@7.25.9': resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-source@7.25.9': resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime@7.26.0': resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} @@ -1116,18 +1186,34 @@ packages: resolution: {integrity: sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.27.6': + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} + engines: {node: '>=6.9.0'} + '@babel/template@7.26.9': resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.26.10': resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.27.4': + resolution: {integrity: sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.26.10': resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} engines: {node: '>=6.9.0'} + '@babel/types@7.27.6': + resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} + engines: {node: '>=6.9.0'} + '@codemirror/autocomplete@6.18.6': resolution: {integrity: sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==} @@ -1404,6 +1490,10 @@ packages: resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-array@0.20.1': + resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-helpers@0.2.2': resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1424,8 +1514,8 @@ packages: resolution: {integrity: sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.28.0': - resolution: {integrity: sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==} + '@eslint/js@9.29.0': + resolution: {integrity: sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -1529,11 +1619,14 @@ packages: crypto-js: ^4.2.0 eventemitter3: ^5.0.1 + '@kevisual/context@0.0.3': + resolution: {integrity: sha512-cYpqVmoHVjv3NrGMU1e6iyiPDKRtNnK2wOWgbBU5d+8IHuC8VYHTg2GY5bnD/272GK7EYdr9x/c3QgsCIqR2BQ==} + '@kevisual/load@0.0.6': resolution: {integrity: sha512-+3YTFehRcZ1haGel5DKYMUwmi5i6f2psyaPZlfkKU/cOXgkpwoG9/BEqPCnPjicKqqnksEpixVRkyHJ+5bjLVA==} - '@kevisual/query-login@0.0.5': - resolution: {integrity: sha512-389cMMWAisjQoafxX+cUEa2z41S5koDjiyHkucfCkhRoP4M6g0iqbBMavLKmLOWSKx3R8e3ZmXT6RfsYGBb8Ww==} + '@kevisual/query-login@0.0.6': + resolution: {integrity: sha512-ZdX+sxeQaM3PV9fZXofMlxFz1RmpYIkoi47exzUgw6DADjEryBAQKRXe2/oL20NsBTV8owqaagRqffAVjq5c5g==} peerDependencies: '@kevisual/query': ^0.0.17 @@ -1546,18 +1639,18 @@ packages: '@kevisual/query@0.0.17': resolution: {integrity: sha512-WMvWM+3pNlPKNhoxPX9fldMp1tOeJrkRM/tXA4bvOnftIoX2yeI4v0wTpbGJXES/bLlo7OC2kV8SeKF0K6dnxQ==} - '@kevisual/query@0.0.28': - resolution: {integrity: sha512-ijgKhfYzrNEoRuQOVD/ed8fqo+MKcNdvNFCBFHiBLVtyUrnSVNeEeyoM3eEw9iASBCltR1L4yoVn4Rls2jvpFA==} + '@kevisual/query@0.0.29': + resolution: {integrity: sha512-rQZk0J073UuC1QGzuyq+pb4Y0hu8/Qx/xYHs9NbsmslM+RuMnd1zpXmvhXNj7Kn1MdYTH90ng2MlFLBkkQFaIg==} '@kevisual/router@0.0.10': resolution: {integrity: sha512-prQGiMIboQhDNN1Eubp8x7YDyRCmAsUqpHQwzfu9f7WvgisVWSLOWSaLbqjqNssV2xcc1DgVrHIKdLhbx8HCqQ==} - '@kevisual/router@0.0.18': - resolution: {integrity: sha512-U7j2NDVFYmiNhkSEJY8U9GlZng0g4v9uv9OeqsOqjao2UA29O21yI+G4AF3DVA71DNkMNFqB+x968LsXln1AZw==} - '@kevisual/router@0.0.21': resolution: {integrity: sha512-XKTxbNO924cT18UOAGplWErZ+hMze8Y53F2jYCk18v4jsdsvjRho5uXXjJb6HSVsuITMtQR4R3rG0IcM3jkDKQ==} + '@kevisual/router@0.0.22': + resolution: {integrity: sha512-Cqv2vV+hPBHrMMfvWlfDIuNrQcmd260oQZ4S5QR/R4tV35XtMKiseqhnC9uR09oVBJUh+d5rW3YucDDddheeDQ==} + '@kevisual/router@0.0.9': resolution: {integrity: sha512-qPyC2GVJ7iOIdJCCKNDsWMAKOQeSJW9HBpL5ZWKHTbi+t4jJBGTzIlXmjKeMHRd0lr/Qq1imQvlkSh4hlrbodA==} @@ -1567,6 +1660,9 @@ packages: '@kevisual/store@0.0.4': resolution: {integrity: sha512-iOgUg7VfyV8au27wSt0DdFqptcykb0mOAayCWChjgfKRKaLh4B021VBn5bdfyrfN1ektJo0ibsapd/QAN6GBtg==} + '@kevisual/store@0.0.9': + resolution: {integrity: sha512-j6OiVcKbws23AvIwlDBL16ohGmZrRxi/OlH2i/UEScW2hKZo7vICXKySHom4ZzrnlwLV5JzKu4fVP48allGOeA==} + '@kevisual/system-lib@0.0.22': resolution: {integrity: sha512-kdzYlWLH+TGnNe4BfzB4Lk7jRdQE/KMQnMguWvPXdOb/aRiwJFVjlfYoNtA6BXgNC9MOpJ59CzFRc+EsMx1HRw==} @@ -1882,8 +1978,8 @@ packages: '@remirror/core-constants@3.0.0': resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} - '@rolldown/pluginutils@1.0.0-beta.9': - resolution: {integrity: sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==} + '@rolldown/pluginutils@1.0.0-beta.11': + resolution: {integrity: sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==} '@rollup/plugin-commonjs@28.0.3': resolution: {integrity: sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==} @@ -2257,11 +2353,17 @@ packages: '@stackblitz/sdk@1.11.0': resolution: {integrity: sha512-DFQGANNkEZRzFk1/rDP6TcFdM82ycHE+zfl9C/M/jXlH68jiqHWHFMQURLELoD8koxvu/eW5uhg94NSAZlYrUQ==} + '@tailwindcss/node@4.1.10': + resolution: {integrity: sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==} + '@tailwindcss/node@4.1.6': resolution: {integrity: sha512-ed6zQbgmKsjsVvodAS1q1Ld2BolEuxJOSyyNc+vhkjdmfNUDCmQnlXBfQkHrlzNmslxHsQU/bFmzcEbv4xXsLg==} - '@tailwindcss/node@4.1.8': - resolution: {integrity: sha512-OWwBsbC9BFAJelmnNcrKuf+bka2ZxCE2A4Ft53Tkg4uoiE67r/PMEYwCsourC26E+kmxfwE0hVzMdxqeW+xu7Q==} + '@tailwindcss/oxide-android-arm64@4.1.10': + resolution: {integrity: sha512-VGLazCoRQ7rtsCzThaI1UyDu/XRYVyH4/EWiaSX6tFglE+xZB5cvtC5Omt0OQ+FfiIVP98su16jDVHDEIuH4iQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] '@tailwindcss/oxide-android-arm64@4.1.6': resolution: {integrity: sha512-VHwwPiwXtdIvOvqT/0/FLH/pizTVu78FOnI9jQo64kSAikFSZT7K4pjyzoDpSMaveJTGyAKvDjuhxJxKfmvjiQ==} @@ -2269,11 +2371,11 @@ packages: cpu: [arm64] os: [android] - '@tailwindcss/oxide-android-arm64@4.1.8': - resolution: {integrity: sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg==} + '@tailwindcss/oxide-darwin-arm64@4.1.10': + resolution: {integrity: sha512-ZIFqvR1irX2yNjWJzKCqTCcHZbgkSkSkZKbRM3BPzhDL/18idA8uWCoopYA2CSDdSGFlDAxYdU2yBHwAwx8euQ==} engines: {node: '>= 10'} cpu: [arm64] - os: [android] + os: [darwin] '@tailwindcss/oxide-darwin-arm64@4.1.6': resolution: {integrity: sha512-weINOCcqv1HVBIGptNrk7c6lWgSFFiQMcCpKM4tnVi5x8OY2v1FrV76jwLukfT6pL1hyajc06tyVmZFYXoxvhQ==} @@ -2281,10 +2383,10 @@ packages: cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-arm64@4.1.8': - resolution: {integrity: sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A==} + '@tailwindcss/oxide-darwin-x64@4.1.10': + resolution: {integrity: sha512-eCA4zbIhWUFDXoamNztmS0MjXHSEJYlvATzWnRiTqJkcUteSjO94PoRHJy1Xbwp9bptjeIxxBHh+zBWFhttbrQ==} engines: {node: '>= 10'} - cpu: [arm64] + cpu: [x64] os: [darwin] '@tailwindcss/oxide-darwin-x64@4.1.6': @@ -2293,11 +2395,11 @@ packages: cpu: [x64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.1.8': - resolution: {integrity: sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw==} + '@tailwindcss/oxide-freebsd-x64@4.1.10': + resolution: {integrity: sha512-8/392Xu12R0cc93DpiJvNpJ4wYVSiciUlkiOHOSOQNH3adq9Gi/dtySK7dVQjXIOzlpSHjeCL89RUUI8/GTI6g==} engines: {node: '>= 10'} cpu: [x64] - os: [darwin] + os: [freebsd] '@tailwindcss/oxide-freebsd-x64@4.1.6': resolution: {integrity: sha512-4m5F5lpkBZhVQJq53oe5XgJ+aFYWdrgkMwViHjRsES3KEu2m1udR21B1I77RUqie0ZYNscFzY1v9aDssMBZ/1w==} @@ -2305,11 +2407,11 @@ packages: cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-freebsd-x64@4.1.8': - resolution: {integrity: sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.10': + resolution: {integrity: sha512-t9rhmLT6EqeuPT+MXhWhlRYIMSfh5LZ6kBrC4FS6/+M1yXwfCtp24UumgCWOAJVyjQwG+lYva6wWZxrfvB+NhQ==} engines: {node: '>= 10'} - cpu: [x64] - os: [freebsd] + cpu: [arm] + os: [linux] '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.6': resolution: {integrity: sha512-qU0rHnA9P/ZoaDKouU1oGPxPWzDKtIfX7eOGi5jOWJKdxieUJdVV+CxWZOpDWlYTd4N3sFQvcnVLJWJ1cLP5TA==} @@ -2317,10 +2419,10 @@ packages: cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8': - resolution: {integrity: sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ==} + '@tailwindcss/oxide-linux-arm64-gnu@4.1.10': + resolution: {integrity: sha512-3oWrlNlxLRxXejQ8zImzrVLuZ/9Z2SeKoLhtCu0hpo38hTO2iL86eFOu4sVR8cZc6n3z7eRXXqtHJECa6mFOvA==} engines: {node: '>= 10'} - cpu: [arm] + cpu: [arm64] os: [linux] '@tailwindcss/oxide-linux-arm64-gnu@4.1.6': @@ -2329,8 +2431,8 @@ packages: cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.1.8': - resolution: {integrity: sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q==} + '@tailwindcss/oxide-linux-arm64-musl@4.1.10': + resolution: {integrity: sha512-saScU0cmWvg/Ez4gUmQWr9pvY9Kssxt+Xenfx1LG7LmqjcrvBnw4r9VjkFcqmbBb7GCBwYNcZi9X3/oMda9sqQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -2341,10 +2443,10 @@ packages: cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.1.8': - resolution: {integrity: sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ==} + '@tailwindcss/oxide-linux-x64-gnu@4.1.10': + resolution: {integrity: sha512-/G3ao/ybV9YEEgAXeEg28dyH6gs1QG8tvdN9c2MNZdUXYBaIY/Gx0N6RlJzfLy/7Nkdok4kaxKPHKJUlAaoTdA==} engines: {node: '>= 10'} - cpu: [arm64] + cpu: [x64] os: [linux] '@tailwindcss/oxide-linux-x64-gnu@4.1.6': @@ -2353,8 +2455,8 @@ packages: cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.1.8': - resolution: {integrity: sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g==} + '@tailwindcss/oxide-linux-x64-musl@4.1.10': + resolution: {integrity: sha512-LNr7X8fTiKGRtQGOerSayc2pWJp/9ptRYAa4G+U+cjw9kJZvkopav1AQc5HHD+U364f71tZv6XamaHKgrIoVzA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -2365,11 +2467,17 @@ packages: cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.1.8': - resolution: {integrity: sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] + '@tailwindcss/oxide-wasm32-wasi@4.1.10': + resolution: {integrity: sha512-d6ekQpopFQJAcIK2i7ZzWOYGZ+A6NzzvQ3ozBvWFdeyqfOZdYHU66g5yr+/HC4ipP1ZgWsqa80+ISNILk+ae/Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib '@tailwindcss/oxide-wasm32-wasi@4.1.6': resolution: {integrity: sha512-qAp4ooTYrBQ5pk5jgg54/U1rCJ/9FLYOkkQ/nTE+bVMseMfB6O7J8zb19YTpWuu4UdfRf5zzOrNKfl6T64MNrQ==} @@ -2383,17 +2491,11 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-wasm32-wasi@4.1.8': - resolution: {integrity: sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - bundledDependencies: - - '@napi-rs/wasm-runtime' - - '@emnapi/core' - - '@emnapi/runtime' - - '@tybys/wasm-util' - - '@emnapi/wasi-threads' - - tslib + '@tailwindcss/oxide-win32-arm64-msvc@4.1.10': + resolution: {integrity: sha512-i1Iwg9gRbwNVOCYmnigWCCgow8nDWSFmeTUU5nbNx3rqbe4p0kRbEqLwLJbYZKmSSp23g4N6rCDmm7OuPBXhDA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] '@tailwindcss/oxide-win32-arm64-msvc@4.1.6': resolution: {integrity: sha512-nqpDWk0Xr8ELO/nfRUDjk1pc9wDJ3ObeDdNMHLaymc4PJBWj11gdPCWZFKSK2AVKjJQC7J2EfmSmf47GN7OuLg==} @@ -2401,10 +2503,10 @@ packages: cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-arm64-msvc@4.1.8': - resolution: {integrity: sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA==} + '@tailwindcss/oxide-win32-x64-msvc@4.1.10': + resolution: {integrity: sha512-sGiJTjcBSfGq2DVRtaSljq5ZgZS2SDHSIfhOylkBvHVjwOsodBhnb3HdmiKkVuUGKD0I7G63abMOVaskj1KpOA==} engines: {node: '>= 10'} - cpu: [arm64] + cpu: [x64] os: [win32] '@tailwindcss/oxide-win32-x64-msvc@4.1.6': @@ -2413,27 +2515,21 @@ packages: cpu: [x64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.1.8': - resolution: {integrity: sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ==} + '@tailwindcss/oxide@4.1.10': + resolution: {integrity: sha512-v0C43s7Pjw+B9w21htrQwuFObSkio2aV/qPx/mhrRldbqxbWJK6KizM+q7BF1/1CmuLqZqX3CeYF7s7P9fbA8Q==} engines: {node: '>= 10'} - cpu: [x64] - os: [win32] '@tailwindcss/oxide@4.1.6': resolution: {integrity: sha512-0bpEBQiGx+227fW4G0fLQ8vuvyy5rsB1YIYNapTq3aRsJ9taF3f5cCaovDjN5pUGKKzcpMrZst/mhNaKAPOHOA==} engines: {node: '>= 10'} - '@tailwindcss/oxide@4.1.8': - resolution: {integrity: sha512-d7qvv9PsM5N3VNKhwVUhpK6r4h9wtLkJ6lz9ZY9aeZgrUWk1Z8VPyqyDT9MZlem7GTGseRQHkeB1j3tC7W1P+A==} - engines: {node: '>= 10'} - - '@tailwindcss/vite@4.1.6': - resolution: {integrity: sha512-zjtqjDeY1w3g2beYQtrMAf51n5G7o+UwmyOjtsDMP7t6XyoRMOidcoKP32ps7AkNOHIXEOK0bhIC05dj8oJp4w==} + '@tailwindcss/vite@4.1.10': + resolution: {integrity: sha512-QWnD5HDY2IADv+vYR82lOhqOlS1jSCUUAmfem52cXAhRTKxpDh3ARX8TTXJTCCO7Rv7cD2Nlekabv02bwP3a2A==} peerDependencies: vite: ^5.2.0 || ^6 - '@tailwindcss/vite@4.1.8': - resolution: {integrity: sha512-CQ+I8yxNV5/6uGaJjiuymgw0kEQiNKRinYbZXPdx1fk5WgiyReG0VaUx/Xq6aVNSUNJFzxm6o8FNKS5aMaim5A==} + '@tailwindcss/vite@4.1.6': + resolution: {integrity: sha512-zjtqjDeY1w3g2beYQtrMAf51n5G7o+UwmyOjtsDMP7t6XyoRMOidcoKP32ps7AkNOHIXEOK0bhIC05dj8oJp4w==} peerDependencies: vite: ^5.2.0 || ^6 @@ -2684,6 +2780,9 @@ packages: '@types/node@22.15.30': resolution: {integrity: sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==} + '@types/node@24.0.3': + resolution: {integrity: sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==} + '@types/nprogress@0.2.3': resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==} @@ -2723,8 +2822,8 @@ packages: '@types/react@19.1.4': resolution: {integrity: sha512-EB1yiiYdvySuIITtD5lhW4yPyJ31RkJkkDw794LaQYrxCSaQV/47y5o1FMC4zF9ZyjUjzJMZwbovEnT5yHTW6g==} - '@types/react@19.1.6': - resolution: {integrity: sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==} + '@types/react@19.1.8': + resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -2746,11 +2845,11 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/eslint-plugin@8.33.1': - resolution: {integrity: sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==} + '@typescript-eslint/eslint-plugin@8.34.1': + resolution: {integrity: sha512-STXcN6ebF6li4PxwNeFnqF8/2BNDvBupf2OPx2yWNzr6mKNGF7q49VM00Pz5FaomJyqvbXpY6PhO+T9w139YEQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.33.1 + '@typescript-eslint/parser': ^8.34.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' @@ -2761,15 +2860,15 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.33.1': - resolution: {integrity: sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==} + '@typescript-eslint/parser@8.34.1': + resolution: {integrity: sha512-4O3idHxhyzjClSMJ0a29AcoK0+YwnEqzI6oz3vlRf3xw0zbzt15MzXwItOlnr5nIth6zlY2RENLsOPvhyrKAQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/project-service@8.33.1': - resolution: {integrity: sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==} + '@typescript-eslint/project-service@8.34.1': + resolution: {integrity: sha512-nuHlOmFZfuRwLJKDGQOVc0xnQrAmuq1Mj/ISou5044y1ajGNp2BNliIqp7F2LPQ5sForz8lempMFCovfeS1XoA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' @@ -2778,12 +2877,12 @@ packages: resolution: {integrity: sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.33.1': - resolution: {integrity: sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==} + '@typescript-eslint/scope-manager@8.34.1': + resolution: {integrity: sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.33.1': - resolution: {integrity: sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==} + '@typescript-eslint/tsconfig-utils@8.34.1': + resolution: {integrity: sha512-K4Sjdo4/xF9NEeA2khOb7Y5nY6NSXBnod87uniVYW9kHP+hNlDV8trUSFeynA2uxWam4gIWgWoygPrv9VMWrYg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' @@ -2795,8 +2894,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/type-utils@8.33.1': - resolution: {integrity: sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==} + '@typescript-eslint/type-utils@8.34.1': + resolution: {integrity: sha512-Tv7tCCr6e5m8hP4+xFugcrwTOucB8lshffJ6zf1mF1TbU67R+ntCc6DzLNKM+s/uzDyv8gLq7tufaAhIBYeV8g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2806,8 +2905,8 @@ packages: resolution: {integrity: sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.33.1': - resolution: {integrity: sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==} + '@typescript-eslint/types@8.34.1': + resolution: {integrity: sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.32.1': @@ -2816,8 +2915,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/typescript-estree@8.33.1': - resolution: {integrity: sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==} + '@typescript-eslint/typescript-estree@8.34.1': + resolution: {integrity: sha512-rjCNqqYPuMUF5ODD+hWBNmOitjBWghkGKJg6hiCHzUvXRy6rK22Jd3rwbP2Xi+R7oYVvIKhokHVhH41BxPV5mA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' @@ -2829,8 +2928,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.33.1': - resolution: {integrity: sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==} + '@typescript-eslint/utils@8.34.1': + resolution: {integrity: sha512-mqOwUdZ3KjtGk7xJJnLbHxTuWVn3GO2WZZuM+Slhkun4+qthLdXx32C8xIXbO1kfCECb3jIs3eoxK3eryk7aoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2840,8 +2939,8 @@ packages: resolution: {integrity: sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.33.1': - resolution: {integrity: sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==} + '@typescript-eslint/visitor-keys@8.34.1': + resolution: {integrity: sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@uiw/codemirror-theme-duotone@4.23.10': @@ -2879,11 +2978,11 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 - '@vitejs/plugin-react@4.5.1': - resolution: {integrity: sha512-uPZBqSI0YD4lpkIru6M35sIfylLGTyhGHvDZbNLuMA73lMlwJKz5xweH7FajfcCAc2HnINciejA9qTz0dr0M7A==} + '@vitejs/plugin-react@4.5.2': + resolution: {integrity: sha512-QNVT3/Lxx99nMQWJWF7K4N6apUEuT0KlZA3mx/mVaoGj3smm/8rc8ezz15J1pcbcjDK0V15rpHetVfya08r76Q==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 '@xterm/xterm@5.5.0': resolution: {integrity: sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==} @@ -2919,6 +3018,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + agentkeepalive@4.6.0: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} engines: {node: '>= 8.0.0'} @@ -2964,8 +3068,8 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - antd@5.25.4: - resolution: {integrity: sha512-yXdWqq1NJSZnD1HoPZWnWuQJGVYYnB3h0Ufsz4sbt3T0N9SdJ4G9GPpLMk8Gn9zWtwBekfR4THPVZ9uzAyhBHQ==} + antd@5.26.1: + resolution: {integrity: sha512-CiLGZ2Ftld+fuoj+U3OL8uouuqUppqFJnW4O/4bOgSWzM9XsJGibpNtUa9QArhrZ5ndfnzlPP/4RVXUK/xfSvQ==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' @@ -3408,6 +3512,10 @@ packages: resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3416,6 +3524,10 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint@9.26.0: resolution: {integrity: sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3426,8 +3538,8 @@ packages: jiti: optional: true - eslint@9.28.0: - resolution: {integrity: sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==} + eslint@9.29.0: + resolution: {integrity: sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -3440,6 +3552,10 @@ packages: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -4074,13 +4190,8 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - lucide-react@0.510.0: - resolution: {integrity: sha512-p8SQRAMVh7NhsAIETokSqDrc5CHnDLbV29mMnzaXx+Vc/hnqQzwI2r0FMWCcoTXnbw2KEjy48xwpGdEL+ck06Q==} - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - lucide-react@0.513.0: - resolution: {integrity: sha512-CJZKq2g8Y8yN4Aq002GahSXbG2JpFv9kXwyiOAMvUBv7pxeOFHUWKB0mO7MiY4ZVFCV4aNjv2BJFq/z3DgKPQg==} + lucide-react@0.516.0: + resolution: {integrity: sha512-aybBJzLHcw1CIn3rUcRkztB37dsJATtpffLNX+0/w+ws2p21nYIlOwX/B5fqxq8F/BjqVemnJX8chKwRidvROg==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -4388,8 +4499,8 @@ packages: resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} engines: {node: '>=10.13.0'} - postcss-import@16.1.0: - resolution: {integrity: sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==} + postcss-import@16.1.1: + resolution: {integrity: sha512-2xVS1NCZAfjtVdvXiyegxzJ447GyqCeEI5V7ApgQVOWnros1p5lGNovJNapwPpMombyFBfqDwt7AD3n2l0KOfQ==} engines: {node: '>=18.0.0'} peerDependencies: postcss: ^8.0.0 @@ -4708,8 +4819,8 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - rc-table@7.50.5: - resolution: {integrity: sha512-FDZu8aolhSYd3v9KOc3lZOVAU77wmRRu44R0Wfb8Oj1dXRUsloFaXMSl6f7yuWZUxArJTli7k8TEOX2mvhDl4A==} + rc-table@7.51.1: + resolution: {integrity: sha512-5iq15mTHhvC42TlBLRCoCBLoCmGlbRZAlyF21FonFnS/DIC8DeRqnmdyVREwt2CFbPceM0zSNdEeVfiGaqYsKw==} engines: {node: '>=8.x'} peerDependencies: react: '>=16.9.0' @@ -4778,6 +4889,12 @@ packages: react: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-datepicker@8.4.0: + resolution: {integrity: sha512-6nPDnj8vektWCIOy9ArS3avus9Ndsyz5XgFCJ7nBxXASSpBdSL6lG9jzNNmViPOAOPh6T5oJyGaXuMirBLECag==} + peerDependencies: + react: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom@19.1.0: resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} peerDependencies: @@ -4801,8 +4918,8 @@ packages: peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 - react-hook-form@7.57.0: - resolution: {integrity: sha512-RbEks3+cbvTP84l/VXGUZ+JMrKOS8ykQCRYdm5aYsxnDquL0vspsyNhGRO7pcH6hsZqWlPOjLye7rJqdtdAmlg==} + react-hook-form@7.58.1: + resolution: {integrity: sha512-Lml/KZYEEFfPhUVgE0RdCVpnC4yhW+PndRhbiTtdvSlQTL8IfVR+iQkBjLIvmmc6+GGoVeM11z37ktKFPAb0FA==} engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 @@ -4823,8 +4940,8 @@ packages: typescript: optional: true - react-i18next@15.5.2: - resolution: {integrity: sha512-ePODyXgmZQAOYTbZXQn5rRsSBu3Gszo69jxW6aKmlSgxKAI1fOhDwSu6bT4EKHciWPKQ7v7lPrjeiadR6Gi+1A==} + react-i18next@15.5.3: + resolution: {integrity: sha512-ypYmOKOnjqPEJZO4m1BI0kS8kWqkBNsKYyhVUfij0gvjy9xJNoG/VcGkxq5dRlVwzmrmY1BQMAmpbbUBLwC4Kw==} peerDependencies: i18next: '>= 23.2.3' react: '>= 16.8.0' @@ -4858,8 +4975,8 @@ packages: react: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - react-resizable-panels@3.0.2: - resolution: {integrity: sha512-j4RNII75fnHkLnbsTb5G5YsDvJsSEZrJK2XSF2z0Tc2jIonYlIVir/Yh/5LvcUFCfs1HqrMAoiBFmIrRjC4XnA==} + react-resizable-panels@3.0.3: + resolution: {integrity: sha512-7HA8THVBHTzhDK4ON0tvlGXyMAJN1zBeRpuyyremSikgYh2ku6ltD7tsGQOcXx4NKPrZtYCm/5CBr+dkruTGQw==} peerDependencies: react: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc @@ -5196,17 +5313,20 @@ packages: tailwind-merge@3.3.0: resolution: {integrity: sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ==} + tailwind-merge@3.3.1: + resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} + tailwindcss-animate@1.0.7: resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} peerDependencies: tailwindcss: '>=3.0.0 || insiders' + tailwindcss@4.1.10: + resolution: {integrity: sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==} + tailwindcss@4.1.6: resolution: {integrity: sha512-j0cGLTreM6u4OWzBeLBpycK0WIh8w7kSwcUsQZoGLHZ7xDTdM69lN64AgoIEEwFi0tnhs4wSykUa5YWxAzgFYg==} - tailwindcss@4.1.8: - resolution: {integrity: sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==} - tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} @@ -5371,8 +5491,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - typescript-eslint@8.33.1: - resolution: {integrity: sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==} + typescript-eslint@8.34.1: + resolution: {integrity: sha512-XjS+b6Vg9oT1BaIUfkW3M3LvqZE++rbzAMEHuccCfO/YkP43ha6w3jTEMilQxMF92nVOYCcdjv1ZUhAa1D/0ow==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -5402,6 +5522,9 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -5746,8 +5869,16 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/compat-data@7.26.8': {} + '@babel/compat-data@7.27.5': {} + '@babel/core@7.26.10': dependencies: '@ampproject/remapping': 2.3.0 @@ -5768,6 +5899,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/core@7.27.4': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) + '@babel/helpers': 7.27.6 + '@babel/parser': 7.27.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 + convert-source-map: 2.0.0 + debug: 4.4.0 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/generator@7.26.10': dependencies: '@babel/parser': 7.26.10 @@ -5776,6 +5927,14 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 + '@babel/generator@7.27.5': + dependencies: + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + '@babel/helper-compilation-targets@7.26.5': dependencies: '@babel/compat-data': 7.26.8 @@ -5784,6 +5943,14 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.27.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + '@babel/helper-module-imports@7.25.9': dependencies: '@babel/traverse': 7.26.10 @@ -5791,6 +5958,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -5800,33 +5974,69 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.27.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.4 + transitivePeerDependencies: + - supports-color + '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-option@7.25.9': {} + '@babel/helper-validator-option@7.27.1': {} + '@babel/helpers@7.26.10': dependencies: '@babel/template': 7.26.9 '@babel/types': 7.26.10 + '@babel/helpers@7.27.6': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.6 + '@babel/parser@7.26.10': dependencies: '@babel/types': 7.26.10 + '@babel/parser@7.27.5': + dependencies: + '@babel/types': 7.27.6 + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.26.5 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.26.5 + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/runtime@7.26.0': dependencies: regenerator-runtime: 0.14.1 @@ -5837,12 +6047,20 @@ snapshots: '@babel/runtime@7.27.1': {} + '@babel/runtime@7.27.6': {} + '@babel/template@7.26.9': dependencies: '@babel/code-frame': 7.26.2 '@babel/parser': 7.26.10 '@babel/types': 7.26.10 + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 + '@babel/traverse@7.26.10': dependencies: '@babel/code-frame': 7.26.2 @@ -5855,11 +6073,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.27.4': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.5 + '@babel/parser': 7.27.5 + '@babel/template': 7.27.2 + '@babel/types': 7.27.6 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + '@babel/types@7.26.10': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@babel/types@7.27.6': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@codemirror/autocomplete@6.18.6': dependencies: '@codemirror/language': 6.11.0 @@ -6024,7 +6259,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0)': + '@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0)': dependencies: '@babel/runtime': 7.26.10 '@emotion/babel-plugin': 11.13.5 @@ -6036,7 +6271,7 @@ snapshots: hoist-non-react-statics: 3.3.2 react: 19.1.0 optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 transitivePeerDependencies: - supports-color @@ -6065,18 +6300,18 @@ snapshots: transitivePeerDependencies: - supports-color - '@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0)': + '@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)': dependencies: '@babel/runtime': 7.26.0 '@emotion/babel-plugin': 11.13.5 '@emotion/is-prop-valid': 1.3.1 - '@emotion/react': 11.14.0(@types/react@19.1.6)(react@19.1.0) + '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0) '@emotion/serialize': 1.3.3 '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.0) '@emotion/utils': 1.4.2 react: 19.1.0 optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 transitivePeerDependencies: - supports-color @@ -6177,9 +6412,9 @@ snapshots: eslint: 9.26.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.7.0(eslint@9.28.0(jiti@2.4.2))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@2.4.2))': dependencies: - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -6192,6 +6427,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/config-array@0.20.1': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + '@eslint/config-helpers@0.2.2': {} '@eslint/core@0.13.0': @@ -6218,7 +6461,7 @@ snapshots: '@eslint/js@9.26.0': {} - '@eslint/js@9.28.0': {} + '@eslint/js@9.29.0': {} '@eslint/object-schema@2.1.6': {} @@ -6338,7 +6581,7 @@ snapshots: dependencies: idb-keyval: 6.2.1 - '@kevisual/container@1.0.0(@emotion/css@11.13.4)(@types/react@19.1.6)(crypto-js@4.2.0)(eventemitter3@5.0.1)(immer@10.1.1)(react@19.1.0)(rollup@4.41.1)(typescript@5.8.3)': + '@kevisual/container@1.0.0(@emotion/css@11.13.4)(@types/react@19.1.8)(crypto-js@4.2.0)(eventemitter3@5.0.1)(immer@10.1.1)(react@19.1.0)(rollup@4.41.1)(typescript@5.8.3)': dependencies: '@emotion/css': 11.13.4 crypto-js: 4.2.0 @@ -6346,7 +6589,7 @@ snapshots: nanoid: 5.1.5 rollup-plugin-dts: 6.2.1(rollup@4.41.1)(typescript@5.8.3) scheduler: 0.23.2 - zustand: 4.5.6(@types/react@19.1.6)(immer@10.1.1)(react@19.1.0) + zustand: 4.5.6(@types/react@19.1.8)(immer@10.1.1)(react@19.1.0) transitivePeerDependencies: - '@types/react' - immer @@ -6354,14 +6597,16 @@ snapshots: - rollup - typescript + '@kevisual/context@0.0.3': {} + '@kevisual/load@0.0.6': dependencies: eventemitter3: 5.0.1 - '@kevisual/query-login@0.0.5(@kevisual/query@0.0.28(ws@8.18.1)(zod@3.24.4))(rollup@4.41.1)(typescript@5.8.3)': + '@kevisual/query-login@0.0.6(@kevisual/query@0.0.29(ws@8.18.1)(zod@3.24.4))(rollup@4.41.1)(typescript@5.8.3)': dependencies: '@kevisual/cache': 0.0.2(rollup@4.41.1)(tslib@2.8.1)(typescript@5.8.3) - '@kevisual/query': 0.0.28(ws@8.18.1)(zod@3.24.4) + '@kevisual/query': 0.0.29(ws@8.18.1)(zod@3.24.4) dotenv: 16.5.0 transitivePeerDependencies: - rollup @@ -6392,7 +6637,7 @@ snapshots: - ws - zod - '@kevisual/query@0.0.28(ws@8.18.1)(zod@3.24.4)': + '@kevisual/query@0.0.29(ws@8.18.1)(zod@3.24.4)': dependencies: openai: 5.1.1(ws@8.18.1)(zod@3.24.4) transitivePeerDependencies: @@ -6408,12 +6653,12 @@ snapshots: - bufferutil - utf-8-validate - '@kevisual/router@0.0.18': + '@kevisual/router@0.0.21': dependencies: path-to-regexp: 8.2.0 selfsigned: 2.4.1 - '@kevisual/router@0.0.21': + '@kevisual/router@0.0.22': dependencies: path-to-regexp: 8.2.0 selfsigned: 2.4.1 @@ -6434,6 +6679,8 @@ snapshots: eventemitter3: 5.0.1 path-to-regexp: 8.2.0 + '@kevisual/store@0.0.9': {} + '@kevisual/system-lib@0.0.22': {} '@kevisual/system-ui@0.0.3': @@ -6502,11 +6749,11 @@ snapshots: - '@types/node' optional: true - '@microsoft/api-extractor-model@7.30.5(@types/node@22.15.30)': + '@microsoft/api-extractor-model@7.30.5(@types/node@24.0.3)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.0(@types/node@22.15.30) + '@rushstack/node-core-library': 5.13.0(@types/node@24.0.3) transitivePeerDependencies: - '@types/node' optional: true @@ -6530,15 +6777,15 @@ snapshots: - '@types/node' optional: true - '@microsoft/api-extractor@7.52.2(@types/node@22.15.30)': + '@microsoft/api-extractor@7.52.2(@types/node@24.0.3)': dependencies: - '@microsoft/api-extractor-model': 7.30.5(@types/node@22.15.30) + '@microsoft/api-extractor-model': 7.30.5(@types/node@24.0.3) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.0(@types/node@22.15.30) + '@rushstack/node-core-library': 5.13.0(@types/node@24.0.3) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.2(@types/node@22.15.30) - '@rushstack/ts-command-line': 4.23.7(@types/node@22.15.30) + '@rushstack/terminal': 0.15.2(@types/node@24.0.3) + '@rushstack/ts-command-line': 4.23.7(@types/node@24.0.3) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.10 @@ -6613,15 +6860,15 @@ snapshots: '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.4)(react@19.1.0))(@types/react@19.1.4)(react@19.1.0) '@types/react': 19.1.4 - '@mui/material@7.1.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@mui/material@7.1.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 '@mui/core-downloads-tracker': 7.1.0 - '@mui/system': 7.1.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) - '@mui/types': 7.4.2(@types/react@19.1.6) - '@mui/utils': 7.1.0(@types/react@19.1.6)(react@19.1.0) + '@mui/system': 7.1.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) + '@mui/types': 7.4.2(@types/react@19.1.8) + '@mui/utils': 7.1.0(@types/react@19.1.8)(react@19.1.0) '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.12(@types/react@19.1.6) + '@types/react-transition-group': 4.4.12(@types/react@19.1.8) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 @@ -6630,19 +6877,19 @@ snapshots: react-is: 19.1.0 react-transition-group: 4.4.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.6)(react@19.1.0) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) - '@types/react': 19.1.6 + '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) + '@types/react': 19.1.8 - '@mui/material@7.1.1(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@mui/material@7.1.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 '@mui/core-downloads-tracker': 7.1.1 - '@mui/system': 7.1.1(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) - '@mui/types': 7.4.3(@types/react@19.1.6) - '@mui/utils': 7.1.1(@types/react@19.1.6)(react@19.1.0) + '@mui/system': 7.1.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) + '@mui/types': 7.4.3(@types/react@19.1.8) + '@mui/utils': 7.1.1(@types/react@19.1.8)(react@19.1.0) '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.12(@types/react@19.1.6) + '@types/react-transition-group': 4.4.12(@types/react@19.1.8) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 @@ -6651,9 +6898,9 @@ snapshots: react-is: 19.1.0 react-transition-group: 4.4.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.6)(react@19.1.0) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) - '@types/react': 19.1.6 + '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) + '@types/react': 19.1.8 '@mui/private-theming@7.1.0(@types/react@19.1.4)(react@19.1.0)': dependencies: @@ -6664,23 +6911,23 @@ snapshots: optionalDependencies: '@types/react': 19.1.4 - '@mui/private-theming@7.1.0(@types/react@19.1.6)(react@19.1.0)': + '@mui/private-theming@7.1.0(@types/react@19.1.8)(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 - '@mui/utils': 7.1.0(@types/react@19.1.6)(react@19.1.0) + '@mui/utils': 7.1.0(@types/react@19.1.8)(react@19.1.0) prop-types: 15.8.1 react: 19.1.0 optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 - '@mui/private-theming@7.1.1(@types/react@19.1.6)(react@19.1.0)': + '@mui/private-theming@7.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 - '@mui/utils': 7.1.1(@types/react@19.1.6)(react@19.1.0) + '@mui/utils': 7.1.1(@types/react@19.1.8)(react@19.1.0) prop-types: 15.8.1 react: 19.1.0 optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 '@mui/styled-engine@7.1.0(@emotion/react@11.14.0(@types/react@19.1.4)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.4)(react@19.1.0))(@types/react@19.1.4)(react@19.1.0))(react@19.1.0)': dependencies: @@ -6695,7 +6942,7 @@ snapshots: '@emotion/react': 11.14.0(@types/react@19.1.4)(react@19.1.0) '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.4)(react@19.1.0))(@types/react@19.1.4)(react@19.1.0) - '@mui/styled-engine@7.1.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(react@19.1.0)': + '@mui/styled-engine@7.1.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 '@emotion/cache': 11.14.0 @@ -6705,10 +6952,10 @@ snapshots: prop-types: 15.8.1 react: 19.1.0 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.6)(react@19.1.0) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) + '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) - '@mui/styled-engine@7.1.1(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(react@19.1.0)': + '@mui/styled-engine@7.1.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 '@emotion/cache': 11.14.0 @@ -6718,8 +6965,8 @@ snapshots: prop-types: 15.8.1 react: 19.1.0 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.6)(react@19.1.0) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) + '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) '@mui/system@7.1.0(@emotion/react@11.14.0(@types/react@19.1.4)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.4)(react@19.1.0))(@types/react@19.1.4)(react@19.1.0))(@types/react@19.1.4)(react@19.1.0)': dependencies: @@ -6737,37 +6984,37 @@ snapshots: '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.4)(react@19.1.0))(@types/react@19.1.4)(react@19.1.0) '@types/react': 19.1.4 - '@mui/system@7.1.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0)': + '@mui/system@7.1.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 - '@mui/private-theming': 7.1.0(@types/react@19.1.6)(react@19.1.0) - '@mui/styled-engine': 7.1.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(react@19.1.0) - '@mui/types': 7.4.2(@types/react@19.1.6) - '@mui/utils': 7.1.0(@types/react@19.1.6)(react@19.1.0) + '@mui/private-theming': 7.1.0(@types/react@19.1.8)(react@19.1.0) + '@mui/styled-engine': 7.1.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) + '@mui/types': 7.4.2(@types/react@19.1.8) + '@mui/utils': 7.1.0(@types/react@19.1.8)(react@19.1.0) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 react: 19.1.0 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.6)(react@19.1.0) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) - '@types/react': 19.1.6 + '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) + '@types/react': 19.1.8 - '@mui/system@7.1.1(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0)': + '@mui/system@7.1.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 - '@mui/private-theming': 7.1.1(@types/react@19.1.6)(react@19.1.0) - '@mui/styled-engine': 7.1.1(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(react@19.1.0) - '@mui/types': 7.4.3(@types/react@19.1.6) - '@mui/utils': 7.1.1(@types/react@19.1.6)(react@19.1.0) + '@mui/private-theming': 7.1.1(@types/react@19.1.8)(react@19.1.0) + '@mui/styled-engine': 7.1.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) + '@mui/types': 7.4.3(@types/react@19.1.8) + '@mui/utils': 7.1.1(@types/react@19.1.8)(react@19.1.0) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 react: 19.1.0 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.6)(react@19.1.0) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0) - '@types/react': 19.1.6 + '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0) + '@types/react': 19.1.8 '@mui/types@7.4.2(@types/react@19.1.4)': dependencies: @@ -6775,17 +7022,17 @@ snapshots: optionalDependencies: '@types/react': 19.1.4 - '@mui/types@7.4.2(@types/react@19.1.6)': + '@mui/types@7.4.2(@types/react@19.1.8)': dependencies: '@babel/runtime': 7.27.1 optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 - '@mui/types@7.4.3(@types/react@19.1.6)': + '@mui/types@7.4.3(@types/react@19.1.8)': dependencies: '@babel/runtime': 7.27.1 optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 '@mui/utils@7.1.0(@types/react@19.1.4)(react@19.1.0)': dependencies: @@ -6799,29 +7046,29 @@ snapshots: optionalDependencies: '@types/react': 19.1.4 - '@mui/utils@7.1.0(@types/react@19.1.6)(react@19.1.0)': + '@mui/utils@7.1.0(@types/react@19.1.8)(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 - '@mui/types': 7.4.2(@types/react@19.1.6) + '@mui/types': 7.4.2(@types/react@19.1.8) '@types/prop-types': 15.7.14 clsx: 2.1.1 prop-types: 15.8.1 react: 19.1.0 react-is: 19.1.0 optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 - '@mui/utils@7.1.1(@types/react@19.1.6)(react@19.1.0)': + '@mui/utils@7.1.1(@types/react@19.1.8)(react@19.1.0)': dependencies: '@babel/runtime': 7.27.1 - '@mui/types': 7.4.3(@types/react@19.1.6) + '@mui/types': 7.4.3(@types/react@19.1.8) '@types/prop-types': 15.7.14 clsx: 2.1.1 prop-types: 15.8.1 react: 19.1.0 react-is: 19.1.0 optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -6917,7 +7164,7 @@ snapshots: '@remirror/core-constants@3.0.0': {} - '@rolldown/pluginutils@1.0.0-beta.9': {} + '@rolldown/pluginutils@1.0.0-beta.11': {} '@rollup/plugin-commonjs@28.0.3(rollup@4.41.1)': dependencies: @@ -7157,7 +7404,7 @@ snapshots: '@types/node': 22.15.18 optional: true - '@rushstack/node-core-library@5.13.0(@types/node@22.15.30)': + '@rushstack/node-core-library@5.13.0(@types/node@24.0.3)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -7168,7 +7415,7 @@ snapshots: resolve: 1.22.10 semver: 7.5.4 optionalDependencies: - '@types/node': 22.15.30 + '@types/node': 24.0.3 optional: true '@rushstack/rig-package@0.5.3': @@ -7185,12 +7432,12 @@ snapshots: '@types/node': 22.15.18 optional: true - '@rushstack/terminal@0.15.2(@types/node@22.15.30)': + '@rushstack/terminal@0.15.2(@types/node@24.0.3)': dependencies: - '@rushstack/node-core-library': 5.13.0(@types/node@22.15.30) + '@rushstack/node-core-library': 5.13.0(@types/node@24.0.3) supports-color: 8.1.1 optionalDependencies: - '@types/node': 22.15.30 + '@types/node': 24.0.3 optional: true '@rushstack/ts-command-line@4.23.7(@types/node@22.15.18)': @@ -7203,9 +7450,9 @@ snapshots: - '@types/node' optional: true - '@rushstack/ts-command-line@4.23.7(@types/node@22.15.30)': + '@rushstack/ts-command-line@4.23.7(@types/node@24.0.3)': dependencies: - '@rushstack/terminal': 0.15.2(@types/node@22.15.30) + '@rushstack/terminal': 0.15.2(@types/node@24.0.3) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -7217,6 +7464,16 @@ snapshots: '@stackblitz/sdk@1.11.0': {} + '@tailwindcss/node@4.1.10': + dependencies: + '@ampproject/remapping': 2.3.0 + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + lightningcss: 1.30.1 + magic-string: 0.30.17 + source-map-js: 1.2.1 + tailwindcss: 4.1.10 + '@tailwindcss/node@4.1.6': dependencies: '@ampproject/remapping': 2.3.0 @@ -7227,87 +7484,95 @@ snapshots: source-map-js: 1.2.1 tailwindcss: 4.1.6 - '@tailwindcss/node@4.1.8': - dependencies: - '@ampproject/remapping': 2.3.0 - enhanced-resolve: 5.18.1 - jiti: 2.4.2 - lightningcss: 1.30.1 - magic-string: 0.30.17 - source-map-js: 1.2.1 - tailwindcss: 4.1.8 + '@tailwindcss/oxide-android-arm64@4.1.10': + optional: true '@tailwindcss/oxide-android-arm64@4.1.6': optional: true - '@tailwindcss/oxide-android-arm64@4.1.8': + '@tailwindcss/oxide-darwin-arm64@4.1.10': optional: true '@tailwindcss/oxide-darwin-arm64@4.1.6': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.8': + '@tailwindcss/oxide-darwin-x64@4.1.10': optional: true '@tailwindcss/oxide-darwin-x64@4.1.6': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.8': + '@tailwindcss/oxide-freebsd-x64@4.1.10': optional: true '@tailwindcss/oxide-freebsd-x64@4.1.6': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.8': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.10': optional: true '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.6': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8': + '@tailwindcss/oxide-linux-arm64-gnu@4.1.10': optional: true '@tailwindcss/oxide-linux-arm64-gnu@4.1.6': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.8': + '@tailwindcss/oxide-linux-arm64-musl@4.1.10': optional: true '@tailwindcss/oxide-linux-arm64-musl@4.1.6': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.8': + '@tailwindcss/oxide-linux-x64-gnu@4.1.10': optional: true '@tailwindcss/oxide-linux-x64-gnu@4.1.6': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.8': + '@tailwindcss/oxide-linux-x64-musl@4.1.10': optional: true '@tailwindcss/oxide-linux-x64-musl@4.1.6': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.8': + '@tailwindcss/oxide-wasm32-wasi@4.1.10': optional: true '@tailwindcss/oxide-wasm32-wasi@4.1.6': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.8': + '@tailwindcss/oxide-win32-arm64-msvc@4.1.10': optional: true '@tailwindcss/oxide-win32-arm64-msvc@4.1.6': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.8': + '@tailwindcss/oxide-win32-x64-msvc@4.1.10': optional: true '@tailwindcss/oxide-win32-x64-msvc@4.1.6': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.8': - optional: true + '@tailwindcss/oxide@4.1.10': + dependencies: + detect-libc: 2.0.4 + tar: 7.4.3 + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.10 + '@tailwindcss/oxide-darwin-arm64': 4.1.10 + '@tailwindcss/oxide-darwin-x64': 4.1.10 + '@tailwindcss/oxide-freebsd-x64': 4.1.10 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.10 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.10 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.10 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.10 + '@tailwindcss/oxide-linux-x64-musl': 4.1.10 + '@tailwindcss/oxide-wasm32-wasi': 4.1.10 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.10 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.10 '@tailwindcss/oxide@4.1.6': dependencies: @@ -7327,23 +7592,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.6 '@tailwindcss/oxide-win32-x64-msvc': 4.1.6 - '@tailwindcss/oxide@4.1.8': + '@tailwindcss/vite@4.1.10(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': dependencies: - detect-libc: 2.0.4 - tar: 7.4.3 - optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.8 - '@tailwindcss/oxide-darwin-arm64': 4.1.8 - '@tailwindcss/oxide-darwin-x64': 4.1.8 - '@tailwindcss/oxide-freebsd-x64': 4.1.8 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.8 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.8 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.8 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.8 - '@tailwindcss/oxide-linux-x64-musl': 4.1.8 - '@tailwindcss/oxide-wasm32-wasi': 4.1.8 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.8 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.8 + '@tailwindcss/node': 4.1.10 + '@tailwindcss/oxide': 4.1.10 + tailwindcss: 4.1.10 + vite: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) '@tailwindcss/vite@4.1.6(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': dependencies: @@ -7352,19 +7606,12 @@ snapshots: tailwindcss: 4.1.6 vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) - '@tailwindcss/vite@4.1.6(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': + '@tailwindcss/vite@4.1.6(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': dependencies: '@tailwindcss/node': 4.1.6 '@tailwindcss/oxide': 4.1.6 tailwindcss: 4.1.6 - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) - - '@tailwindcss/vite@4.1.8(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': - dependencies: - '@tailwindcss/node': 4.1.8 - '@tailwindcss/oxide': 4.1.8 - tailwindcss: 4.1.8 - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) + vite: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) '@tiptap/core@2.11.7(@tiptap/pm@2.11.7)': dependencies: @@ -7640,6 +7887,10 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@24.0.3': + dependencies: + undici-types: 7.8.0 + '@types/nprogress@0.2.3': {} '@types/parse-json@4.0.2': {} @@ -7658,27 +7909,27 @@ snapshots: dependencies: '@types/react': 19.1.4 - '@types/react-dom@19.1.6(@types/react@19.1.6)': + '@types/react-dom@19.1.6(@types/react@19.1.8)': dependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 '@types/react-resizable@3.0.8': dependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 '@types/react-transition-group@4.4.12(@types/react@19.1.4)': dependencies: '@types/react': 19.1.4 - '@types/react-transition-group@4.4.12(@types/react@19.1.6)': + '@types/react-transition-group@4.4.12(@types/react@19.1.8)': dependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 '@types/react@19.1.4': dependencies: csstype: 3.1.3 - '@types/react@19.1.6': + '@types/react@19.1.8': dependencies: csstype: 3.1.3 @@ -7707,15 +7958,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.34.1(@typescript-eslint/parser@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.33.1 - '@typescript-eslint/type-utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.33.1 - eslint: 9.28.0(jiti@2.4.2) + '@typescript-eslint/parser': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.34.1 + '@typescript-eslint/type-utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.34.1 + eslint: 9.29.0(jiti@2.4.2) graphemer: 1.4.0 ignore: 7.0.4 natural-compare: 1.4.0 @@ -7736,22 +7987,22 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/parser@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.33.1 - '@typescript-eslint/types': 8.33.1 - '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.33.1 + '@typescript-eslint/scope-manager': 8.34.1 + '@typescript-eslint/types': 8.34.1 + '@typescript-eslint/typescript-estree': 8.34.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.34.1 debug: 4.4.0 - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.33.1(typescript@5.8.3)': + '@typescript-eslint/project-service@8.34.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3) - '@typescript-eslint/types': 8.33.1 + '@typescript-eslint/tsconfig-utils': 8.34.1(typescript@5.8.3) + '@typescript-eslint/types': 8.34.1 debug: 4.4.0 typescript: 5.8.3 transitivePeerDependencies: @@ -7762,12 +8013,12 @@ snapshots: '@typescript-eslint/types': 8.32.1 '@typescript-eslint/visitor-keys': 8.32.1 - '@typescript-eslint/scope-manager@8.33.1': + '@typescript-eslint/scope-manager@8.34.1': dependencies: - '@typescript-eslint/types': 8.33.1 - '@typescript-eslint/visitor-keys': 8.33.1 + '@typescript-eslint/types': 8.34.1 + '@typescript-eslint/visitor-keys': 8.34.1 - '@typescript-eslint/tsconfig-utils@8.33.1(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.34.1(typescript@5.8.3)': dependencies: typescript: 5.8.3 @@ -7782,12 +8033,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.34.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) debug: 4.4.0 - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: @@ -7795,7 +8046,7 @@ snapshots: '@typescript-eslint/types@8.32.1': {} - '@typescript-eslint/types@8.33.1': {} + '@typescript-eslint/types@8.34.1': {} '@typescript-eslint/typescript-estree@8.32.1(typescript@5.8.3)': dependencies: @@ -7811,12 +8062,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.33.1(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.34.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/project-service': 8.33.1(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3) - '@typescript-eslint/types': 8.33.1 - '@typescript-eslint/visitor-keys': 8.33.1 + '@typescript-eslint/project-service': 8.34.1(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.34.1(typescript@5.8.3) + '@typescript-eslint/types': 8.34.1 + '@typescript-eslint/visitor-keys': 8.34.1 debug: 4.4.0 fast-glob: 3.3.3 is-glob: 4.0.3 @@ -7838,13 +8089,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.33.1 - '@typescript-eslint/types': 8.33.1 - '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) - eslint: 9.28.0(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.34.1 + '@typescript-eslint/types': 8.34.1 + '@typescript-eslint/typescript-estree': 8.34.1(typescript@5.8.3) + eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -7854,10 +8105,10 @@ snapshots: '@typescript-eslint/types': 8.32.1 eslint-visitor-keys: 4.2.0 - '@typescript-eslint/visitor-keys@8.33.1': + '@typescript-eslint/visitor-keys@8.34.1': dependencies: - '@typescript-eslint/types': 8.33.1 - eslint-visitor-keys: 4.2.0 + '@typescript-eslint/types': 8.34.1 + eslint-visitor-keys: 4.2.1 '@uiw/codemirror-theme-duotone@4.23.10(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.5)': dependencies: @@ -7881,9 +8132,9 @@ snapshots: '@codemirror/state': 6.5.2 '@codemirror/view': 6.36.5 - '@uiw/react-textarea-code-editor@3.1.1(@babel/runtime@7.27.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@uiw/react-textarea-code-editor@3.1.1(@babel/runtime@7.27.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@babel/runtime': 7.27.1 + '@babel/runtime': 7.27.6 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) rehype: 13.0.2 @@ -7895,9 +8146,9 @@ snapshots: dependencies: vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) - '@vitejs/plugin-basic-ssl@2.0.0(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': + '@vitejs/plugin-basic-ssl@2.0.0(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': dependencies: - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) + vite: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) '@vitejs/plugin-react@4.4.1(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': dependencies: @@ -7910,26 +8161,26 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.4.1(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': + '@vitejs/plugin-react@4.4.1(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': dependencies: '@babel/core': 7.26.10 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10) '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) + vite: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.5.1(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': + '@vitejs/plugin-react@4.5.2(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1))': dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10) - '@rolldown/pluginutils': 1.0.0-beta.9 + '@babel/core': 7.27.4 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.27.4) + '@rolldown/pluginutils': 1.0.0-beta.11 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) + vite: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) transitivePeerDependencies: - supports-color @@ -7969,12 +8220,18 @@ snapshots: dependencies: acorn: 8.14.1 + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-walk@8.3.4: dependencies: acorn: 8.14.1 acorn@8.14.1: {} + acorn@8.15.0: {} + agentkeepalive@4.6.0: dependencies: humanize-ms: 1.2.1 @@ -8022,7 +8279,7 @@ snapshots: ansi-styles@6.2.1: {} - antd@5.25.4(date-fns@4.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + antd@5.26.1(date-fns@4.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: '@ant-design/colors': 7.2.1 '@ant-design/cssinjs': 1.23.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -8063,7 +8320,7 @@ snapshots: rc-slider: 11.1.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0) rc-steps: 6.0.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) rc-switch: 4.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - rc-table: 7.50.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + rc-table: 7.51.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) rc-tabs: 15.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) rc-textarea: 1.10.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) rc-tooltip: 6.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -8483,27 +8740,34 @@ snapshots: dependencies: eslint: 9.26.0(jiti@2.4.2) - eslint-plugin-react-hooks@5.2.0(eslint@9.28.0(jiti@2.4.2)): + eslint-plugin-react-hooks@5.2.0(eslint@9.29.0(jiti@2.4.2)): dependencies: - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) eslint-plugin-react-refresh@0.4.20(eslint@9.26.0(jiti@2.4.2)): dependencies: eslint: 9.26.0(jiti@2.4.2) - eslint-plugin-react-refresh@0.4.20(eslint@9.28.0(jiti@2.4.2)): + eslint-plugin-react-refresh@0.4.20(eslint@9.29.0(jiti@2.4.2)): dependencies: - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) eslint-scope@8.3.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-visitor-keys@3.4.3: {} eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.2.1: {} + eslint@9.26.0(jiti@2.4.2): dependencies: '@eslint-community/eslint-utils': 4.5.1(eslint@9.26.0(jiti@2.4.2)) @@ -8548,15 +8812,15 @@ snapshots: transitivePeerDependencies: - supports-color - eslint@9.28.0(jiti@2.4.2): + eslint@9.29.0(jiti@2.4.2): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.20.0 + '@eslint/config-array': 0.20.1 '@eslint/config-helpers': 0.2.2 '@eslint/core': 0.14.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.28.0 + '@eslint/js': 9.29.0 '@eslint/plugin-kit': 0.3.1 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 @@ -8568,9 +8832,9 @@ snapshots: cross-spawn: 7.0.6 debug: 4.4.0 escape-string-regexp: 4.0.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -8596,6 +8860,12 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 4.2.0 + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -9207,11 +9477,7 @@ snapshots: dependencies: react: 19.1.0 - lucide-react@0.510.0(react@19.1.0): - dependencies: - react: 19.1.0 - - lucide-react@0.513.0(react@19.1.0): + lucide-react@0.516.0(react@19.1.0): dependencies: react: 19.1.0 @@ -9472,7 +9738,7 @@ snapshots: pngjs@5.0.0: {} - postcss-import@16.1.0(postcss@8.5.3): + postcss-import@16.1.1(postcss@8.5.3): dependencies: postcss: 8.5.3 postcss-value-parser: 4.2.0 @@ -9884,7 +10150,7 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - rc-table@7.50.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + rc-table@7.51.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: '@babel/runtime': 7.27.1 '@rc-component/context': 1.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -9983,6 +10249,14 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) + react-datepicker@8.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@floating-ui/react': 0.27.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + clsx: 2.1.1 + date-fns: 4.1.0 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-dom@19.1.0(react@19.1.0): dependencies: react: 19.1.0 @@ -10006,7 +10280,7 @@ snapshots: dependencies: react: 19.1.0 - react-hook-form@7.57.0(react@19.1.0): + react-hook-form@7.58.1(react@19.1.0): dependencies: react: 19.1.0 @@ -10020,9 +10294,9 @@ snapshots: react-dom: 19.1.0(react@19.1.0) typescript: 5.8.3 - react-i18next@15.5.2(i18next@25.2.1(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3): + react-i18next@15.5.3(i18next@25.2.1(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3): dependencies: - '@babel/runtime': 7.27.1 + '@babel/runtime': 7.27.6 html-parse-stringify: 3.0.1 i18next: 25.2.1(typescript@5.8.3) react: 19.1.0 @@ -10043,7 +10317,7 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - react-resizable-panels@3.0.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + react-resizable-panels@3.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) @@ -10476,18 +10750,20 @@ snapshots: tailwind-merge@3.3.0: {} + tailwind-merge@3.3.1: {} + + tailwindcss-animate@1.0.7(tailwindcss@4.1.10): + dependencies: + tailwindcss: 4.1.10 + tailwindcss-animate@1.0.7(tailwindcss@4.1.6): dependencies: tailwindcss: 4.1.6 - tailwindcss-animate@1.0.7(tailwindcss@4.1.8): - dependencies: - tailwindcss: 4.1.8 + tailwindcss@4.1.10: {} tailwindcss@4.1.6: {} - tailwindcss@4.1.8: {} - tapable@2.2.1: {} tar@7.4.3: @@ -10562,14 +10838,14 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@22.15.30)(typescript@5.8.3): + ts-node@10.9.2(@types/node@24.0.3)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.15.30 + '@types/node': 24.0.3 acorn: 8.14.1 acorn-walk: 8.3.4 arg: 4.1.3 @@ -10610,7 +10886,7 @@ snapshots: - tsx - yaml - tsup@8.4.0(@microsoft/api-extractor@7.52.2(@types/node@22.15.30))(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.3)(yaml@2.5.1): + tsup@8.4.0(@microsoft/api-extractor@7.52.2(@types/node@24.0.3))(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.3)(yaml@2.5.1): dependencies: bundle-require: 5.1.0(esbuild@0.25.1) cac: 6.7.14 @@ -10629,7 +10905,7 @@ snapshots: tinyglobby: 0.2.12 tree-kill: 1.2.2 optionalDependencies: - '@microsoft/api-extractor': 7.52.2(@types/node@22.15.30) + '@microsoft/api-extractor': 7.52.2(@types/node@24.0.3) postcss: 8.5.3 typescript: 5.8.3 transitivePeerDependencies: @@ -10689,12 +10965,12 @@ snapshots: transitivePeerDependencies: - supports-color - typescript-eslint@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3): + typescript-eslint@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.28.0(jiti@2.4.2) + '@typescript-eslint/eslint-plugin': 8.34.1(@typescript-eslint/parser@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -10714,6 +10990,8 @@ snapshots: undici-types@6.21.0: {} + undici-types@7.8.0: {} + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -10791,10 +11069,10 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-plugin-tsconfig-paths@1.4.1(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)): + vite-plugin-tsconfig-paths@1.4.1(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1)): dependencies: typescript-paths: 1.5.1(typescript@5.8.3) - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) + vite: 6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1) transitivePeerDependencies: - typescript @@ -10814,7 +11092,7 @@ snapshots: terser: 5.39.0 yaml: 2.5.1 - vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1): + vite@6.3.5(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(yaml@2.5.1): dependencies: esbuild: 0.25.1 fdir: 6.4.4(picomatch@4.0.2) @@ -10823,7 +11101,7 @@ snapshots: rollup: 4.37.0 tinyglobby: 0.2.13 optionalDependencies: - '@types/node': 22.15.30 + '@types/node': 24.0.3 fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.30.1 @@ -10938,11 +11216,11 @@ snapshots: immer: 10.1.1 react: 19.1.0 - zustand@4.5.6(@types/react@19.1.6)(immer@10.1.1)(react@19.1.0): + zustand@4.5.6(@types/react@19.1.8)(immer@10.1.1)(react@19.1.0): dependencies: use-sync-external-store: 1.4.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 immer: 10.1.1 react: 19.1.0 @@ -10953,9 +11231,9 @@ snapshots: react: 19.1.0 use-sync-external-store: 1.4.0(react@19.1.0) - zustand@5.0.5(@types/react@19.1.6)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)): + zustand@5.0.5(@types/react@19.1.8)(immer@10.1.1)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)): optionalDependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 immer: 10.1.1 react: 19.1.0 use-sync-external-store: 1.4.0(react@19.1.0) diff --git a/src/modules/query.ts b/src/modules/query.ts index cf33478..1953cf7 100644 --- a/src/modules/query.ts +++ b/src/modules/query.ts @@ -1,5 +1,5 @@ import { QueryClient } from '@kevisual/query'; -import { QueryLoginBrowser } from '@kevisual/query-login'; +import { QueryLoginBrowser } from '@/query/query-login/query-login-browser'; import { toastLogin } from '@kevisual/resources/pages/message/ToastLogin.tsx'; import { toast } from 'react-toastify'; export const query = new QueryClient({ @@ -22,7 +22,7 @@ query.afterResponse = async (res, ctx) => { toast.success('刷新登陆信息'); setTimeout(() => { window.location.reload(); - }, 1000); + }, 2000); } }, }); diff --git a/src/query/index.ts b/src/query/index.ts new file mode 100644 index 0000000..cff06fa --- /dev/null +++ b/src/query/index.ts @@ -0,0 +1,7 @@ +import { Query } from '@kevisual/query'; + +export const query = new Query(); + +export const clientQuery = new Query({ url: '/client/router' }); + +export { QueryUtil } from '@kevisual/router/define'; diff --git a/src/query/kevisual.json b/src/query/kevisual.json new file mode 100644 index 0000000..ca52328 --- /dev/null +++ b/src/query/kevisual.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://kevisual.xiongxiao.me/root/ai/kevisual/tools/kevisual-sync/schema.json?v=2", + "metadata": { + "share": "public" + }, + "checkDir": { + "src/query": { + "url": "https://kevisual.xiongxiao.me/root/ai/code/registry/query", + "enabled": true + } + }, + "syncDirectory": [ + { + "files": [ + "src/query/**/*" + ], + "ignore": [], + "registry": "https://kevisual.xiongxiao.me/root/ai/code/registry", + "replace": { + "src/": "" + } + } + ], + "sync": {} +} \ No newline at end of file diff --git a/src/query/query-ai/defines/ai.ts b/src/query/query-ai/defines/ai.ts new file mode 100644 index 0000000..d8ca83b --- /dev/null +++ b/src/query/query-ai/defines/ai.ts @@ -0,0 +1,42 @@ +import { QueryUtil } from '@/query/index.ts'; + +type Message = { + role?: 'user' | 'assistant' | 'system' | 'tool'; + content?: string; + name?: string; +}; +export type PostChat = { + messages?: Message[]; + model?: string; + group?: string; + user?: string; +}; + +export type ChatDataOpts = { + id?: string; + title?: string; + messages?: any[]; + data?: any; + type?: 'temp' | 'keep' | string; +}; +export type ChatOpts = { + username: string; + model: string; + /** + * 获取完整消息回复 + */ + getFull?: boolean; + group: string; + /** + * openai的参数 + */ + options?: any; +}; + +export const appDefine = QueryUtil.create({ + chat: { + path: 'ai', + key: 'chat', + description: '与 AI 进行对话, 调用 GPT 的AI 服务,生成结果,并返回。', + }, +}); diff --git a/src/query/query-ai/query-ai.ts b/src/query/query-ai/query-ai.ts new file mode 100644 index 0000000..2ede31c --- /dev/null +++ b/src/query/query-ai/query-ai.ts @@ -0,0 +1,101 @@ +import { appDefine } from './defines/ai.ts'; +import { PostChat, ChatOpts, ChatDataOpts } from './defines/ai.ts'; + +import { BaseQuery, DataOpts, Query } from '@kevisual/query/query'; + +export { appDefine }; + +export class QueryApp extends BaseQuery { + constructor(opts?: { query: T }) { + super({ + ...opts, + query: opts?.query!, + queryDefine: appDefine, + }); + } + /** + * 与 AI 进行对话, 调用 GPT 的AI 服务,生成结果,并返回。 + * @param data + * @param opts + * @returns + */ + postChat(data: PostChat, opts?: DataOpts) { + return this.chain('chat').post(data, opts); + } + /** + * 获取模型列表 + * @param opts + * @returns + */ + getModelList(data?: { usernames?: string[] }, opts?: DataOpts) { + return this.query.post( + { + path: 'ai', + key: 'get-model-list', + data, + }, + opts, + ); + } + /** + * 聊天对话模型 + * @param data + * @param chatOpts + * @param opts + * @returns + */ + chat(data: ChatDataOpts, chatOpts: ChatOpts, opts?: DataOpts) { + const { username, model, group, getFull = true } = chatOpts; + if (!username || !model || !group) { + throw new Error('username, model, group is required'); + } + return this.query.post( + { + path: 'ai', + key: 'chat', + ...chatOpts, + getFull, + data, + }, + opts, + ); + } + clearConfigCache(opts?: DataOpts) { + return this.query.post( + { + path: 'ai', + key: 'clear-cache', + }, + opts, + ); + } + /** + * 获取聊天使用情况 + * @param opts + * @returns + */ + getChatUsage(opts?: DataOpts) { + return this.query.post( + { + path: 'ai', + key: 'get-chat-usage', + }, + opts, + ); + } + + /** + * 清除当前用户模型自己的统计 + * @param opts + * @returns + */ + clearSelfUsage(opts?: DataOpts) { + return this.query.post( + { + path: 'ai', + key: 'clear-chat-limit', + }, + opts, + ); + } +} diff --git a/src/query/query-app/defines/index.ts b/src/query/query-app/defines/index.ts new file mode 100644 index 0000000..2a74834 --- /dev/null +++ b/src/query/query-app/defines/index.ts @@ -0,0 +1,3 @@ +import { appDefine } from './user-app-list'; +import { userAppDefine } from './user-app'; +export { appDefine, userAppDefine }; diff --git a/src/query/query-app/defines/user-app-list.ts b/src/query/query-app/defines/user-app-list.ts new file mode 100644 index 0000000..b887e87 --- /dev/null +++ b/src/query/query-app/defines/user-app-list.ts @@ -0,0 +1,62 @@ +import { QueryUtil } from '@/query/index.ts'; + +export const appDefine = QueryUtil.create({ + getApp: { + path: 'app', + key: 'get', + description: '获取应用信息', + }, + + updateApp: { + path: 'app', + key: 'update', + description: '更新应用信息', + }, + + deleteApp: { + path: 'app', + key: 'delete', + description: '删除应用信息', + }, + + listApps: { + path: 'app', + key: 'list', + description: '列出所有应用信息', + }, + + canUploadFiles: { + path: 'app', + key: 'canUploadFiles', + description: '检查是否可以上传文件', + }, + + uploadFiles: { + path: 'app', + key: 'uploadFiles', + description: '上传文件', + }, + + publishApp: { + path: 'app', + key: 'publish', + description: '发布应用', + }, + + getMinioList: { + path: 'app', + key: 'get-minio-list', + description: '获取 MinIO 文件列表', + }, + + detectVersionList: { + path: 'app', + key: 'detectVersionList', + description: '检测版本列表并同步 MinIO 数据', + }, + publicList: { + path: 'app', + key: 'public-list', + description: '获取公开应用列表', + }, +}); diff --git a/src/query/query-app/defines/user-app.ts b/src/query/query-app/defines/user-app.ts new file mode 100644 index 0000000..9b517f5 --- /dev/null +++ b/src/query/query-app/defines/user-app.ts @@ -0,0 +1,33 @@ +import { QueryUtil } from '@/query/index.ts'; + +export const userAppDefine = QueryUtil.create({ + listUserApps: { + path: 'user-app', + key: 'list', + description: '列出当前用户的所有应用(不包含 data 字段)', + }, + + getUserApp: { + path: 'user-app', + key: 'get', + description: '获取用户应用信息,可以指定 id 或 key', + }, + + updateUserApp: { + path: 'user-app', + key: 'update', + description: '更新或创建用户应用', + }, + + deleteUserApp: { + path: 'user-app', + key: 'delete', + description: '删除用户应用及关联数据', + }, + + testUserApp: { + path: 'user-app', + key: 'test', + description: '对 user-app 的数据进行测试,获取版本信息', + }, +}); diff --git a/src/query/query-app/query-app-define.ts b/src/query/query-app/query-app-define.ts new file mode 100644 index 0000000..23e8118 --- /dev/null +++ b/src/query/query-app/query-app-define.ts @@ -0,0 +1 @@ +export * from './defines/index.ts'; diff --git a/src/query/query-app/query-app.ts b/src/query/query-app/query-app.ts new file mode 100644 index 0000000..6f882f7 --- /dev/null +++ b/src/query/query-app/query-app.ts @@ -0,0 +1,18 @@ +import { appDefine, userAppDefine } from './defines/index.ts'; + +import { BaseQuery, DataOpts, Query } from '@kevisual/query/query'; + +export { appDefine, userAppDefine }; + +export class QueryApp extends BaseQuery { + appDefine = appDefine; + userAppDefine = userAppDefine; + constructor(opts?: { query: Query }) { + super(opts!); + this.appDefine.query = this.query; + this.userAppDefine.query = this.query; + } + getList(data: any, opts?: DataOpts) { + return this.appDefine.queryChain('listApps').post(data, opts); + } +} diff --git a/src/query/query-login/login-cache.ts b/src/query/query-login/login-cache.ts new file mode 100644 index 0000000..7facec1 --- /dev/null +++ b/src/query/query-login/login-cache.ts @@ -0,0 +1,204 @@ +export interface Cache { + /** + * @update 获取缓存 + */ + get(key: string): Promise; + /** + * @update 设置缓存 + */ + set(key: string, value: any): Promise; + /** + * @update 删除缓存 + */ + del(): Promise; + /** + * 初始化 + */ + init?: () => Promise; +} +export type User = { + avatar?: string; + description?: string; + id?: string; + needChangePassword?: boolean; + orgs?: string[]; + type?: string; + username?: string; +}; + +export type CacheLoginUser = { + user?: User; + id?: string; + accessToken?: string; + refreshToken?: string; +}; +type CacheLogin = { + loginUsers: CacheLoginUser[]; +} & CacheLoginUser; + +export type CacheStore = { + name: string; + /** + * 缓存数据 + * @important 需要先调用init + */ + cacheData: CacheLogin; + /** + * 实际操作的cache, 需要先调用init + */ + cache: T; + + /** + * 设置当前用户 + */ + setLoginUser(user: CacheLoginUser): Promise; + /** + * 获取当前用户 + */ + getCurrentUser(): Promise; + /** + * 获取当前用户列表 + */ + getCurrentUserList(): Promise; + /** + * 获取缓存的refreshToken + */ + getRefreshToken(): Promise; + /** + * 获取缓存的accessToken + */ + getAccessToken(): Promise; + /** + * 清除当前用户 + */ + clearCurrentUser(): Promise; + /** + * 清除所有用户 + */ + clearAll(): Promise; + + getValue(): Promise; + setValue(value: CacheLogin): Promise; + delValue(): Promise; + init(): Promise; +}; + +export type LoginCacheStoreOpts = { + name: string; + cache: Cache; +}; +export class LoginCacheStore implements CacheStore { + cache: Cache; + name: string; + cacheData: CacheLogin; + constructor(opts: LoginCacheStoreOpts) { + if (!opts.cache) { + throw new Error('cache is required'); + } + // @ts-ignore + this.cache = opts.cache; + this.cacheData = { + loginUsers: [], + user: undefined, + id: undefined, + accessToken: undefined, + refreshToken: undefined, + }; + this.name = opts.name; + } + /** + * 设置缓存 + * @param key + * @param value + * @returns + */ + async setValue(value: CacheLogin) { + await this.cache.set(this.name, value); + this.cacheData = value; + return value; + } + /** + * 删除缓存 + */ + async delValue() { + await this.cache.del(); + } + getValue(): Promise { + return this.cache.get(this.name); + } + /** + * 初始化,设置默认值 + */ + async init() { + const defaultData = { + loginUsers: [], + user: null, + id: null, + accessToken: null, + refreshToken: null, + }; + if (this.cache.init) { + try { + const cacheData = await this.cache.init(); + this.cacheData = cacheData || defaultData; + } catch (error) { + console.log('cacheInit error', error); + } + } else { + this.cacheData = (await this.getValue()) || defaultData; + } + } + /** + * 设置当前用户 + * @param user + */ + async setLoginUser(user: CacheLoginUser) { + const has = this.cacheData.loginUsers.find((u) => u.id === user.id); + if (has) { + this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id); + } + this.cacheData.loginUsers.push(user); + this.cacheData.user = user.user; + this.cacheData.id = user.id; + this.cacheData.accessToken = user.accessToken; + this.cacheData.refreshToken = user.refreshToken; + await this.setValue(this.cacheData); + } + + getCurrentUser(): Promise { + const cacheData = this.cacheData; + return Promise.resolve(cacheData.user!); + } + getCurrentUserList(): Promise { + return Promise.resolve(this.cacheData.loginUsers.filter((u) => u?.id)); + } + getRefreshToken(): Promise { + const cacheData = this.cacheData; + return Promise.resolve(cacheData.refreshToken || ''); + } + getAccessToken(): Promise { + const cacheData = this.cacheData; + return Promise.resolve(cacheData.accessToken || ''); + } + + async clearCurrentUser() { + const user = await this.getCurrentUser(); + const has = this.cacheData.loginUsers.find((u) => u.id === user.id); + if (has) { + this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id); + } + this.cacheData.user = undefined; + this.cacheData.id = undefined; + this.cacheData.accessToken = undefined; + this.cacheData.refreshToken = undefined; + await this.setValue(this.cacheData); + } + async clearAll() { + this.cacheData.loginUsers = []; + this.cacheData.user = undefined; + this.cacheData.id = undefined; + this.cacheData.accessToken = undefined; + this.cacheData.refreshToken = undefined; + await this.setValue(this.cacheData); + } +} diff --git a/src/query/query-login/login-node-cache.ts b/src/query/query-login/login-node-cache.ts new file mode 100644 index 0000000..a0e2b26 --- /dev/null +++ b/src/query/query-login/login-node-cache.ts @@ -0,0 +1,132 @@ +import { Cache } from './login-cache.ts'; +import { homedir } from 'node:os'; +import { join, dirname } from 'node:path'; +import fs from 'node:fs'; +import { readFileSync, writeFileSync, accessSync } from 'node:fs'; +import { readFile, writeFile, unlink, mkdir } from 'node:fs/promises'; +export const fileExists = async ( + filePath: string, + { createIfNotExists = true, isFile = true, isDir = false }: { createIfNotExists?: boolean; isFile?: boolean; isDir?: boolean } = {}, +) => { + try { + accessSync(filePath, fs.constants.F_OK); + return true; + } catch (error) { + if (createIfNotExists && isDir) { + await mkdir(filePath, { recursive: true }); + return true; + } else if (createIfNotExists && isFile) { + await mkdir(dirname(filePath), { recursive: true }); + return false; + } + return false; + } +}; +export const readConfigFile = (filePath: string) => { + try { + const data = readFileSync(filePath, 'utf-8'); + const jsonData = JSON.parse(data); + return jsonData; + } catch (error) { + return {}; + } +}; +export const writeConfigFile = (filePath: string, data: any) => { + writeFileSync(filePath, JSON.stringify(data, null, 2)); +}; +export const getHostName = () => { + const configDir = join(homedir(), '.config', 'envision'); + const configFile = join(configDir, 'config.json'); + const config = readConfigFile(configFile); + const baseURL = config.baseURL || 'https://kevisual.cn'; + const hostname = new URL(baseURL).hostname; + return hostname; +}; +export class StorageNode implements Storage { + cacheData: any; + filePath: string; + constructor() { + this.cacheData = {}; + const configDir = join(homedir(), '.config', 'envision'); + const hostname = getHostName(); + this.filePath = join(configDir, 'config', `${hostname}-storage.json`); + fileExists(this.filePath, { isFile: true }); + } + async loadCache() { + const filePath = this.filePath; + try { + const data = await readConfigFile(filePath); + this.cacheData = data; + } catch (error) { + this.cacheData = {}; + await writeFile(filePath, JSON.stringify(this.cacheData, null, 2)); + } + } + get length() { + return Object.keys(this.cacheData).length; + } + getItem(key: string) { + return this.cacheData[key]; + } + setItem(key: string, value: any) { + this.cacheData[key] = value; + writeFile(this.filePath, JSON.stringify(this.cacheData, null, 2)); + } + removeItem(key: string) { + delete this.cacheData[key]; + writeFile(this.filePath, JSON.stringify(this.cacheData, null, 2)); + } + clear() { + this.cacheData = {}; + writeFile(this.filePath, JSON.stringify(this.cacheData, null, 2)); + } + key(index: number) { + return Object.keys(this.cacheData)[index]; + } +} +export class LoginNodeCache implements Cache { + filepath: string; + + constructor(filepath?: string) { + this.filepath = filepath || join(homedir(), '.config', 'envision', 'config', `${getHostName()}-login.json`); + fileExists(this.filepath, { isFile: true }); + } + async get(_key: string) { + try { + const filePath = this.filepath; + const data = readConfigFile(filePath); + return data; + } catch (error) { + console.log('get error', error); + return {}; + } + } + async set(_key: string, value: any) { + try { + const data = readConfigFile(this.filepath); + const newData = { ...data, ...value }; + writeConfigFile(this.filepath, newData); + } catch (error) { + console.log('set error', error); + } + } + async del() { + await unlink(this.filepath); + } + async loadCache(filePath: string) { + try { + const data = await readFile(filePath, 'utf-8'); + const jsonData = JSON.parse(data); + return jsonData; + } catch (error) { + // console.log('loadCache error', error); + console.log('create new cache file:', filePath); + const defaultData = { loginUsers: [] }; + writeConfigFile(filePath, defaultData); + return defaultData; + } + } + async init() { + return await this.loadCache(this.filepath); + } +} diff --git a/src/query/query-login/query-login-browser.ts b/src/query/query-login/query-login-browser.ts new file mode 100644 index 0000000..2d131cb --- /dev/null +++ b/src/query/query-login/query-login-browser.ts @@ -0,0 +1,12 @@ +import { QueryLogin, QueryLoginOpts } from './query-login.ts'; +import { MyCache } from '@kevisual/cache'; +type QueryLoginNodeOptsWithoutCache = Omit; + +export class QueryLoginBrowser extends QueryLogin { + constructor(opts: QueryLoginNodeOptsWithoutCache) { + super({ + ...opts, + cache: new MyCache('login'), + }); + } +} diff --git a/src/query/query-login/query-login-node.ts b/src/query/query-login/query-login-node.ts new file mode 100644 index 0000000..5cb6527 --- /dev/null +++ b/src/query/query-login/query-login-node.ts @@ -0,0 +1,14 @@ +import { QueryLogin, QueryLoginOpts } from './query-login.ts'; +import { LoginNodeCache, StorageNode } from './login-node-cache.ts'; +type QueryLoginNodeOptsWithoutCache = Omit; +export const storage = new StorageNode(); +await storage.loadCache(); +export class QueryLoginNode extends QueryLogin { + constructor(opts: QueryLoginNodeOptsWithoutCache) { + super({ + ...opts, + storage, + cache: new LoginNodeCache(), + }); + } +} diff --git a/src/query/query-login/query-login.ts b/src/query/query-login/query-login.ts new file mode 100644 index 0000000..ca3b762 --- /dev/null +++ b/src/query/query-login/query-login.ts @@ -0,0 +1,468 @@ +import { Query, BaseQuery } from '@kevisual/query'; +import type { Result, DataOpts } from '@kevisual/query/query'; +import { setBaseResponse } from '@kevisual/query/query'; +import { LoginCacheStore, CacheStore, User } from './login-cache.ts'; +import { Cache } from './login-cache.ts'; + +export type QueryLoginOpts = { + query?: Query; + isBrowser?: boolean; + onLoad?: () => void; + storage?: Storage; + cache: Cache; +}; +export type QueryLoginData = { + username?: string; + password: string; + email?: string; +}; +export type QueryLoginResult = { + accessToken: string; + refreshToken: string; +}; + +export class QueryLogin extends BaseQuery { + /** + * query login cache, 非实际操作, 一个cache的包裹模块 + */ + cacheStore: CacheStore; + isBrowser: boolean; + load?: boolean; + storage: Storage; + onLoad?: () => void; + + constructor(opts?: QueryLoginOpts) { + super({ + query: opts?.query || new Query(), + }); + this.cacheStore = new LoginCacheStore({ name: 'login', cache: opts?.cache! }); + this.isBrowser = opts?.isBrowser ?? true; + this.init(); + this.onLoad = opts?.onLoad; + this.storage = opts?.storage || localStorage; + } + setQuery(query: Query) { + this.query = query; + } + private async init() { + await this.cacheStore.init(); + this.load = true; + this.onLoad?.(); + } + async post(data: any, opts?: DataOpts) { + try { + return this.query.post({ path: 'user', ...data }, opts); + } catch (error) { + console.log('error', error); + return { + code: 400, + } as any; + } + } + /** + * 登录, + * @param data + * @returns + */ + async login(data: QueryLoginData) { + const res = await this.post({ key: 'login', ...data }); + if (res.code === 200) { + const { accessToken, refreshToken } = res?.data || {}; + this.storage.setItem('token', accessToken || ''); + await this.beforeSetLoginUser({ accessToken, refreshToken }); + } + return res; + } + /** + * 手机号登录 + * @param data + * @returns + */ + async loginByCode(data: { phone: string; code: string }) { + const res = await this.post({ path: 'sms', key: 'login', data }); + if (res.code === 200) { + const { accessToken, refreshToken } = res?.data || {}; + this.storage.setItem('token', accessToken || ''); + await this.beforeSetLoginUser({ accessToken, refreshToken }); + } + return res; + } + /** + * 设置token + * @param token + */ + async setLoginToken(token: { accessToken: string; refreshToken: string }) { + const { accessToken, refreshToken } = token; + this.storage.setItem('token', accessToken || ''); + await this.beforeSetLoginUser({ accessToken, refreshToken }); + } + async loginByWechat(data: { code: string }) { + const res = await this.post({ path: 'wx', key: 'open-login', code: data.code }); + if (res.code === 200) { + const { accessToken, refreshToken } = res?.data || {}; + this.storage.setItem('token', accessToken || ''); + await this.beforeSetLoginUser({ accessToken, refreshToken }); + } + return res; + } + /** + * 检测微信登录,登陆成功后,调用onSuccess,否则调用onError + * @param param0 + */ + async checkWechat({ onSuccess, onError }: { onSuccess?: (res: QueryLoginResult) => void; onError?: (res: any) => void }) { + const url = new URL(window.location.href); + const code = url.searchParams.get('code'); + const state = url.searchParams.get('state'); + if (code && state) { + const res = await this.loginByWechat({ code }); + if (res.code === 200) { + onSuccess?.(res.data); + } else { + onError?.(res); + } + } + } + /** + * 登陆成功,需要获取用户信息进行缓存 + * @param param0 + */ + async beforeSetLoginUser({ accessToken, refreshToken, check401 }: { accessToken?: string; refreshToken?: string; check401?: boolean }) { + if (accessToken && refreshToken) { + const resUser = await this.getMe(accessToken, check401); + if (resUser.code === 200) { + const user = resUser.data; + if (user) { + this.cacheStore.setLoginUser({ + user, + id: user.id, + accessToken, + refreshToken, + }); + } else { + console.error('登录失败'); + } + } + } + } + /** + * 刷新token + * @param refreshToken + * @returns + */ + async queryRefreshToken(refreshToken?: string) { + const _refreshToken = refreshToken || this.cacheStore.getRefreshToken(); + let data = { refreshToken: _refreshToken }; + if (!_refreshToken) { + await this.cacheStore.clearCurrentUser(); + return { + code: 401, + message: '请先登录', + data: {} as any, + }; + } + return this.post( + { key: 'refreshToken', data }, + { + noStop: true, + beforeRequest: async (config) => { + return config; + }, + afterResponse: async (response, ctx) => { + setBaseResponse(response); + return response as any; + }, + }, + ); + } + /** + * 检查401错误,并刷新token, 如果refreshToken存在,则刷新token, 否则返回401 + * 拦截请求,请使用run401Action, 不要直接使用 afterCheck401ToRefreshToken + * @param response + * @param ctx + * @param refetch + * @returns + */ + async afterCheck401ToRefreshToken(response: Result, ctx?: { req?: any; res?: any; fetch?: any }, refetch?: boolean) { + const that = this; + if (response?.code === 401) { + const hasRefreshToken = await that.cacheStore.getRefreshToken(); + if (hasRefreshToken) { + const res = await that.queryRefreshToken(hasRefreshToken); + if (res.code === 200) { + const { accessToken, refreshToken } = res?.data || {}; + that.storage.setItem('token', accessToken || ''); + await that.beforeSetLoginUser({ accessToken, refreshToken, check401: false }); + if (refetch && ctx && ctx.req && ctx.req.url && ctx.fetch) { + await new Promise((resolve) => setTimeout(resolve, 1500)); + const url = ctx.req?.url; + const body = ctx.req?.body; + const headers = ctx.req?.headers; + const res = await ctx.fetch(url, { + method: 'POST', + body: body, + headers: { ...headers, Authorization: `Bearer ${accessToken}` }, + }); + setBaseResponse(res); + return res; + } + } else { + that.storage.removeItem('token'); + await that.cacheStore.clearCurrentUser(); + } + return res; + } + } + return response as any; + } + /** + * 一个简单的401处理, 如果401,则刷新token, 如果refreshToken不存在,则返回401 + * refetch 是否重新请求, 会有bug,无限循环,按需要使用 + * TODO: + * @param response + * @param ctx + * @param opts + * @returns + */ + async run401Action( + response: Result, + ctx?: { req?: any; res?: any; fetch?: any }, + opts?: { + /** + * 是否重新请求, 会有bug,无限循环,按需要使用 + */ + refetch?: boolean; + /** + * check之后的回调 + */ + afterCheck?: (res: Result) => any; + /** + * 401处理后, 还是401, 则回调 + */ + afterAlso401?: (res: Result) => any; + }, + ) { + const that = this; + const refetch = opts?.refetch ?? false; + + if (response?.code === 401) { + if (that.query.stop === true) { + return { code: 500, success: false, message: 'refresh token loading...' }; + } + that.query.stop = true; + const res = await that.afterCheck401ToRefreshToken(response, ctx, refetch); + that.query.stop = false; + opts?.afterCheck?.(res); + if (res.code === 401) { + opts?.afterAlso401?.(res); + } + return res; + } else { + return response as any; + } + } + /** + * 获取用户信息 + * @param token + * @returns + */ + async getMe(token?: string, check401: boolean = true) { + const _token = token || this.storage.getItem('token'); + const that = this; + return that.post( + { key: 'me' }, + { + noStop: true, + beforeRequest: async (config) => { + if (config.headers) { + config.headers['Authorization'] = `Bearer ${_token}`; + } + if (!_token) { + return false; + } + return config; + }, + afterResponse: async (response, ctx) => { + if (response?.code === 401 && check401 && !token) { + return await that.afterCheck401ToRefreshToken(response, ctx); + } + return response as any; + }, + }, + ); + } + /** + * 检查本地用户,如果本地用户存在,则返回本地用户,否则返回null + * @returns + */ + async checkLocalUser() { + const user = await this.cacheStore.getCurrentUser(); + if (user) { + return user; + } + return null; + } + /** + * 检查本地token是否存在,简单的判断是否已经属于登陆状态 + * @returns + */ + async checkLocalToken() { + const token = this.storage.getItem('token'); + return !!token; + } + /** + * 检查本地用户列表 + * @returns + */ + async getToken() { + const token = this.storage.getItem('token'); + return token || ''; + } + async beforeRequest(opts: any = {}) { + const token = this.storage.getItem('token'); + if (token) { + opts.headers = { ...opts.headers, Authorization: `Bearer ${token}` }; + } + return opts; + } + /** + * 请求更新,切换用户, 使用switchUser + * @param username + * @returns + */ + private async postSwitchUser(username: string) { + return this.post({ key: 'switchCheck', data: { username } }); + } + /** + * 切换用户 + * @param username + * @returns + */ + async switchUser(username: string) { + const localUserList = await this.cacheStore.getCurrentUserList(); + const user = localUserList.find((userItem) => userItem.user!.username === username); + if (user) { + this.storage.setItem('token', user.accessToken || ''); + await this.beforeSetLoginUser({ accessToken: user.accessToken, refreshToken: user.refreshToken }); + return { + code: 200, + data: { + accessToken: user.accessToken, + refreshToken: user.refreshToken, + }, + success: true, + message: '切换用户成功', + }; + } + const res = await this.postSwitchUser(username); + + if (res.code === 200) { + const { accessToken, refreshToken } = res?.data || {}; + this.storage.setItem('token', accessToken || ''); + await this.beforeSetLoginUser({ accessToken, refreshToken }); + } + return res; + } + /** + * 退出登陆,去掉token, 并删除缓存 + * @returns + */ + async logout() { + this.storage.removeItem('token'); + const users = await this.cacheStore.getCurrentUserList(); + const tokens = users + .map((user) => { + return user?.accessToken; + }) + .filter(Boolean); + this.cacheStore.delValue(); + return this.post({ key: 'logout', data: { tokens } }); + } + /** + * 检查用户名的组,这个用户是否存在 + * @param username + * @returns + */ + async hasUser(username: string) { + const that = this; + return this.post( + { + path: 'org', + key: 'hasUser', + data: { + username, + }, + }, + { + afterResponse: async (response, ctx) => { + if (response?.code === 401) { + const res = await that.afterCheck401ToRefreshToken(response, ctx, true); + return res; + } + return response as any; + }, + }, + ); + } + async getLoginUser() { + const that = this; + const userInfo = await that.checkLocalUser(); + const token = await that.getToken(); + if (userInfo) { + return userInfo; + } else if (token) { + const userinfo = await that.getLoginUserByToken(token); + if (userinfo) { + return userinfo; + } + } + return null; + } + async getLoginUserByToken(token: string): Promise { + const me = await this.getMe(token, false); + if (me.code === 200) { + const user = me.data; + this.cacheStore.setLoginUser({ + user, + id: user.id, + accessToken: token, + refreshToken: me.data?.refreshToken || '', + }); + return user; + } + return null; + } + /** + * 检查登录状态,根据 login by web + * @param token + * @returns + */ + async checkLoginStatus(token: string) { + const res = await this.post({ + path: 'user', + key: 'checkLoginStatus', + loginToken: token, + }); + if (res.code === 200) { + const accessToken = res.data?.accessToken; + this.storage.setItem('token', accessToken || ''); + await this.beforeSetLoginUser({ accessToken, refreshToken: res.data?.refreshToken }); + return res; + } + return false; + } + /** + * 使用web登录,创建url地址, 需要MD5和jsonwebtoken + */ + loginWithWeb(baseURL: string, { MD5, jsonwebtoken }: { MD5: any; jsonwebtoken: any }) { + const randomId = Math.random().toString(36).substring(2, 15); + const timestamp = Date.now(); + const tokenSecret = 'xiao' + randomId; + const sign = MD5(`${tokenSecret}${timestamp}`).toString(); + const token = jsonwebtoken.sign({ randomId, timestamp, sign }, tokenSecret, { + // 10分钟过期 + expiresIn: 60 * 10, // 10分钟 + }); + const url = `${baseURL}/api/router?path=user&key=webLogin&p&loginToken=${token}&sign=${sign}&randomId=${randomId}`; + return { url, token, tokenSecret }; + } +} diff --git a/src/query/query-mark/query-mark.ts b/src/query/query-mark/query-mark.ts new file mode 100644 index 0000000..1d58692 --- /dev/null +++ b/src/query/query-mark/query-mark.ts @@ -0,0 +1,154 @@ +import { Query } from '@kevisual/query'; +import type { Result, DataOpts } from '@kevisual/query/query'; + +export type SimpleObject = Record; +export const markType = ['simple', 'md', 'mdx', 'wallnote', 'excalidraw', 'chat'] as const; +export type MarkType = (typeof markType)[number]; +export type MarkData = { + nodes?: any[]; + edges?: any[]; + elements?: any[]; + permission?: any; + + [key: string]: any; +}; +export type Mark = { + id: string; + title: string; + description: string; + markType: MarkType; + link: string; + data?: MarkData; + uid: string; + puid: string; + summary: string; + thumbnail?: string; + tags: string[]; + createdAt: string; + updatedAt: string; + version: number; +}; +export type ShowMarkPick = Pick; + +export type SearchOpts = { + page?: number; + pageSize?: number; + search?: string; + sort?: string; // DESC, ASC + markType?: MarkType; // 类型 + [key: string]: any; +}; + +export type QueryMarkOpts = { + query?: Query; + isBrowser?: boolean; + onLoad?: () => void; +} & T; + +export type ResultMarkList = { + list: Mark[]; + pagination: { + pageSize: number; + current: number; + total: number; + }; +}; +export type QueryMarkData = { + id?: string; + title?: string; + description?: string; + [key: string]: any; +}; +export type QueryMarkResult = { + accessToken: string; + refreshToken: string; +}; + +export class QueryMarkBase { + query: Query; + isBrowser: boolean; + load?: boolean; + storage?: Storage; + onLoad?: () => void; + + constructor(opts?: QueryMarkOpts) { + this.query = opts?.query || new Query(); + this.isBrowser = opts?.isBrowser ?? true; + this.init(); + this.onLoad = opts?.onLoad; + } + setQuery(query: Query) { + this.query = query; + } + private async init() { + this.load = true; + this.onLoad?.(); + } + + async post>(data: any, opts?: DataOpts): Promise { + try { + return this.query.post({ path: 'mark', ...data }, opts) as Promise; + } catch (error) { + console.log('error', error); + return { + code: 400, + } as any; + } + } + + async getMarkList(search: SearchOpts, opts?: DataOpts) { + return this.post>({ key: 'list', ...search }, opts); + } + + async getMark(id: string, opts?: DataOpts) { + return this.post>({ key: 'get', id }, opts); + } + async getVersion(id: string, opts?: DataOpts) { + return this.post>({ key: 'getVersion', id }, opts); + } + /** + * 检查版本 + * 当需要更新时,返回true + * @param id + * @param version + * @param opts + * @returns + */ + async checkVersion(id: string, version?: number, opts?: DataOpts) { + if (!version) { + return true; + } + const res = await this.getVersion(id, opts); + if (res.code === 200) { + if (res.data!.version > version) { + return true; + } + return false; + } + return true; + } + + async updateMark(data: any, opts?: DataOpts) { + return this.post>({ key: 'update', data }, opts); + } + + async deleteMark(id: string, opts?: DataOpts) { + return this.post>({ key: 'delete', id }, opts); + } +} +export class QueryMark extends QueryMarkBase { + markType: string; + constructor(opts?: QueryMarkOpts & { markType?: MarkType }) { + super(opts); + this.markType = opts?.markType || 'simple'; + } + async getMarkList(search?: SearchOpts, opts?: DataOpts) { + return this.post>({ key: 'list', ...search, markType: this.markType }, opts); + } + async updateMark(data: any, opts?: DataOpts) { + if (!data.id) { + data.markType = this.markType || 'simple'; + } + return super.updateMark(data, opts); + } +} diff --git a/src/query/query-resources/index.ts b/src/query/query-resources/index.ts new file mode 100644 index 0000000..99b96e8 --- /dev/null +++ b/src/query/query-resources/index.ts @@ -0,0 +1,155 @@ +import { Content } from './../../apps/ai-editor/content'; +import { DataOpts, Result } from '@kevisual/query'; +import { adapter } from '@kevisual/query'; +import path from 'path-browserify-esm'; +import { hashContent } from './utils'; + +type QueryResourcesOptions = { + prefix?: string; + storage?: Storage; + username?: string; + [key: string]: any; +}; +export class QueryResources { + prefix: string; // /root/resources + storage: Storage; + constructor(opts: QueryResourcesOptions) { + if (opts.username) { + this.prefix = `/${opts.username}/resources/`; + } else { + this.prefix = opts.prefix || ''; + } + this.storage = opts.storage || localStorage; + } + setUsername(username: string) { + const prefix = `/${username}/resources/`; + return prefix; + } + setPrefix(prefix: string) { + this.prefix = prefix; + } + header(headers?: Record, json = true): Record { + const token = this.storage.getItem('token'); + const _headers: Record = { + 'Content-Type': 'application/json', + ...headers, + }; + if (!json) { + delete _headers['Content-Type']; + } + if (!token) { + return _headers; + } + return { + ..._headers, + Authorization: `Bearer ${token}`, + }; + } + async get(data: any, opts: DataOpts): Promise { + return adapter({ + url: opts.url!, + method: 'GET', + body: data, + ...opts, + headers: this.header(opts?.headers), + }); + } + async getList(prefix: string, data?: { recursive?: boolean }, opts?: DataOpts): Promise> { + return this.get(data, { + url: `${this.prefix}${prefix}`, + body: data, + ...opts, + }); + } + async fetchFile(filepath: string, opts?: DataOpts): Promise> { + const url = `${this.prefix}${filepath}`; + return this.get({}, { url, method: 'GET', headers: this.header(opts?.headers, false), isText: true }); + } + async uploadFile(filepath: string, content: string, opts?: DataOpts): Promise> { + const pathname = `${this.prefix}${filepath}`; + const filename = path.basename(pathname); + const type = getContentType(filename); + const url = new URL(pathname, window.location.origin); + const hash = hashContent(content); + url.searchParams.set('hash', hash); + const formData = new FormData(); + formData.append('file', new Blob([content], { type })); + return adapter({ + url: url.toString(), + headers: { ...this.header(opts?.headers, false) }, + isPostFile: true, + + method: 'POST', + body: formData, + }); + } +} + +export const getContentType = (filename: string): string => { + const ext = path.extname(filename); + let type = 'text/plain'; + + switch (ext) { + case '': + type = 'application/octet-stream'; + break; + case '.json': + type = 'application/json'; + break; + case '.txt': + type = 'text/plain'; + break; + case '.csv': + type = 'text/csv'; + break; + case '.md': + type = 'text/markdown'; + break; + case '.html': + case '.htm': + type = 'text/html'; + break; + case '.xml': + type = 'application/xml'; + break; + case '.js': + type = 'application/javascript'; + break; + case '.css': + type = 'text/css'; + break; + case '.ts': + type = 'application/typescript'; + break; + case '.pdf': + type = 'application/pdf'; + break; + case '.zip': + type = 'application/zip'; + break; + case '.docx': + type = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; + break; + case '.xlsx': + type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; + break; + case '.mp3': + type = 'audio/mpeg'; + break; + case '.mp4': + type = 'video/mp4'; + break; + case '.png': + case '.jpg': + case '.jpeg': + case '.gif': + case '.webp': + type = `image/${ext.slice(1)}`; + break; + case '.svg': + type = 'image/svg+xml'; + break; + } + + return type; +}; diff --git a/src/query/query-resources/utils.ts b/src/query/query-resources/utils.ts new file mode 100644 index 0000000..895734f --- /dev/null +++ b/src/query/query-resources/utils.ts @@ -0,0 +1,42 @@ +import MD5 from 'crypto-js/md5'; + +export const hashContent = (str: string | Buffer): string => { + if (typeof str === 'string') { + return MD5(str).toString(); + } else if (Buffer.isBuffer(str)) { + return MD5(str.toString()).toString(); + } + console.error('hashContent error: input must be a string or Buffer'); + return ''; +}; +export const hashFile = (file: File): Promise => { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + + reader.onload = async (event) => { + try { + const content = event.target?.result; + if (content instanceof ArrayBuffer) { + const contentString = new TextDecoder().decode(content); + const hashHex = MD5(contentString).toString(); + resolve(hashHex); + } else if (typeof content === 'string') { + const hashHex = MD5(content).toString(); + resolve(hashHex); + } else { + throw new Error('Invalid content type'); + } + } catch (error) { + console.error('hashFile error', error); + reject(error); + } + }; + + reader.onerror = (error) => { + reject(error); + }; + + // 读取文件为 ArrayBuffer + reader.readAsArrayBuffer(file); + }); +}; diff --git a/src/query/query-shop/defines/query-shop-define.ts b/src/query/query-shop/defines/query-shop-define.ts new file mode 100644 index 0000000..160a089 --- /dev/null +++ b/src/query/query-shop/defines/query-shop-define.ts @@ -0,0 +1,27 @@ +import { QueryUtil } from '@/query/index.ts'; + +export const shopDefine = QueryUtil.create({ + getRegistry: { + path: 'shop', + key: 'get-registry', + description: '获取应用商店注册表信息', + }, + + listInstalled: { + path: 'shop', + key: 'list-installed', + description: '列出当前已安装的所有应用', + }, + + install: { + path: 'shop', + key: 'install', + description: '安装指定的应用,可以指定 id、type、force 和 yes 参数', + }, + + uninstall: { + path: 'shop', + key: 'uninstall', + description: '卸载指定的应用,可以指定 id 和 type 参数', + }, +}); diff --git a/src/query/query-shop/query-shop.ts b/src/query/query-shop/query-shop.ts new file mode 100644 index 0000000..c5eba7e --- /dev/null +++ b/src/query/query-shop/query-shop.ts @@ -0,0 +1,17 @@ +import { shopDefine } from './defines/query-shop-define.ts'; + +import { BaseQuery, DataOpts, Query } from '@kevisual/query/query'; + +export { shopDefine }; + +export class QueryShop extends BaseQuery { + constructor(opts?: { query: T }) { + super({ + query: opts?.query!, + queryDefine: shopDefine, + }); + } + getInstall(data: any, opts?: DataOpts) { + return this.queryDefine.queryChain('install').post(data, opts); + } +} diff --git a/src/query/query-upload/core/upload-chunk.ts b/src/query/query-upload/core/upload-chunk.ts new file mode 100644 index 0000000..6b7a4dd --- /dev/null +++ b/src/query/query-upload/core/upload-chunk.ts @@ -0,0 +1,134 @@ +import { randomId } from '../utils/random-id.ts'; +import { UploadProgress } from './upload-progress.ts'; +export type ConvertOpts = { + appKey?: string; + version?: string; + username?: string; + directory?: string; + isPublic?: boolean; + filename?: string; + /** + * 是否不检查应用文件, 默认 true,默认不检测 + */ + noCheckAppFiles?: boolean; +}; + +// createEventSource: (baseUrl: string, searchParams: URLSearchParams) => { +// return new EventSource(baseUrl + '/api/s1/events?' + searchParams.toString()); +// }, +export type UploadOpts = { + uploadProgress: UploadProgress; + /** + * 创建 EventSource 兼容 nodejs + * @param baseUrl 基础 URL + * @param searchParams 查询参数 + * @returns EventSource + */ + createEventSource: (baseUrl: string, searchParams: URLSearchParams) => EventSource; + baseUrl?: string; + token: string; + FormDataFn: any; +}; +export const uploadFileChunked = async (file: File, opts: ConvertOpts, opts2: UploadOpts) => { + const { directory, appKey, version, username, isPublic, noCheckAppFiles = true } = opts; + const { uploadProgress, createEventSource, baseUrl = '', token, FormDataFn } = opts2 || {}; + return new Promise(async (resolve, reject) => { + const taskId = randomId(); + const filename = opts.filename || file.name; + uploadProgress?.start(`${filename} 上传中...`); + + const searchParams = new URLSearchParams(); + searchParams.set('taskId', taskId); + if (isPublic) { + searchParams.set('public', 'true'); + } + if (noCheckAppFiles) { + searchParams.set('noCheckAppFiles', '1'); + } + const eventSource = createEventSource(baseUrl + '/api/s1/events', searchParams); + let isError = false; + // 监听服务器推送的进度更新 + eventSource.onmessage = function (event) { + console.log('Progress update:', event.data); + const parseIfJson = (data: string) => { + try { + return JSON.parse(data); + } catch (e) { + return data; + } + }; + const receivedData = parseIfJson(event.data); + if (typeof receivedData === 'string') return; + const progress = Number(receivedData.progress); + const progressFixed = progress.toFixed(2); + uploadProgress?.set(progress, { ...receivedData, progressFixed, filename, taskId }); + }; + eventSource.onerror = function (event) { + console.log('eventSource.onerror', event); + isError = true; + reject(event); + }; + + const chunkSize = 1 * 1024 * 1024; // 1MB + const totalChunks = Math.ceil(file.size / chunkSize); + + for (let currentChunk = 0; currentChunk < totalChunks; currentChunk++) { + const start = currentChunk * chunkSize; + const end = Math.min(start + chunkSize, file.size); + const chunk = file.slice(start, end); + + const formData = new FormDataFn(); + formData.append('file', chunk, filename); + formData.append('chunkIndex', currentChunk.toString()); + formData.append('totalChunks', totalChunks.toString()); + const isLast = currentChunk === totalChunks - 1; + if (directory) { + formData.append('directory', directory); + } + if (appKey && version) { + formData.append('appKey', appKey); + formData.append('version', version); + } + if (username) { + formData.append('username', username); + } + try { + const res = await fetch(baseUrl + '/api/s1/resources/upload/chunk?taskId=' + taskId, { + method: 'POST', + body: formData, + headers: { + 'task-id': taskId, + Authorization: `Bearer ${token}`, + }, + }).then((response) => response.json()); + + if (res?.code !== 200) { + console.log('uploadChunk error', res); + uploadProgress?.error(res?.message || '上传失败'); + isError = true; + eventSource.close(); + + uploadProgress?.done(); + reject(new Error(res?.message || '上传失败')); + return; + } + if (isLast) { + fetch(baseUrl + '/api/s1/events/close?taskId=' + taskId); + eventSource.close(); + uploadProgress?.done(); + resolve(res); + } + // console.log(`Chunk ${currentChunk + 1}/${totalChunks} uploaded`, res); + } catch (error) { + console.log('Error uploading chunk', error); + fetch(baseUrl + '/api/s1/events/close?taskId=' + taskId); + reject(error); + return; + } + } + // 循环结束 + if (!uploadProgress?.end) { + uploadProgress?.done(); + } + }); +}; diff --git a/src/query/query-upload/core/upload-progress.ts b/src/query/query-upload/core/upload-progress.ts new file mode 100644 index 0000000..1de66a6 --- /dev/null +++ b/src/query/query-upload/core/upload-progress.ts @@ -0,0 +1,103 @@ +interface UploadNProgress { + start: (msg?: string) => void; + done: () => void; + set: (progress: number) => void; +} +export type UploadProgressData = { + progress: number; + progressFixed: number; + filename?: string; + taskId?: string; +}; +type UploadProgressOpts = { + onStart?: () => void; + onDone?: () => void; + onProgress?: (progress: number, data?: UploadProgressData) => void; +}; +export class UploadProgress implements UploadNProgress { + /** + * 进度 + */ + progress: number; + /** + * 开始回调 + */ + onStart: (() => void) | undefined; + /** + * 结束回调 + */ + onDone: (() => void) | undefined; + /** + * 消息回调 + */ + onProgress: ((progress: number, data?: UploadProgressData) => void) | undefined; + /** + * 数据 + */ + data: any; + /** + * 是否结束 + */ + end: boolean; + constructor(uploadOpts: UploadProgressOpts) { + this.progress = 0; + this.end = false; + const mockFn = () => {}; + this.onStart = uploadOpts.onStart || mockFn; + this.onDone = uploadOpts.onDone || mockFn; + this.onProgress = uploadOpts.onProgress || mockFn; + } + start(msg?: string) { + this.progress = 0; + msg && this.info(msg); + this.end = false; + this.onStart?.(); + } + done() { + this.progress = 100; + this.end = true; + this.onDone?.(); + } + set(progress: number, data?: UploadProgressData) { + this.progress = progress; + this.data = data; + this.onProgress?.(progress, data); + console.log('uploadProgress set', progress, data); + } + /** + * 开始回调 + */ + setOnStart(callback: () => void) { + this.onStart = callback; + } + /** + * 结束回调 + */ + setOnDone(callback: () => void) { + this.onDone = callback; + } + /** + * 消息回调 + */ + setOnProgress(callback: (progress: number, data?: UploadProgressData) => void) { + this.onProgress = callback; + } + /** + * 打印信息 + */ + info(msg: string) { + console.log(msg); + } + /** + * 打印错误 + */ + error(msg: string) { + console.error(msg); + } + /** + * 打印警告 + */ + warn(msg: string) { + console.warn(msg); + } +} diff --git a/src/query/query-upload/core/upload.ts b/src/query/query-upload/core/upload.ts new file mode 100644 index 0000000..d545a3d --- /dev/null +++ b/src/query/query-upload/core/upload.ts @@ -0,0 +1,113 @@ +import { randomId } from '../utils/random-id.ts'; +import type { UploadOpts } from './upload-chunk.ts'; +type ConvertOpts = { + appKey?: string; + version?: string; + username?: string; + directory?: string; + /** + * 文件大小限制 + */ + maxSize?: number; + /** + * 文件数量限制 + */ + maxCount?: number; + /** + * 是否不检查应用文件, 默认 true,默认不检测 + */ + noCheckAppFiles?: boolean; +}; + +export const uploadFiles = async (files: File[], opts: ConvertOpts, opts2: UploadOpts) => { + const { directory, appKey, version, username, noCheckAppFiles = true } = opts; + const { uploadProgress, createEventSource, baseUrl = '', token, FormDataFn } = opts2 || {}; + const length = files.length; + const maxSize = opts.maxSize || 20 * 1024 * 1024; // 20MB + const totalSize = files.reduce((acc, file) => acc + file.size, 0); + if (totalSize > maxSize) { + const maxSizeMB = maxSize / 1024 / 1024; + uploadProgress?.error('有文件大小不能超过' + maxSizeMB + 'MB'); + return; + } + const maxCount = opts.maxCount || 10; + if (length > maxCount) { + uploadProgress?.error(`最多只能上传${maxCount}个文件`); + return; + } + uploadProgress?.info(`上传中,共${length}个文件`); + return new Promise((resolve, reject) => { + const formData = new FormDataFn(); + const webkitRelativePath = files[0]?.webkitRelativePath; + const keepDirectory = webkitRelativePath !== ''; + const root = keepDirectory ? webkitRelativePath.split('/')[0] : ''; + for (let i = 0; i < files.length; i++) { + const file = files[i]; + if (keepDirectory) { + // relativePath 去除第一级 + const webkitRelativePath = file.webkitRelativePath.replace(root + '/', ''); + formData.append('file', file, webkitRelativePath); // 保留文件夹路径 + } else { + formData.append('file', files[i], files[i].name); + } + } + if (directory) { + formData.append('directory', directory); + } + if (appKey && version) { + formData.append('appKey', appKey); + formData.append('version', version); + } + if (username) { + formData.append('username', username); + } + const searchParams = new URLSearchParams(); + const taskId = randomId(); + searchParams.set('taskId', taskId); + + if (noCheckAppFiles) { + searchParams.set('noCheckAppFiles', '1'); + } + const eventSource = new EventSource('/api/s1/events?taskId=' + taskId); + + uploadProgress?.start('上传中...'); + eventSource.onopen = async function (event) { + const res = await fetch('/api/s1/resources/upload?' + searchParams.toString(), { + method: 'POST', + body: formData, + headers: { + 'task-id': taskId, + Authorization: `Bearer ${token}`, + }, + }).then((response) => response.json()); + + console.log('upload success', res); + fetch('/api/s1/events/close?taskId=' + taskId); + eventSource.close(); + uploadProgress?.done(); + resolve(res); + }; + // 监听服务器推送的进度更新 + eventSource.onmessage = function (event) { + console.log('Progress update:', event.data); + const parseIfJson = (data: string) => { + try { + return JSON.parse(data); + } catch (e) { + return data; + } + }; + const receivedData = parseIfJson(event.data); + if (typeof receivedData === 'string') return; + const progress = Number(receivedData.progress); + const progressFixed = progress.toFixed(2); + console.log('progress', progress); + uploadProgress?.set(progress, { ...receivedData, taskId, progressFixed }); + }; + + eventSource.onerror = function (event) { + console.log('eventSource.onerror', event); + reject(event); + }; + }); +}; diff --git a/src/query/query-upload/query-upload-browser.ts b/src/query/query-upload/query-upload-browser.ts new file mode 100644 index 0000000..16e502c --- /dev/null +++ b/src/query/query-upload/query-upload-browser.ts @@ -0,0 +1,51 @@ +import { UploadProgress, UploadProgressData } from './core/upload-progress.ts'; +import { uploadFileChunked } from './core/upload-chunk.ts'; +import { toFile, uploadFiles, randomId } from './query-upload.ts'; + +export { toFile, randomId }; +export { uploadFiles, uploadFileChunked, UploadProgress }; + +type UploadFileProps = { + onStart?: () => void; + onDone?: () => void; + onProgress?: (progress: number, data: UploadProgressData) => void; + onSuccess?: (res: any) => void; + onError?: (err: any) => void; + token?: string; +}; +export type ConvertOpts = { + appKey?: string; + version?: string; + username?: string; + directory?: string; + isPublic?: boolean; + filename?: string; + /** + * 是否不检查应用文件, 默认 true,默认不检测 + */ + noCheckAppFiles?: boolean; +}; + +export const uploadChunk = async (file: File, opts: ConvertOpts, props?: UploadFileProps) => { + const uploadProgress = new UploadProgress({ + onStart: function () { + props?.onStart?.(); + }, + onDone: () => { + props?.onDone?.(); + }, + onProgress: (progress, data) => { + props?.onProgress?.(progress, data!); + }, + }); + const result = await uploadFileChunked(file, opts, { + uploadProgress, + token: props?.token!, + createEventSource: (url: string, searchParams: URLSearchParams) => { + return new EventSource(url + '?' + searchParams.toString()); + }, + FormDataFn: FormData, + }); + + return result; +}; diff --git a/src/query/query-upload/query-upload-node.ts b/src/query/query-upload/query-upload-node.ts new file mode 100644 index 0000000..f638cb6 --- /dev/null +++ b/src/query/query-upload/query-upload-node.ts @@ -0,0 +1 @@ +// console.log('upload) \ No newline at end of file diff --git a/src/query/query-upload/query-upload.ts b/src/query/query-upload/query-upload.ts new file mode 100644 index 0000000..547d20b --- /dev/null +++ b/src/query/query-upload/query-upload.ts @@ -0,0 +1,11 @@ +import { uploadFiles } from './core/upload.ts'; + +import { uploadFileChunked } from './core/upload-chunk.ts'; +import { UploadProgress } from './core/upload-progress.ts'; + +export { uploadFiles, uploadFileChunked, UploadProgress }; + +export * from './utils/to-file.ts'; +export { randomId } from './utils/random-id.ts'; + +export { filterFiles } from './utils/filter-files.ts'; diff --git a/src/query/query-upload/utils/filter-files.ts b/src/query/query-upload/utils/filter-files.ts new file mode 100644 index 0000000..71ab8f0 --- /dev/null +++ b/src/query/query-upload/utils/filter-files.ts @@ -0,0 +1,23 @@ +/** + * 过滤文件, 过滤 .DS_Store, node_modules, 以.开头的文件, 过滤 __开头的文件 + * @param files + * @returns + */ +export const filterFiles = (files: File[]) => { + files = files.filter((file) => { + if (file.webkitRelativePath.startsWith('__MACOSX')) { + return false; + } + // 过滤node_modules + if (file.webkitRelativePath.includes('node_modules')) { + return false; + } + // 过滤文件 .DS_Store + if (file.name === '.DS_Store') { + return false; + } + // 过滤以.开头的文件 + return !file.name.startsWith('.'); + }); + return files; +}; diff --git a/src/query/query-upload/utils/index.ts b/src/query/query-upload/utils/index.ts new file mode 100644 index 0000000..86bd60c --- /dev/null +++ b/src/query/query-upload/utils/index.ts @@ -0,0 +1,3 @@ +export * from './to-file.ts'; +export * from './filter-files.ts'; +export * from './random-id.ts'; diff --git a/src/query/query-upload/utils/random-id.ts b/src/query/query-upload/utils/random-id.ts new file mode 100644 index 0000000..c36e4f0 --- /dev/null +++ b/src/query/query-upload/utils/random-id.ts @@ -0,0 +1,3 @@ +export const randomId = () => { + return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); +}; \ No newline at end of file diff --git a/src/query/query-upload/utils/to-file.ts b/src/query/query-upload/utils/to-file.ts new file mode 100644 index 0000000..1072e24 --- /dev/null +++ b/src/query/query-upload/utils/to-file.ts @@ -0,0 +1,105 @@ +const getFileExtension = (filename: string) => { + return filename.split('.').pop(); +}; +const getFileType = (extension: string) => { + switch (extension) { + case 'js': + return 'text/javascript'; + case 'css': + return 'text/css'; + case 'html': + return 'text/html'; + case 'json': + return 'application/json'; + case 'png': + return 'image/png'; + case 'jpg': + return 'image/jpeg'; + case 'jpeg': + return 'image/jpeg'; + case 'gif': + return 'image/gif'; + case 'svg': + return 'image/svg+xml'; + case 'webp': + return 'image/webp'; + case 'ico': + return 'image/x-icon'; + default: + return 'text/plain'; + } +}; +const checkIsBase64 = (content: string) => { + return content.startsWith('data:'); +}; +/** + * 获取文件的目录和文件名 + * @param filename 文件名 + * @returns 目录和文件名 + */ +export const getDirectoryAndName = (filename: string) => { + if (!filename) { + return null; + } + if (filename.startsWith('.')) { + return null; + } else { + filename = filename.replace(/^\/+/, ''); // Remove all leading slashes + } + const hasDirectory = filename.includes('/'); + if (!hasDirectory) { + return { directory: '', name: filename }; + } + const parts = filename.split('/'); + const name = parts.pop()!; // Get the last part as the file name + const directory = parts.join('/'); // Join the remaining parts as the directory + return { directory, name }; +}; +/** + * 把字符串转为文件流,并返回文件流,根据filename的扩展名,自动设置文件类型. + * 当不是文本类型,自动需要把base64的字符串转为blob + * @param content 字符串 + * @param filename 文件名 + * @returns 文件流 + */ +export const toFile = (content: string, filename: string) => { + // 如果文件名是 a/d/a.js 格式的,则需要把d作为目录,a.js作为文件名 + const directoryAndName = getDirectoryAndName(filename); + if (!directoryAndName) { + throw new Error('Invalid filename'); + } + const { name } = directoryAndName; + const extension = getFileExtension(name); + if (!extension) { + throw new Error('Invalid filename'); + } + const isBase64 = checkIsBase64(content); + const type = getFileType(extension); + + if (isBase64) { + // Decode base64 string + const base64Data = content.split(',')[1]; // Remove the data URL prefix + const byteCharacters = atob(base64Data); + const byteNumbers = new Array(byteCharacters.length); + for (let i = 0; i < byteCharacters.length; i++) { + byteNumbers[i] = byteCharacters.charCodeAt(i); + } + const byteArray = new Uint8Array(byteNumbers); + const blob = new Blob([byteArray], { type }); + return new File([blob], filename, { type }); + } else { + const blob = new Blob([content], { type }); + return new File([blob], filename, { type }); + } +}; + +/** + * 把字符串转为文本文件 + * @param content 字符串 + * @param filename 文件名 + * @returns 文件流 + */ +export const toTextFile = (content: string = 'keep directory exist', filename: string = 'keep.txt') => { + const file = toFile(content, filename); + return file; +}; diff --git a/submodules/store b/submodules/store index 9d22faa..bbf826b 160000 --- a/submodules/store +++ b/submodules/store @@ -1 +1 @@ -Subproject commit 9d22faa8ba210d183064b15cc229563d9cf89430 +Subproject commit bbf826b765f841fb0f07b2180a6fe7f3de009116