diff --git a/.gitignore b/.gitignore index 6407e0bb..5b4a5874 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ progress.md .pi/agent/git/ .pi/agent/npm/ .pi/agent/bin/ +.pi/agent/data/ .pi/agent/auth.json .pi/agent/models.json .pi/agent/settings.json @@ -67,3 +68,10 @@ progress.md tmp/ bun.lock collect.sh + +# Root-level binary/build artifacts (do not commit) +/*.wasm +/llvm-*.js +/rustc-*.js +/util_cmd-*.js +/wasm32-*.tar.br diff --git a/.pi/agent/AGENTS.md b/.pi/agent/AGENTS.md index 905090d5..8e0ff456 100755 --- a/.pi/agent/AGENTS.md +++ b/.pi/agent/AGENTS.md @@ -62,11 +62,11 @@ - Go:默认已有 `GOPROXY=https://goproxy.cn,direct`;若仍不可用,设置 `http_proxy`/`https_proxy` 环境变量 - Docker pull:配置 Docker daemon 代理或使用 `docker pull` 前设置环境变量 - 代理地址汇总:HTTP 代理 `http://192.168.1.1:17892`、SOCKS5 代理 `socks5://192.168.1.1:17891`(由 smywrt mihomo 提供) -- 操作完成���如非必要应及时取消代理,避免影响内网服务访问 +- 操作完成如非必要应及时取消代理,避免影响内网服务访问 ## SproutClaw 项目规范 -- 当用户要求安装 npm 扩展时,默认使用 `pi install npm:<包名>` 命令安装 -- 安装目录为 `/shumengya/project/agent/sproutclaw/.pi/agent/npm/node_modules/` +- 当用户要求安装 npm 插件扩展时,默认使用 `sproutclaw install npm:<包名>` 命令安装 +- 安装目录为 `sproutclaw/.pi/agent/npm/node_modules/` - 不要使用 `npm install --save-dev` 安装 pi 扩展,避免冗余安装到根 `node_modules` ## 服务器Docker部署规则 @@ -76,17 +76,6 @@ - 资源限制:所有容器统一设置内存限制 `5GB` - 管理员认证:默认使用内网密码 `shumengya520`(存在默认认证时使用) -## 网络代理规则(克隆与依赖下载) -- 当用户要求 `git clone` 克隆项目,或下载/安装项目依赖(npm/pip/cargo/go mod 等)时,**优先配置代理后再执行操作**,避免因网络问题导致超时或失败 -- Git 代理:执行前先设置环境变量 `export http_proxy=http://192.168.1.1:17892` 和 `export https_proxy=http://192.168.1.1:17892`(或 `git config --global http.proxy`),克隆完成后记得取消代理 -- npm/yarn/pnpm:使用 `--proxy http://192.168.1.1:17892` 或设置环境变量 `http_proxy`/`https_proxy` -- pip:使用 `--proxy http://192.168.1.1:17892` 或设置环境变量 -- cargo:设置环境变量 `http_proxy`/`https_proxy`,或配置 `~/.cargo/config.toml` 中的 `[http]` 代理 -- Go:默认已有 `GOPROXY=https://goproxy.cn,direct`;若仍不可用,设置 `http_proxy`/`https_proxy` 环境变量 -- Docker pull:配置 Docker daemon 代理或使用 `docker pull` 前设置环境变量 -- 代理地址汇总:HTTP 代理 `http://192.168.1.1:17892`、SOCKS5 代理 `socks5://192.168.1.1:17891`(由 smywrt mihomo 提供) -- 操作完成后如非必要应及时取消代理,避免影响内网服务访问 - ## Emoji 表现 - 萌小芽的专属 Emoji 为:`O(≧口≦)O` `(≧∇≦)` `(`・ω・´)` `(。・ω・。)` `(=・ω・=)` `ヘ(=^・ω・^=)ノ` `|・ω・`)` - 在合适且自然的场景下,可少量使用这些 Emoji,避免过度堆叠 diff --git a/.pi/agent/extensions/prompt-url-widget/index.ts b/.pi/agent/extensions-disabled/prompt-url-widget/index.ts similarity index 100% rename from .pi/agent/extensions/prompt-url-widget/index.ts rename to .pi/agent/extensions-disabled/prompt-url-widget/index.ts diff --git a/.pi/agent/extensions/redraws/index.ts b/.pi/agent/extensions-disabled/redraws/index.ts similarity index 100% rename from .pi/agent/extensions/redraws/index.ts rename to .pi/agent/extensions-disabled/redraws/index.ts diff --git a/.pi/agent/extensions/webui/.gitignore b/.pi/agent/extensions/webui/.gitignore deleted file mode 100644 index 45a4f775..00000000 --- a/.pi/agent/extensions/webui/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -frontend/dist/ -frontend/dist-desketop/ -frontend/.env.desktop -data/ -webui-service.env -*.db -webui-settings.json.migrated -.webui.pid diff --git a/.pi/agent/extensions/webui/backend/config/cli.ts b/.pi/agent/extensions/webui/backend/config/cli.ts deleted file mode 100644 index 4b16b1e8..00000000 --- a/.pi/agent/extensions/webui/backend/config/cli.ts +++ /dev/null @@ -1,9 +0,0 @@ -export function parsePort(argv: string[] = process.argv.slice(2)): number { - const idx = argv.indexOf("--port"); - const raw = idx !== -1 ? argv[idx + 1] : "19133"; - const port = parseInt(raw || "19133", 10); - if (!Number.isFinite(port) || port < 1 || port > 65535) { - throw new Error(`无效端口: ${raw}`); - } - return port; -} diff --git a/.pi/agent/extensions/webui/backend/config/paths.ts b/.pi/agent/extensions/webui/backend/config/paths.ts deleted file mode 100644 index 86ade9c4..00000000 --- a/.pi/agent/extensions/webui/backend/config/paths.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { existsSync } from "node:fs"; -import { dirname, join, resolve } from "node:path"; -import { fileURLToPath } from "node:url"; - -const configDir = dirname(fileURLToPath(import.meta.url)); -const backendDir = dirname(configDir); -const extensionRoot = resolve(backendDir, ".."); - -export interface WebUiPaths { - extensionRoot: string; - repoRoot: string; - agentDir: string; - publicDir: string; - pidFile: string; - sessionsDir: string; - agentExtensionsDir: string; - agentNpmNodeModules: string; - agentSettingsFile: string; - systemPromptFile: string; - modelsConfigFile: string; - mcpCacheFile: string; - mcpConfigFile: string; - piCliDist: string; -} - -export function createWebUiPaths(): WebUiPaths { - const repoRoot = process.cwd(); - const agentDir = resolve(process.env.PI_CODING_AGENT_DIR || join(repoRoot, ".pi", "agent")); - - return { - extensionRoot, - repoRoot, - agentDir, - publicDir: join(extensionRoot, "frontend", "dist"), - pidFile: join(extensionRoot, ".webui.pid"), - sessionsDir: join(agentDir, "sessions"), - agentExtensionsDir: join(agentDir, "extensions"), - agentNpmNodeModules: join(agentDir, "npm", "node_modules"), - agentSettingsFile: join(agentDir, "settings.json"), - systemPromptFile: join(agentDir, "AGENTS.md"), - modelsConfigFile: join(agentDir, "models.json"), - mcpCacheFile: join(agentDir, "mcp-cache.json"), - mcpConfigFile: join(agentDir, "mcp.json"), - piCliDist: join(repoRoot, "packages", "coding-agent", "dist", "cli.js"), - }; -} - -export type PiRpcLaunchMode = "dist" | "tsx"; - -export function resolvePiRpcLaunch( - paths: WebUiPaths, -): { command: string; args: string[]; mode: PiRpcLaunchMode } { - const rpcArgs = ["--mode", "rpc"]; - if (existsSync(paths.piCliDist)) { - return { command: process.execPath, args: [paths.piCliDist, ...rpcArgs], mode: "dist" }; - } - - const tsxCli = join(paths.repoRoot, "node_modules", "tsx", "dist", "cli.mjs"); - const piCliSrc = join(paths.repoRoot, "packages", "coding-agent", "src", "cli.ts"); - if (existsSync(tsxCli) && existsSync(piCliSrc)) { - return { command: process.execPath, args: [tsxCli, piCliSrc, ...rpcArgs], mode: "tsx" }; - } - - const buildHint = - process.platform === "win32" - ? "请先运行: npm run build 或 pi-built.bat" - : "请先运行: npm run build 或 sproutclaw build"; - throw new Error(`[webui] pi 未找到: ${paths.piCliDist}。${buildHint}`); -} diff --git a/.pi/agent/extensions/webui/backend/db/index.ts b/.pi/agent/extensions/webui/backend/db/index.ts deleted file mode 100644 index e9f00f27..00000000 --- a/.pi/agent/extensions/webui/backend/db/index.ts +++ /dev/null @@ -1,224 +0,0 @@ -/** - * WebUI 专有 SQLite 配置存储 - * - * 数据库文件位于扩展目录 data/webui.db,与 pi-Agent 配置完全隔离。 - */ - -import { existsSync, mkdirSync, readFileSync, renameSync } from "node:fs"; -import { join } from "node:path"; -import { DatabaseSync } from "node:sqlite"; - -const SCHEMA_VERSION = 1; - -export interface WebuiDbInfo { - dataDir: string; - dbPath: string; -} - -export interface WebuiAvatarSettings { - userAvatarUrl: string; - agentAvatarUrl: string; -} - -let db: DatabaseSync | null = null; - -function requireDb(): DatabaseSync { - if (!db?.isOpen) { - throw new Error("WebUI 数据库未初始化"); - } - return db; -} - -function getMeta(key: string): string | null { - const row = requireDb() - .prepare("SELECT value FROM webui_meta WHERE key = ?") - .get(key) as { value: string } | undefined; - return row?.value ?? null; -} - -function setMeta(key: string, value: string): void { - requireDb() - .prepare( - `INSERT INTO webui_meta (key, value) VALUES (?, ?) - ON CONFLICT(key) DO UPDATE SET value = excluded.value`, - ) - .run(key, value); -} - -function migrateLegacyJsonIfNeeded(extensionDir: string): void { - if (getMeta("legacy_json_migrated") === "1") return; - - const legacyFile = join(extensionDir, "webui-settings.json"); - if (!existsSync(legacyFile)) { - setMeta("legacy_json_migrated", "1"); - return; - } - - try { - const raw = JSON.parse(readFileSync(legacyFile, "utf8")) as Partial; - if (typeof raw.userAvatarUrl === "string" && raw.userAvatarUrl && !getWebuiConfig("userAvatarUrl")) { - setWebuiConfig("userAvatarUrl", raw.userAvatarUrl); - } - if (typeof raw.agentAvatarUrl === "string" && raw.agentAvatarUrl && !getWebuiConfig("agentAvatarUrl")) { - setWebuiConfig("agentAvatarUrl", raw.agentAvatarUrl); - } - const migratedPath = `${legacyFile}.migrated`; - if (!existsSync(migratedPath)) { - renameSync(legacyFile, migratedPath); - } - console.log("[webui] 已从 webui-settings.json 迁移配置到 SQLite"); - } catch (err) { - console.warn("[webui] 迁移 webui-settings.json 失败:", err); - } - - setMeta("legacy_json_migrated", "1"); -} - -export function initWebuiDatabase(extensionDir: string): WebuiDbInfo { - const dataDir = join(extensionDir, "data"); - const dbPath = join(dataDir, "webui.db"); - mkdirSync(dataDir, { recursive: true }); - - db = new DatabaseSync(dbPath); - db.exec("PRAGMA journal_mode = WAL;"); - db.exec("PRAGMA foreign_keys = ON;"); - db.exec(` - CREATE TABLE IF NOT EXISTS webui_meta ( - key TEXT PRIMARY KEY NOT NULL, - value TEXT NOT NULL - ); - CREATE TABLE IF NOT EXISTS webui_config ( - key TEXT PRIMARY KEY NOT NULL, - value TEXT NOT NULL, - updated_at TEXT NOT NULL - ); - `); - - if (!getMeta("schema_version")) { - setMeta("schema_version", String(SCHEMA_VERSION)); - } - - migrateLegacyJsonIfNeeded(extensionDir); - - return { dataDir, dbPath }; -} - -export function getWebuiConfig(key: string): string | null { - const row = requireDb() - .prepare("SELECT value FROM webui_config WHERE key = ?") - .get(key) as { value: string } | undefined; - return row?.value ?? null; -} - -export function setWebuiConfig(key: string, value: string): void { - const now = new Date().toISOString(); - requireDb() - .prepare( - `INSERT INTO webui_config (key, value, updated_at) VALUES (?, ?, ?) - ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at`, - ) - .run(key, value, now); -} - -export function setWebuiConfigMany(entries: Record): void { - const stmt = requireDb().prepare( - `INSERT INTO webui_config (key, value, updated_at) VALUES (?, ?, ?) - ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at`, - ); - const now = new Date().toISOString(); - for (const [key, value] of Object.entries(entries)) { - stmt.run(key, value, now); - } -} - -export function getAllWebuiConfig(): Record { - const rows = requireDb() - .prepare("SELECT key, value FROM webui_config ORDER BY key") - .all() as Array<{ key: string; value: string }>; - return Object.fromEntries(rows.map((row) => [row.key, row.value])); -} - -export function deleteWebuiConfig(key: string): boolean { - const result = requireDb().prepare("DELETE FROM webui_config WHERE key = ?").run(key); - return result.changes > 0; -} - -export function readWebuiAvatarSettings(): WebuiAvatarSettings { - return { - userAvatarUrl: getWebuiConfig("userAvatarUrl") ?? "", - agentAvatarUrl: getWebuiConfig("agentAvatarUrl") ?? "", - }; -} - -export function writeWebuiAvatarSettings(settings: WebuiAvatarSettings): void { - setWebuiConfigMany({ - userAvatarUrl: settings.userAvatarUrl, - agentAvatarUrl: settings.agentAvatarUrl, - }); -} - -export function closeWebuiDatabase(): void { - if (db?.isOpen) { - db.close(); - db = null; - } -} - -export function getWebuiDatabasePath(): string | null { - return db?.location() ?? null; -} - -const PINNED_SESSIONS_CONFIG_KEY = "pinnedSessionPaths"; - -export function readPinnedSessionPaths(): string[] { - const raw = getWebuiConfig(PINNED_SESSIONS_CONFIG_KEY); - if (!raw) return []; - try { - const parsed = JSON.parse(raw) as unknown; - if (!Array.isArray(parsed)) return []; - return parsed.filter((entry): entry is string => typeof entry === "string" && entry.trim().length > 0); - } catch { - return []; - } -} - -function writePinnedSessionPaths(paths: string[]): void { - const unique: string[] = []; - for (const path of paths) { - if (!unique.includes(path)) unique.push(path); - } - setWebuiConfig(PINNED_SESSIONS_CONFIG_KEY, JSON.stringify(unique)); -} - -export function prunePinnedSessionPaths(validPaths: Iterable): string[] { - const valid = new Set(validPaths); - const current = readPinnedSessionPaths(); - const pruned = current.filter((path) => valid.has(path)); - if (pruned.length !== current.length) { - writePinnedSessionPaths(pruned); - } - return pruned; -} - -export function pinSessionPath(path: string): string[] { - const current = readPinnedSessionPaths(); - if (current.includes(path)) return current; - writePinnedSessionPaths([path, ...current]); - return readPinnedSessionPaths(); -} - -export function unpinSessionPath(path: string): string[] { - const next = readPinnedSessionPaths().filter((entry) => entry !== path); - writePinnedSessionPaths(next); - return next; -} - -export function removePinnedSessionPath(path: string): void { - if (readPinnedSessionPaths().includes(path)) { - unpinSessionPath(path); - } -} - -export function setSessionPinned(path: string, pinned: boolean): string[] { - return pinned ? pinSessionPath(path) : unpinSessionPath(path); -} diff --git a/.pi/agent/extensions/webui/backend/http/cors.ts b/.pi/agent/extensions/webui/backend/http/cors.ts deleted file mode 100644 index d508c596..00000000 --- a/.pi/agent/extensions/webui/backend/http/cors.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { IncomingMessage, ServerResponse } from "node:http"; - -/** CORS for desktop / cross-origin clients (e.g. frontend/dist-desketop loading local static files). */ -export function applyCorsHeaders(req: IncomingMessage, res: ServerResponse): boolean { - const origin = typeof req.headers.origin === "string" ? req.headers.origin : ""; - res.setHeader("Access-Control-Allow-Origin", origin || "*"); - res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); - res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); - res.setHeader("Access-Control-Max-Age", "86400"); - if (req.method === "OPTIONS") { - res.writeHead(204); - res.end(); - return true; - } - return false; -} diff --git a/.pi/agent/extensions/webui/backend/http/request.ts b/.pi/agent/extensions/webui/backend/http/request.ts deleted file mode 100644 index 2b483b9e..00000000 --- a/.pi/agent/extensions/webui/backend/http/request.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { IncomingMessage, ServerResponse } from "node:http"; - -export function json(res: ServerResponse, data: unknown, status = 200): void { - res.writeHead(status, { "Content-Type": "application/json" }); - res.end(JSON.stringify(data)); -} - -export function readBody(req: IncomingMessage): Promise> { - return new Promise((resolve, reject) => { - let body = ""; - req.on("data", (chunk: Buffer) => { - body += chunk.toString(); - }); - req.on("end", () => { - try { - resolve(JSON.parse(body)); - } catch { - reject(new Error("无效 JSON")); - } - }); - req.on("error", reject); - }); -} diff --git a/.pi/agent/extensions/webui/backend/http/server.ts b/.pi/agent/extensions/webui/backend/http/server.ts deleted file mode 100644 index 956e471e..00000000 --- a/.pi/agent/extensions/webui/backend/http/server.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { createServer, type IncomingMessage, type ServerResponse } from "node:http"; -import { applyCorsHeaders } from "./cors.ts"; -import { serveStatic } from "./static.ts"; -import { handleChatRoute } from "../routes/chat.ts"; -import { handleExtensionUiRoute } from "../routes/extension-ui.ts"; -import { handleCommandsRoute } from "../routes/commands.ts"; -import { handleModelsRoute } from "../routes/models.ts"; -import { handleSessionsRoute } from "../routes/sessions.ts"; -import { handleSettingsRoute } from "../routes/settings.ts"; -import { handleWebuiConfigRoute } from "../routes/webui-config.ts"; -import type { WebUiContext } from "../types/context.ts"; - -export function createWebUiServer(ctx: WebUiContext) { - return createServer((req: IncomingMessage, res: ServerResponse) => { - const url = new URL(req.url!, `http://localhost:${ctx.config.port}`); - const pathname = url.pathname; - - if (pathname.startsWith("/api/") && applyCorsHeaders(req, res)) { - return; - } - - if (req.method === "GET" && !pathname.startsWith("/api/")) { - serveStatic(ctx.config.paths.publicDir, pathname, req, res, true); - return; - } - - if (handleChatRoute(req, res, ctx, pathname)) return; - if (handleExtensionUiRoute(req, res, ctx, pathname)) return; - if (handleSessionsRoute(req, res, ctx, pathname)) return; - if (handleModelsRoute(req, res, ctx, pathname)) return; - if (handleWebuiConfigRoute(req, res, ctx, pathname, url)) return; - if (handleSettingsRoute(req, res, ctx, pathname)) return; - if (handleCommandsRoute(req, res, ctx, pathname)) return; - - res.writeHead(404); - res.end("Not found"); - }); -} diff --git a/.pi/agent/extensions/webui/backend/http/static.ts b/.pi/agent/extensions/webui/backend/http/static.ts deleted file mode 100644 index 40c11453..00000000 --- a/.pi/agent/extensions/webui/backend/http/static.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { existsSync, readFileSync } from "node:fs"; -import { join, resolve } from "node:path"; -import { gzipSync } from "node:zlib"; -import type { ServerResponse, IncomingMessage } from "node:http"; -import { isPathInsideRoot } from "../utils/paths.ts"; - -const MIME: Record = { - ".html": "text/html; charset=utf-8", - ".js": "application/javascript; charset=utf-8", - ".css": "text/css; charset=utf-8", - ".png": "image/png", - ".svg": "image/svg+xml", - ".woff2": "font/woff2", - ".woff": "font/woff", - ".ico": "image/x-icon", - ".webmanifest": "application/manifest+json", - ".json": "application/json", -}; - -const GZIPABLE = new Set([".html", ".js", ".css", ".json", ".webmanifest"]); - -// Vite build outputs hashed filenames like index-DeT2iZAf.js -const HASHED_FILE_RE = /-[A-Za-z0-9_-]{6,}\.\w+$/; - -function getCacheControl(file: string): string | undefined { - if (file === "/index.html") { - return "no-cache"; - } - if (HASHED_FILE_RE.test(file) || file.endsWith(".woff2") || file.endsWith(".woff")) { - return "public, max-age=31536000, immutable"; - } - return undefined; -} - -export function serveStatic( - publicDir: string, - urlPath: string, - req: IncomingMessage, - res: ServerResponse, - spaFallback = false, -): void { - const file = urlPath === "/" ? "/index.html" : urlPath; - const full = join(publicDir, file); - const resolvedPublic = resolve(publicDir); - const resolvedFull = resolve(full); - if (!isPathInsideRoot(resolvedPublic, resolvedFull) && resolvedFull !== resolvedPublic) { - res.writeHead(403); - res.end("Forbidden"); - return; - } - if (!existsSync(full)) { - if (spaFallback && !urlPath.includes(".")) { - serveStatic(publicDir, "/index.html", req, res, false); - return; - } - res.writeHead(404); - res.end("Not found"); - return; - } - const ext = file.match(/\.\w+$/)?.[0] || ".html"; - const mimeType = MIME[ext] || "application/octet-stream"; - const content = readFileSync(full); - - const headers: Record = { - "Content-Type": mimeType, - }; - - const cacheControl = getCacheControl(file); - if (cacheControl) { - headers["Cache-Control"] = cacheControl; - } - - const acceptEncoding = req.headers["accept-encoding"] || ""; - const shouldGzip = GZIPABLE.has(ext) && acceptEncoding.includes("gzip"); - - if (shouldGzip) { - const compressed = gzipSync(content); - headers["Content-Encoding"] = "gzip"; - res.writeHead(200, headers); - res.end(compressed); - return; - } - - res.writeHead(200, headers); - res.end(content); -} diff --git a/.pi/agent/extensions/webui/backend/main.ts b/.pi/agent/extensions/webui/backend/main.ts deleted file mode 100644 index 7768abbd..00000000 --- a/.pi/agent/extensions/webui/backend/main.ts +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env node - -/** - * pi-mono WebUI Server - * - * 被 webui 扩展启动,作为独立子进程运行。 - * 内嵌 HTTP 服务 + pi RPC 子进程,提供浏览器聊天界面。 - * - * 用法(由扩展自动调用): - * tsx backend/main.ts --port 19133 - * - * 前端静态文件位于 frontend/dist/ 下(Vite 构建产物)。 - */ - -import { existsSync, unlinkSync, writeFileSync } from "node:fs"; -import { arch, hostname, platform, release, type } from "node:os"; -import { parsePort } from "./config/cli.ts"; -import { createWebUiPaths } from "./config/paths.ts"; -import { closeWebuiDatabase, initWebuiDatabase } from "./db/index.ts"; -import { createWebUiServer } from "./http/server.ts"; -import { createPiClient } from "./rpc/pi-client.ts"; -import type { WebUiContext } from "./types/context.ts"; - -const paths = createWebUiPaths(); -const port = parsePort(); - -function writePidFile(): void { - try { - writeFileSync(paths.pidFile, String(process.pid), "utf8"); - } catch { - /* ignore */ - } -} - -function clearPidFile(): void { - try { - if (existsSync(paths.pidFile)) unlinkSync(paths.pidFile); - } catch { - /* ignore */ - } -} - -function shutdown(exitCode = 0): never { - closeWebuiDatabase(); - clearPidFile(); - process.exit(exitCode); -} - -const webuiDb = initWebuiDatabase(paths.extensionRoot); -console.log(`[webui] 配置数据库: ${webuiDb.dbPath}`); -console.log(`[webui] 运行环境: Node.js ${process.version} | ${type()} ${release()} (${platform()}/${arch()}) | 主机: ${hostname()}`); - -process.on("SIGTERM", () => shutdown(0)); -process.on("SIGINT", () => shutdown(0)); -writePidFile(); - -const piClient = createPiClient(paths, (code) => { - if (code !== 0 && code !== null) { - console.error(`[webui] pi RPC 进程异常退出 (code=${code}),WebUI 即将关闭`); - setTimeout(() => shutdown(1), 500); - return; - } - shutdown(1); -}); - -const ctx: WebUiContext = { - config: { paths, port }, - rpc: { - sendCmd: piClient.sendCmd, - submitPrompt: piClient.submitPrompt, - sendExtensionUiResponse: piClient.sendExtensionUiResponse, - getRunSnapshot: piClient.getRunSnapshot, - connectSseClient: piClient.connectSseClient, - removeSseClient: piClient.removeSseClient, - }, - db: webuiDb, -}; - -const server = createWebUiServer(ctx); - -server.on("error", (err: NodeJS.ErrnoException) => { - if (err.code === "EADDRINUSE") { - console.error(`[webui] 端口 ${port} 已被占用`); - } else { - console.error(`[webui] HTTP 服务启动失败: ${err.message}`); - } - process.exit(1); -}); - -server.listen(port, "0.0.0.0", () => { - console.log(`[webui] HTTP 服务已启动: http://localhost:${port}`); - console.log(`[webui] 局域网访问: http://${hostname()}:${port}`); -}); diff --git a/.pi/agent/extensions/webui/backend/routes/chat.ts b/.pi/agent/extensions/webui/backend/routes/chat.ts deleted file mode 100644 index 9806cca0..00000000 --- a/.pi/agent/extensions/webui/backend/routes/chat.ts +++ /dev/null @@ -1,128 +0,0 @@ -import type { IncomingMessage, ServerResponse } from "node:http"; -import { dispatchSlashCommand } from "../slash/dispatch.ts"; -import { normalizeChatImages } from "../services/chat-images.ts"; -import type { WebUiContext } from "../types/context.ts"; -import { json, readBody } from "../http/request.ts"; - -async function trySlashDispatch( - msg: string, - imgs: ReturnType, - sendCmd: WebUiContext["rpc"]["sendCmd"], -): Promise> | null> { - const trimmed = msg.trim(); - if (!trimmed.startsWith("/")) return null; - const slash = await dispatchSlashCommand(trimmed, sendCmd); - return slash?.handled ? slash : null; -} - -export function handleChatRoute( - req: IncomingMessage, - res: ServerResponse, - ctx: WebUiContext, - pathname: string, -): boolean { - const { sendCmd, submitPrompt } = ctx.rpc; - - if (req.method === "POST" && pathname === "/api/chat") { - void readBody(req) - .then(async ({ message, images, streamingBehavior }) => { - const msg = typeof message === "string" ? message : ""; - const imgs = normalizeChatImages(images); - if (!msg.trim() && !imgs?.length) throw new Error("消息不能为空"); - if (imgs?.length) console.log(`[webui] chat: ${imgs.length} image(s), message=${msg.length} chars`); - - const slash = await trySlashDispatch(msg, imgs, sendCmd); - if (slash) { - return json(res, { ok: true, slash: true, ...slash }); - } - - const behavior = - streamingBehavior === "steer" || streamingBehavior === "followUp" - ? streamingBehavior - : undefined; - submitPrompt({ message: msg, images: imgs, streamingBehavior: behavior }); - return json(res, { ok: true, accepted: true }, 202); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/steer") { - void readBody(req) - .then(async ({ message, images }) => { - const msg = typeof message === "string" ? message.trim() : ""; - const imgs = normalizeChatImages(images); - if (!msg && !imgs?.length) throw new Error("消息不能为空"); - const result = await sendCmd({ type: "steer", message: msg, images: imgs }); - if (!result.success) throw new Error(result.error || "steer 失败"); - json(res, { ok: true }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/follow-up") { - void readBody(req) - .then(async ({ message, images }) => { - const msg = typeof message === "string" ? message.trim() : ""; - const imgs = normalizeChatImages(images); - if (!msg && !imgs?.length) throw new Error("消息不能为空"); - const result = await sendCmd({ type: "follow_up", message: msg, images: imgs }); - if (!result.success) throw new Error(result.error || "follow_up 失败"); - json(res, { ok: true }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/bash") { - void readBody(req) - .then(async ({ command, excludeFromContext }) => { - const cmd = typeof command === "string" ? command.trim() : ""; - if (!cmd) throw new Error("命令不能为空"); - const result = await sendCmd({ - type: "bash", - command: cmd, - excludeFromContext: excludeFromContext === true, - }); - if (!result.success) throw new Error(result.error || "命令执行失败"); - json(res, result.data); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "GET" && pathname === "/api/events") { - res.writeHead(200, { - "Content-Type": "text/event-stream", - "Cache-Control": "no-cache", - Connection: "keep-alive", - }); - ctx.rpc.connectSseClient(res); - req.on("close", () => ctx.rpc.removeSseClient(res)); - return true; - } - - if (req.method === "POST" && pathname === "/api/messages") { - void sendCmd({ type: "get_messages" }) - .then((r: any) => (r.success ? json(res, r.data) : json(res, { error: r.error }, 500))) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/abort") { - void sendCmd({ type: "abort" }) - .then(() => json(res, { ok: true })) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/abort-retry") { - void sendCmd({ type: "abort_retry" }) - .then(() => json(res, { ok: true })) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - return false; -} diff --git a/.pi/agent/extensions/webui/backend/routes/commands.ts b/.pi/agent/extensions/webui/backend/routes/commands.ts deleted file mode 100644 index 3d071231..00000000 --- a/.pi/agent/extensions/webui/backend/routes/commands.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { IncomingMessage, ServerResponse } from "node:http"; -import { listSlashCommands } from "../services/slash-commands.ts"; -import type { WebUiContext } from "../types/context.ts"; -import { json } from "../http/request.ts"; - -export function handleCommandsRoute( - req: IncomingMessage, - res: ServerResponse, - ctx: WebUiContext, - pathname: string, -): boolean { - if (req.method === "GET" && pathname === "/api/commands") { - void listSlashCommands(ctx.rpc.sendCmd) - .then((commands) => json(res, { commands })) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - return false; -} diff --git a/.pi/agent/extensions/webui/backend/routes/extension-ui.ts b/.pi/agent/extensions/webui/backend/routes/extension-ui.ts deleted file mode 100644 index 2e84e1af..00000000 --- a/.pi/agent/extensions/webui/backend/routes/extension-ui.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { IncomingMessage, ServerResponse } from "node:http"; -import type { WebUiContext } from "../types/context.ts"; -import { json, readBody } from "../http/request.ts"; - -export function handleExtensionUiRoute( - req: IncomingMessage, - res: ServerResponse, - ctx: WebUiContext, - pathname: string, -): boolean { - if (req.method !== "POST" || pathname !== "/api/extension-ui-response") { - return false; - } - - void readBody(req) - .then(({ id, response }) => { - if (typeof id !== "string" || !id.trim()) throw new Error("缺少 extension UI 响应 id"); - if (!response || typeof response !== "object") throw new Error("缺少 extension UI 响应内容"); - ctx.rpc.sendExtensionUiResponse(id, response as Record); - json(res, { ok: true }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - - return true; -} diff --git a/.pi/agent/extensions/webui/backend/routes/models.ts b/.pi/agent/extensions/webui/backend/routes/models.ts deleted file mode 100644 index e4fe5932..00000000 --- a/.pi/agent/extensions/webui/backend/routes/models.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { IncomingMessage, ServerResponse } from "node:http"; -import type { WebUiContext } from "../types/context.ts"; -import { json, readBody } from "../http/request.ts"; - -export function handleModelsRoute( - req: IncomingMessage, - res: ServerResponse, - ctx: WebUiContext, - pathname: string, -): boolean { - const { sendCmd } = ctx.rpc; - - if (req.method === "GET" && pathname === "/api/models") { - void sendCmd({ type: "get_available_models" }) - .then((r: any) => (r.success ? json(res, r.data) : json(res, { error: r.error }, 500))) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/model") { - void readBody(req) - .then(({ provider, modelId }) => - sendCmd({ type: "set_model", provider, modelId }).then((r: any) => - r.success ? json(res, { model: r.data }) : json(res, { error: r.error }, 500), - ), - ) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/thinking") { - void readBody(req) - .then(({ level }) => - sendCmd({ type: "set_thinking_level", level }).then((r: any) => - r.success ? json(res, { ok: true }) : json(res, { error: r.error }, 500), - ), - ) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - return false; -} diff --git a/.pi/agent/extensions/webui/backend/routes/sessions.ts b/.pi/agent/extensions/webui/backend/routes/sessions.ts deleted file mode 100644 index 77e63e48..00000000 --- a/.pi/agent/extensions/webui/backend/routes/sessions.ts +++ /dev/null @@ -1,129 +0,0 @@ -import type { IncomingMessage, ServerResponse } from "node:http"; -import { - appendSessionName, - buildSessionListResponse, - deleteSessionFile, - pinSession, - readSessionMessages, - readSessionSummary, - resolveSessionFile, -} from "../services/sessions.ts"; -import type { WebUiContext } from "../types/context.ts"; -import { isSameResolvedPath } from "../utils/paths.ts"; -import { json, readBody } from "../http/request.ts"; - -export function handleSessionsRoute( - req: IncomingMessage, - res: ServerResponse, - ctx: WebUiContext, - pathname: string, -): boolean { - const { paths } = ctx.config; - const { sendCmd } = ctx.rpc; - - if (req.method === "POST" && pathname === "/api/new-session") { - void sendCmd({ type: "new_session" }) - .then(async (r: any) => { - if (!r.success) return json(res, { error: r.error }, 500); - if (r.data?.cancelled) return json(res, r.data); - const state = await sendCmd({ type: "get_state" }); - const sessionFile = state.success ? state.data?.sessionFile : undefined; - return json(res, { ...r.data, sessionFile }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "GET" && pathname === "/api/sessions") { - json(res, buildSessionListResponse(paths)); - return true; - } - - if (req.method === "POST" && pathname === "/api/sessions/history") { - void readBody(req) - .then(({ path: sp }) => { - const messages = readSessionMessages(sp as string); - const summary = readSessionSummary(paths, sp as string); - json(res, { messages, session: summary }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/sessions/delete") { - void readBody(req) - .then(({ path: sp }) => { - deleteSessionFile(paths, sp as string); - json(res, { ok: true }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/sessions/pin") { - void readBody(req) - .then(({ path: sp, pinned }) => { - const result = pinSession(paths, sp as string, Boolean(pinned)); - json(res, { ok: true, ...result }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/sessions/load") { - void readBody(req) - .then(async ({ path: sp }) => { - const sw = await sendCmd({ type: "switch_session", sessionPath: sp, cwdOverride: paths.repoRoot }); - if (!sw.success) throw new Error(sw.error); - const mr = await sendCmd({ type: "get_messages" }); - if (!mr.success) throw new Error(mr.error); - const summary = readSessionSummary(paths, sp as string); - json(res, { messages: mr.data.messages, session: summary }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/sessions/activate") { - void readBody(req) - .then(async ({ path: sp }) => { - const sw = await sendCmd({ type: "switch_session", sessionPath: sp, cwdOverride: paths.repoRoot }); - if (!sw.success) throw new Error(sw.error); - const state = await sendCmd({ type: "get_state" }); - if (!state.success) throw new Error(state.error); - json(res, { ok: true, state: state.data }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/sessions/name") { - void readBody(req) - .then(async ({ path: sp, name }) => { - if (typeof sp !== "string" || !sp.trim()) throw new Error("无效会话路径"); - const savedName = appendSessionName(paths, sp, typeof name === "string" ? name : ""); - const sessionPath = resolveSessionFile(paths, sp); - const state = await sendCmd({ type: "get_state" }); - if ( - state.success && - state.data?.sessionFile && - isSameResolvedPath(String(state.data.sessionFile), sessionPath) - ) { - const rename = await sendCmd({ type: "set_session_name", name: savedName }); - if (!rename.success) throw new Error(rename.error || "同步当前会话名称失败"); - } - json(res, { ok: true, name: savedName }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "GET" && pathname === "/api/session-state") { - void sendCmd({ type: "get_state" }) - .then((r: any) => (r.success ? json(res, r.data) : json(res, { error: r.error }, 500))) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - return false; -} diff --git a/.pi/agent/extensions/webui/backend/routes/settings.ts b/.pi/agent/extensions/webui/backend/routes/settings.ts deleted file mode 100644 index feda8226..00000000 --- a/.pi/agent/extensions/webui/backend/routes/settings.ts +++ /dev/null @@ -1,225 +0,0 @@ -import type { IncomingMessage, ServerResponse } from "node:http"; -import { arch, freemem, hostname, platform, release, totalmem, type as osType } from "node:os"; -import { readWebuiAvatarSettings, writeWebuiAvatarSettings } from "../db/index.ts"; -import { setExtensionEnabled } from "../settings/extension-settings.ts"; -import { listMcpSettings, setMcpServerEnabled, setMcpToolEnabled } from "../settings/mcp-settings.ts"; -import { listSkillSettings, setSkillEnabled } from "../settings/skills-settings.ts"; -import { normalizeAvatarUrl } from "../services/avatars.ts"; -import { - listExtensionsForSettings, - listLoadedExtensionsByPath, - mergeExtensionToggleResponse, -} from "../services/extensions-display.ts"; -import { readModelsConfig, writeModelsConfig } from "../services/models-config.ts"; -import { readSystemPrompt, writeSystemPrompt } from "../services/system-prompt.ts"; -import type { WebUiContext } from "../types/context.ts"; -import { json, readBody } from "../http/request.ts"; - -function listMcpTools(ctx: WebUiContext): Record[] { - return listMcpSettings(ctx.config.paths.mcpConfigFile, ctx.config.paths.mcpCacheFile); -} - -export function handleSettingsRoute( - req: IncomingMessage, - res: ServerResponse, - ctx: WebUiContext, - pathname: string, -): boolean { - const { paths } = ctx.config; - const { sendCmd } = ctx.rpc; - - if (req.method === "GET" && pathname === "/api/settings") { - void listSkillSettings(paths.repoRoot, paths.agentDir) - .then((skills) => - listExtensionsForSettings(paths, sendCmd).then((extensions) => - json(res, { - ...readWebuiAvatarSettings(), - webuiDbPath: ctx.db.dbPath, - systemPrompt: readSystemPrompt(paths), - systemPromptPath: paths.systemPromptFile, - modelsConfig: readModelsConfig(paths), - modelsConfigPath: paths.modelsConfigFile, - extensionsPath: paths.agentExtensionsDir, - mcpCachePath: paths.mcpCacheFile, - mcpConfigPath: paths.mcpConfigFile, - skills, - extensions, - mcpTools: listMcpTools(ctx), - }), - ), - ) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/settings/skills/toggle") { - void readBody(req) - .then(async ({ path: skillPath, enabled }) => { - if (typeof skillPath !== "string" || !skillPath.trim()) { - throw new Error("skill path 无效"); - } - if (typeof enabled !== "boolean") { - throw new Error("enabled 必须是 boolean"); - } - const skill = await setSkillEnabled(paths.repoRoot, paths.agentDir, skillPath.trim(), enabled); - const reload = await sendCmd({ type: "reload" }); - if (!reload.success) throw new Error(reload.error || "Agent 重新加载失败"); - json(res, { ok: true, skill }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/settings/extensions/toggle") { - void readBody(req) - .then(async ({ path: extensionPath, enabled }) => { - if (typeof extensionPath !== "string" || !extensionPath.trim()) { - throw new Error("extension path 无效"); - } - if (typeof enabled !== "boolean") { - throw new Error("enabled 必须是 boolean"); - } - const extension = await setExtensionEnabled( - paths.repoRoot, - paths.agentDir, - extensionPath.trim(), - enabled, - ); - const reload = await sendCmd({ type: "reload" }); - if (!reload.success) throw new Error(reload.error || "Agent 重新加载失败"); - let loadedByPath = new Map(); - try { - loadedByPath = await listLoadedExtensionsByPath(paths, sendCmd); - } catch { - /* ignore */ - } - json(res, { - ok: true, - extension: mergeExtensionToggleResponse(paths, extension, loadedByPath), - }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/settings/mcp/server/toggle") { - void readBody(req) - .then(async ({ server, enabled }) => { - if (typeof server !== "string" || !server.trim()) { - throw new Error("server 名称无效"); - } - if (typeof enabled !== "boolean") { - throw new Error("enabled 必须是 boolean"); - } - const entry = setMcpServerEnabled( - paths.mcpConfigFile, - paths.mcpCacheFile, - server.trim(), - enabled, - ); - const reload = await sendCmd({ type: "reload" }); - if (!reload.success) throw new Error(reload.error || "Agent 重新加载失败"); - json(res, { ok: true, server: entry }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/settings/mcp/tool/toggle") { - void readBody(req) - .then(async ({ server, tool, enabled }) => { - if (typeof server !== "string" || !server.trim()) { - throw new Error("server 名称无效"); - } - if (typeof tool !== "string" || !tool.trim()) { - throw new Error("tool 名称无效"); - } - if (typeof enabled !== "boolean") { - throw new Error("enabled 必须是 boolean"); - } - const entry = setMcpToolEnabled( - paths.mcpConfigFile, - paths.mcpCacheFile, - server.trim(), - tool.trim(), - enabled, - ); - const reload = await sendCmd({ type: "reload" }); - if (!reload.success) throw new Error(reload.error || "Agent 重新加载失败"); - json(res, { ok: true, tool: entry }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/settings/reload") { - void sendCmd({ type: "reload" }) - .then((r: any) => (r.success ? json(res, { ok: true }) : json(res, { error: r.error }, 500))) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/settings/models-config") { - void readBody(req) - .then(async ({ modelsConfig }) => { - if (typeof modelsConfig !== "string") { - throw new Error("modelsConfig 必须是字符串"); - } - writeModelsConfig(paths, modelsConfig); - const reload = await sendCmd({ type: "reload" }); - if (!reload.success) throw new Error(reload.error || "Agent 重新加载失败"); - json(res, { ok: true, modelsConfigPath: paths.modelsConfigFile }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/settings/system-prompt") { - void readBody(req) - .then(async ({ systemPrompt }) => { - if (typeof systemPrompt !== "string") { - throw new Error("systemPrompt 必须是字符串"); - } - writeSystemPrompt(paths, systemPrompt); - const reload = await sendCmd({ type: "reload" }); - if (!reload.success) throw new Error(reload.error || "Agent 重新加载失败"); - json(res, { ok: true, systemPromptPath: paths.systemPromptFile }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/settings/avatars") { - void readBody(req) - .then(({ userAvatarUrl, agentAvatarUrl }) => { - const settings = { - userAvatarUrl: normalizeAvatarUrl(userAvatarUrl), - agentAvatarUrl: normalizeAvatarUrl(agentAvatarUrl), - }; - writeWebuiAvatarSettings(settings); - json(res, { ok: true, ...settings }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "GET" && pathname === "/api/environment") { - json(res, { - nodeVersion: process.version, - platform: platform(), - arch: arch(), - osType: osType(), - osRelease: release(), - hostname: hostname(), - pid: process.pid, - cwd: process.cwd(), - uptime: Math.floor(process.uptime()), - totalMemMb: Math.round(totalmem() / 1024 / 1024), - freeMemMb: Math.round(freemem() / 1024 / 1024), - execPath: process.execPath, - }); - return true; - } - - return false; -} diff --git a/.pi/agent/extensions/webui/backend/routes/webui-config.ts b/.pi/agent/extensions/webui/backend/routes/webui-config.ts deleted file mode 100644 index c21282e2..00000000 --- a/.pi/agent/extensions/webui/backend/routes/webui-config.ts +++ /dev/null @@ -1,70 +0,0 @@ -import type { IncomingMessage, ServerResponse } from "node:http"; -import { - deleteWebuiConfig, - getAllWebuiConfig, - getWebuiConfig, - readWebuiAvatarSettings, - setWebuiConfig, - setWebuiConfigMany, -} from "../db/index.ts"; -import { normalizeConfigKey, normalizeConfigValue } from "../services/avatars.ts"; -import type { WebUiContext } from "../types/context.ts"; -import { json, readBody } from "../http/request.ts"; - -export function handleWebuiConfigRoute( - req: IncomingMessage, - res: ServerResponse, - ctx: WebUiContext, - pathname: string, - url: URL, -): boolean { - if (req.method === "GET" && pathname === "/api/avatars") { - json(res, readWebuiAvatarSettings()); - return true; - } - - if (req.method === "GET" && pathname === "/api/webui/config") { - const key = url.searchParams.get("key"); - if (key) { - const normalized = normalizeConfigKey(key); - json(res, { key: normalized, value: getWebuiConfig(normalized) }); - return true; - } - json(res, { config: getAllWebuiConfig(), dbPath: ctx.db.dbPath }); - return true; - } - - if (req.method === "POST" && pathname === "/api/webui/config") { - void readBody(req) - .then(({ key, value, entries }) => { - if (entries && typeof entries === "object" && !Array.isArray(entries)) { - const normalized: Record = {}; - for (const [rawKey, rawValue] of Object.entries(entries as Record)) { - normalized[normalizeConfigKey(rawKey)] = normalizeConfigValue(rawValue); - } - setWebuiConfigMany(normalized); - return json(res, { ok: true, config: getAllWebuiConfig() }); - } - if (typeof key !== "string") throw new Error("缺少配置键 key"); - const normalizedKey = normalizeConfigKey(key); - const normalizedValue = normalizeConfigValue(value); - setWebuiConfig(normalizedKey, normalizedValue); - return json(res, { ok: true, key: normalizedKey, value: normalizedValue }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - if (req.method === "POST" && pathname === "/api/webui/config/delete") { - void readBody(req) - .then(({ key }) => { - const normalized = normalizeConfigKey(key); - const deleted = deleteWebuiConfig(normalized); - json(res, { ok: true, deleted, key: normalized }); - }) - .catch((err) => json(res, { error: err.message }, 500)); - return true; - } - - return false; -} diff --git a/.pi/agent/extensions/webui/backend/rpc/pi-client.ts b/.pi/agent/extensions/webui/backend/rpc/pi-client.ts deleted file mode 100644 index 6ef0007f..00000000 --- a/.pi/agent/extensions/webui/backend/rpc/pi-client.ts +++ /dev/null @@ -1,242 +0,0 @@ -import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process"; -import type { ServerResponse } from "node:http"; -import { resolvePiRpcLaunch, type WebUiPaths } from "../config/paths.ts"; -import type { RunSnapshot, SendCmd, SubmitPromptOptions } from "../types/context.ts"; - -export interface PiClient { - sendCmd: SendCmd; - submitPrompt: (options: SubmitPromptOptions) => void; - sendExtensionUiResponse: (id: string, response: Record) => void; - getRunSnapshot: () => RunSnapshot; - connectSseClient: (res: ServerResponse) => void; - removeSseClient: (res: ServerResponse) => void; - child: ChildProcessWithoutNullStreams; -} - -const BUFFERED_EVENT_TYPES = new Set([ - "agent_start", - "agent_end", - "message_start", - "message_update", - "message_end", - "tool_execution_start", - "tool_execution_update", - "tool_execution_end", - "compaction_start", - "compaction_end", - "queue_update", - "auto_retry_start", - "auto_retry_end", - "bash_update", -]); - -const DEFAULT_CMD_TIMEOUT_MS = 60_000; -const PROMPT_PREFLIGHT_TIMEOUT_MS = 30_000; -const PI_STDERR_BUFFER_MAX = 8192; - -function formatSpawnArgs(args: string[]): string { - return args.map((arg) => JSON.stringify(arg)).join(" "); -} - -function summarizeStderr(buffer: string): string { - const trimmed = buffer.trim(); - if (!trimmed) return "(无 stderr 输出)"; - const lines = trimmed.split(/\r?\n/).filter(Boolean); - return lines.slice(-8).join("\n"); -} - -export function createPiClient(paths: WebUiPaths, onExit: (code: number | null) => void): PiClient { - const piLaunch = resolvePiRpcLaunch(paths); - console.log( - `[webui] 启动 pi RPC (${piLaunch.mode}): ${piLaunch.command} ${formatSpawnArgs(piLaunch.args)}`, - ); - - const pi = spawn(piLaunch.command, piLaunch.args, { - cwd: paths.repoRoot, - stdio: ["pipe", "pipe", "pipe"], - env: { - ...process.env, - PI_CODING_AGENT_DIR: paths.agentDir, - }, - }); - - // Keep stdin pipe open; closing it on Windows can trigger RPC shutdown via stdin "end". - pi.stdin.write(""); - - let stderrBuffer = ""; - pi.stderr.on("data", (data: Buffer) => { - const chunk = data.toString(); - stderrBuffer = (stderrBuffer + chunk).slice(-PI_STDERR_BUFFER_MAX); - process.stderr.write(`[pi] ${data}`); - }); - pi.on("exit", (code) => { - console.log(`[webui] pi 退出, code=${code}`); - if (code !== 0 && code !== null) { - console.error(`[webui] pi RPC 启动失败 (code=${code}):\n${summarizeStderr(stderrBuffer)}`); - } - onExit(code); - }); - - let buffer = ""; - const pending = new Map void; reject: (error: Error) => void }>(); - const sseClients = new Set(); - let reqId = 0; - - let isStreaming = false; - let sessionFile: string | undefined; - let turnEventBuffer: Record[] = []; - - function getRunSnapshot(): RunSnapshot { - return { - isStreaming, - sessionFile, - replay: [...turnEventBuffer], - }; - } - - function broadcastSse(msg: Record): void { - const data = `data: ${JSON.stringify(msg)}\n\n`; - for (const res of sseClients) res.write(data); - } - - function trackAgentEvent(msg: Record): void { - const type = msg.type; - if (typeof type !== "string") return; - - if (type === "agent_start") { - isStreaming = true; - turnEventBuffer = [msg]; - return; - } - - if (type === "agent_end") { - turnEventBuffer.push(msg); - isStreaming = false; - turnEventBuffer = []; - return; - } - - if (isStreaming && BUFFERED_EVENT_TYPES.has(type)) { - turnEventBuffer.push(msg); - } - } - - function registerPending( - id: string, - handlers: { resolve: (value: any) => void; reject: (error: Error) => void }, - timeoutMs: number, - timeoutLabel: string, - ): void { - pending.set(id, handlers); - setTimeout(() => { - if (!pending.has(id)) return; - pending.delete(id); - handlers.reject(new Error(`命令超时: ${timeoutLabel}`)); - }, timeoutMs); - } - - function onLine(line: string): void { - if (!line.trim()) return; - try { - const msg = JSON.parse(line) as Record; - if (msg.type === "response" && msg.id && pending.has(String(msg.id))) { - const id = String(msg.id); - const p = pending.get(id)!; - pending.delete(id); - if (msg.command === "prompt" && msg.success === false) { - broadcastSse({ - type: "prompt_rejected", - error: String(msg.error || "prompt rejected"), - }); - } - if (msg.command === "get_state" && msg.success === true) { - const data = msg.data as { sessionFile?: string } | undefined; - if (data?.sessionFile) { - sessionFile = data.sessionFile; - } - } - p.resolve(msg); - return; - } - trackAgentEvent(msg); - broadcastSse(msg); - } catch { - /* ignore non-JSON lines */ - } - } - - pi.stdout.on("data", (chunk: Buffer) => { - buffer += chunk.toString(); - const lines = buffer.split("\n"); - buffer = lines.pop() || ""; - for (const line of lines) onLine(line); - }); - - const sendCmd: SendCmd = (command) => - new Promise((resolvePromise, reject) => { - const id = `req_${++reqId}`; - const line = JSON.stringify({ ...command, id }) + "\n"; - registerPending( - id, - { resolve: resolvePromise, reject }, - DEFAULT_CMD_TIMEOUT_MS, - String(command.type), - ); - pi.stdin.write(line); - }); - - function submitPrompt(options: SubmitPromptOptions): void { - const id = `req_${++reqId}`; - const payload: Record = { - type: "prompt", - message: options.message, - images: options.images, - id, - }; - if (options.streamingBehavior) { - payload.streamingBehavior = options.streamingBehavior; - } - const line = JSON.stringify(payload) + "\n"; - registerPending( - id, - { - resolve: () => { - /* preflight success: agent events arrive via SSE */ - }, - reject: (err) => { - broadcastSse({ type: "prompt_rejected", error: err.message }); - }, - }, - PROMPT_PREFLIGHT_TIMEOUT_MS, - "prompt", - ); - pi.stdin.write(line); - } - - function sendExtensionUiResponse(id: string, response: Record): void { - const line = JSON.stringify({ type: "extension_ui_response", id, ...response }) + "\n"; - pi.stdin.write(line); - } - - function connectSseClient(res: ServerResponse): void { - const snapshot = getRunSnapshot(); - res.write( - `data: ${JSON.stringify({ - type: "connected", - isStreaming: snapshot.isStreaming, - replay: snapshot.replay, - })}\n\n`, - ); - sseClients.add(res); - } - - return { - sendCmd, - submitPrompt, - sendExtensionUiResponse, - getRunSnapshot, - connectSseClient, - removeSseClient: (res) => sseClients.delete(res), - child: pi, - }; -} diff --git a/.pi/agent/extensions/webui/backend/services/avatars.ts b/.pi/agent/extensions/webui/backend/services/avatars.ts deleted file mode 100644 index 81bed61a..00000000 --- a/.pi/agent/extensions/webui/backend/services/avatars.ts +++ /dev/null @@ -1,32 +0,0 @@ -export function normalizeAvatarUrl(value: unknown): string { - if (typeof value !== "string") return ""; - const url = value.trim(); - if (!url) return ""; - let parsed: URL; - try { - parsed = new URL(url); - } catch { - throw new Error(`无效头像链接: ${url}`); - } - if (parsed.protocol !== "http:" && parsed.protocol !== "https:") { - throw new Error("头像链接仅支持 http 或 https"); - } - return parsed.toString(); -} - -export function normalizeConfigKey(key: unknown): string { - if (typeof key !== "string") throw new Error("配置键必须是字符串"); - const trimmed = key.trim(); - if (!trimmed) throw new Error("配置键不能为空"); - if (trimmed.length > 128) throw new Error("配置键过长"); - if (!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(trimmed)) { - throw new Error("配置键格式无效"); - } - return trimmed; -} - -export function normalizeConfigValue(value: unknown): string { - if (typeof value !== "string") throw new Error("配置值必须是字符串"); - if (value.length > 65536) throw new Error("配置值过长"); - return value; -} diff --git a/.pi/agent/extensions/webui/backend/services/chat-images.ts b/.pi/agent/extensions/webui/backend/services/chat-images.ts deleted file mode 100644 index f29eadb2..00000000 --- a/.pi/agent/extensions/webui/backend/services/chat-images.ts +++ /dev/null @@ -1,24 +0,0 @@ -const ALLOWED_CHAT_IMAGE_MIME = new Set(["image/jpeg", "image/png", "image/gif", "image/webp"]); -const MAX_CHAT_IMAGES = 8; -const MAX_CHAT_IMAGE_BYTES = 10 * 1024 * 1024; - -export function normalizeChatImages( - images: unknown, -): Array<{ type: "image"; data: string; mimeType: string }> | undefined { - if (!Array.isArray(images) || images.length === 0) return undefined; - const out: Array<{ type: "image"; data: string; mimeType: string }> = []; - for (const raw of images.slice(0, MAX_CHAT_IMAGES)) { - if (!raw || typeof raw !== "object") continue; - const mimeType = String((raw as { mimeType?: string }).mimeType || ""); - const data = String((raw as { data?: string }).data || ""); - if ((raw as { type?: string }).type !== "image" || !ALLOWED_CHAT_IMAGE_MIME.has(mimeType) || !data) { - throw new Error(`不支持的图片类型: ${mimeType || "unknown"}`); - } - const size = Buffer.from(data, "base64").length; - if (size > MAX_CHAT_IMAGE_BYTES) { - throw new Error(`图片过大(最大 ${Math.round(MAX_CHAT_IMAGE_BYTES / 1024 / 1024)}MB)`); - } - out.push({ type: "image", mimeType, data }); - } - return out.length ? out : undefined; -} diff --git a/.pi/agent/extensions/webui/backend/services/extensions-display.ts b/.pi/agent/extensions/webui/backend/services/extensions-display.ts deleted file mode 100644 index e37b40e3..00000000 --- a/.pi/agent/extensions/webui/backend/services/extensions-display.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { basename, resolve } from "node:path"; -import type { WebUiPaths } from "../config/paths.ts"; -import type { SendCmd } from "../types/context.ts"; -import { listExtensionSettings, type ExtensionSettingsEntry } from "../settings/extension-settings.ts"; -import { - getExtensionCategoryFromPath, - readConfiguredNpmPackageNames, - readNpmPackageVersion, - resolveNpmSource, -} from "../settings/extensions-paths.ts"; - -function getConfiguredNpmPackages(paths: WebUiPaths): Set { - return readConfiguredNpmPackageNames(paths.agentSettingsFile); -} - -function getExtensionPath(extension: any): string { - return String(extension.path || extension.resolvedPath || ""); -} - -function classifyExtension( - paths: WebUiPaths, - extension: any, - configuredPackages: Set, -): "local" | "npm" | null { - const pathValue = getExtensionPath(extension); - return getExtensionCategoryFromPath( - pathValue, - paths.agentExtensionsDir, - paths.agentNpmNodeModules, - configuredPackages, - ); -} - -function cleanExtensionName(name: string): string { - return basename(name).replace(/\.[cm]?[tj]s$/i, ""); -} - -function displayExtensionName(extensionPath: string, source: string): string { - const sourceMatch = source.match(/^npm:(.+)$/); - if (sourceMatch?.[1]) return sourceMatch[1]; - - const normalized = extensionPath.replace(/\\/g, "/"); - const parts = normalized.split("/").filter(Boolean); - const file = parts[parts.length - 1] || normalized; - if (/^index\.[tj]s$/i.test(file) && parts.length >= 2) { - return cleanExtensionName(parts[parts.length - 2]); - } - return cleanExtensionName(file); -} - -function displayExtensionKind( - scope: string, - source: string, - category: "local" | "npm", - version?: string, -): string { - if (category === "npm") { - const packageName = source.startsWith("npm:") ? source.slice(4) : source; - const base = packageName ? `npm · ${packageName}` : "npm"; - return version ? `${base} · ${version}` : base; - } - const scopeText = scope === "project" ? "项目" : scope === "user" ? "用户" : scope || ""; - if (source === "auto" || source === "local") { - return scopeText ? `${scopeText}本地` : "本地"; - } - return source ? `${scopeText || "未知"} · ${source}` : scopeText || "本地"; -} - -function displayExtensionLocation(repoRoot: string, extensionPath: string, resolvedPath: string): string { - const pathValue = extensionPath || resolvedPath; - if (!pathValue) return ""; - return pathValue.replace(repoRoot, "."); -} - -export function normalizeExtension( - paths: WebUiPaths, - extension: any, - configuredPackages: Set, -): Record { - const sourceInfo = extension.sourceInfo || {}; - const pathValue = getExtensionPath(extension); - const category = classifyExtension(paths, extension, configuredPackages); - const source = - category === "npm" - ? resolveNpmSource(pathValue, paths.agentNpmNodeModules, String(sourceInfo.source || "")) - : String(sourceInfo.source || ""); - const resolvedPath = String(extension.resolvedPath || extension.path || pathValue); - const npmCategory = category === "npm" ? "npm" : "local"; - const version = - category === "npm" - ? readNpmPackageVersion(paths.agentNpmNodeModules, pathValue, source) - : undefined; - return { - name: displayExtensionName(pathValue, source), - rawName: extension.name || "", - path: pathValue, - resolvedPath, - scope: sourceInfo.scope || extension.scope || "", - source, - sourcePath: sourceInfo.path || "", - location: displayExtensionLocation(paths.repoRoot, pathValue, resolvedPath), - version, - kind: displayExtensionKind(sourceInfo.scope || extension.scope, source, npmCategory, version), - category: category || "local", - enabled: extension.enabled !== false, - commands: extension.commands || [], - tools: extension.tools || [], - flags: extension.flags || [], - shortcuts: extension.shortcuts || [], - handlers: extension.handlers || [], - }; -} - -export async function listLoadedExtensionsByPath( - paths: WebUiPaths, - sendCmd: SendCmd, -): Promise> { - const configuredPackages = getConfiguredNpmPackages(paths); - const response = await sendCmd({ type: "get_extensions" }); - if (!response.success) throw new Error(response.error || "读取扩展失败"); - const loadedByPath = new Map(); - for (const extension of response.data?.extensions || []) { - if (classifyExtension(paths, extension, configuredPackages) === null) continue; - const pathValue = getExtensionPath(extension); - loadedByPath.set(resolve(pathValue), extension); - if (extension.resolvedPath) { - loadedByPath.set(resolve(String(extension.resolvedPath)), extension); - } - } - return loadedByPath; -} - -export async function listExtensionsForSettings( - paths: WebUiPaths, - sendCmd: SendCmd, -): Promise[]> { - const configuredPackages = getConfiguredNpmPackages(paths); - const resolved = await listExtensionSettings(paths.repoRoot, paths.agentDir); - let loadedByPath = new Map(); - try { - loadedByPath = await listLoadedExtensionsByPath(paths, sendCmd); - } catch { - /* show resolved extensions even if agent RPC is unavailable */ - } - - return resolved - .map((entry) => { - const loaded = - loadedByPath.get(resolve(entry.path)) || - loadedByPath.get(resolve(entry.resolvedPath || entry.path)); - const merged = loaded - ? { ...loaded, enabled: entry.enabled } - : { - path: entry.path, - resolvedPath: entry.resolvedPath, - sourceInfo: { scope: entry.scope, source: entry.source }, - commands: [], - tools: [], - flags: [], - shortcuts: [], - handlers: [], - enabled: entry.enabled, - }; - return normalizeExtension(paths, merged, configuredPackages); - }) - .sort((a, b) => { - const categoryOrder = a.category === b.category ? 0 : a.category === "local" ? -1 : 1; - if (categoryOrder !== 0) return categoryOrder; - return String(a.name).localeCompare(String(b.name)); - }); -} - -export function mergeExtensionToggleResponse( - paths: WebUiPaths, - extension: ExtensionSettingsEntry, - loadedByPath: Map, -): Record { - const configuredPackages = getConfiguredNpmPackages(paths); - const loaded = - loadedByPath.get(resolve(extension.path)) || - loadedByPath.get(resolve(extension.resolvedPath || extension.path)); - const merged = loaded - ? { ...loaded, enabled: extension.enabled } - : { - path: extension.path, - resolvedPath: extension.resolvedPath, - sourceInfo: { scope: extension.scope, source: extension.source }, - commands: [], - tools: [], - flags: [], - shortcuts: [], - handlers: [], - enabled: extension.enabled, - }; - return normalizeExtension(paths, merged, configuredPackages); -} diff --git a/.pi/agent/extensions/webui/backend/services/models-config.ts b/.pi/agent/extensions/webui/backend/services/models-config.ts deleted file mode 100644 index fe689c9f..00000000 --- a/.pi/agent/extensions/webui/backend/services/models-config.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; -import { dirname } from "node:path"; -import type { WebUiPaths } from "../config/paths.ts"; - -export function readModelsConfig(paths: WebUiPaths): string { - if (!existsSync(paths.modelsConfigFile)) return "{\n \"providers\": {}\n}\n"; - return readFileSync(paths.modelsConfigFile, "utf8"); -} - -export function writeModelsConfig(paths: WebUiPaths, content: string): void { - let parsed: unknown; - try { - parsed = JSON.parse(content); - } catch (err) { - const message = err instanceof Error ? err.message : String(err); - throw new Error(`models.json 不是有效的 JSON: ${message}`); - } - if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) { - throw new Error("models.json 根节点必须是 JSON 对象"); - } - const formatted = `${JSON.stringify(parsed, null, 2)}\n`; - mkdirSync(dirname(paths.modelsConfigFile), { recursive: true }); - writeFileSync(paths.modelsConfigFile, formatted, "utf8"); -} diff --git a/.pi/agent/extensions/webui/backend/services/sessions.ts b/.pi/agent/extensions/webui/backend/services/sessions.ts deleted file mode 100644 index 4677e001..00000000 --- a/.pi/agent/extensions/webui/backend/services/sessions.ts +++ /dev/null @@ -1,257 +0,0 @@ -import { randomUUID } from "node:crypto"; -import { - appendFileSync, - existsSync, - readFileSync, - readdirSync, - statSync, - unlinkSync, -} from "node:fs"; -import { join, resolve } from "node:path"; -import type { WebUiPaths } from "../config/paths.ts"; -import { isPathInsideRoot } from "../utils/paths.ts"; -import { prunePinnedSessionPaths, removePinnedSessionPath, setSessionPinned } from "../db/index.ts"; - -function isMachineSessionLabel(text: string, sessionHeaderId: string): boolean { - const t = (text ?? "").trim(); - if (!t) return true; - if (sessionHeaderId && t === sessionHeaderId) return true; - if (/^[0-9a-f]{8,}$/i.test(t)) return true; - if (/^[0-9]{10,}$/.test(t)) return true; - return false; -} - -function titleFromFirstUserMessage(text: string, maxChars = 56): string { - const cleaned = String(text ?? "").replace(/\s+/g, " ").trim(); - if (!cleaned) return ""; - const sentenceMatch = cleaned.match(/^(.+?[。!?.!?])(\s|$)/); - let candidate = sentenceMatch && sentenceMatch[1] ? sentenceMatch[1].trim() : cleaned; - if (candidate.length > maxChars) { - candidate = `${candidate.slice(0, maxChars).trimEnd()}…`; - } - return candidate; -} - -function extractPreview(msg: any): string { - const c = msg.content; - if (!c) return ""; - if (typeof c === "string") return c.slice(0, 200); - if (Array.isArray(c)) { - const text = c - .filter((x: any) => x.type === "text") - .map((x: any) => x.text) - .join("") - .slice(0, 200); - if (text) return text; - const imageCount = c.filter((x: any) => x.type === "image").length; - if (imageCount > 0) return `[${imageCount} 张图片]`; - } - return ""; -} - -export function listSessionFiles(paths: WebUiPaths): string[] { - if (!existsSync(paths.sessionsDir)) return []; - const files: string[] = []; - const visit = (dir: string) => { - for (const entry of readdirSync(dir, { withFileTypes: true })) { - const fullPath = join(dir, entry.name); - if (entry.isDirectory()) { - visit(fullPath); - } else if (entry.isFile() && entry.name.endsWith(".jsonl")) { - files.push(fullPath); - } - } - }; - visit(paths.sessionsDir); - return files.sort().reverse(); -} - -export function readSessionSummary(paths: WebUiPaths, filePath: string): Record | null { - try { - const content = readFileSync(filePath, "utf8"); - const lines = content.trim().split("\n"); - if (!lines.length) return null; - const header = JSON.parse(lines[0]); - if (header.type !== "session") return null; - - let nameFromInfo = ""; - let messageCount = 0; - let firstMessage = ""; - const stats = statSync(filePath); - - for (const line of lines) { - if (!line.trim()) continue; - try { - const entry = JSON.parse(line); - if (entry.type === "session_info" && entry.name) { - const n = String(entry.name).trim(); - if (n && !isMachineSessionLabel(n, header.id)) { - nameFromInfo = n; - } - } - if (entry.type === "message") { - messageCount++; - if (!firstMessage && entry.message?.role === "user") { - firstMessage = extractPreview(entry.message); - } - } - } catch { - /* skip */ - } - } - - const fromFirstUser = titleFromFirstUserMessage(firstMessage); - let name = nameFromInfo; - if (!name || isMachineSessionLabel(name, header.id)) { - name = fromFirstUser || ""; - } - - return { - path: filePath, - id: header.id, - name, - created: header.timestamp, - modified: stats.mtime.toISOString(), - messageCount, - firstMessage: firstMessage || "(空)", - }; - } catch { - return null; - } -} - -export function readSessionMessages(filePath: string): unknown[] { - try { - const content = readFileSync(filePath, "utf8"); - return content - .trim() - .split("\n") - .map((line) => { - try { - const entry = JSON.parse(line); - return entry.type === "message" ? entry.message : null; - } catch { - return null; - } - }) - .filter(Boolean); - } catch { - return []; - } -} - -export function resolveSessionFile(paths: WebUiPaths, filePath: string): string { - if (typeof filePath !== "string" || !filePath.trim()) { - throw new Error("无效会话路径"); - } - const sessionsRoot = resolve(paths.sessionsDir); - const resolved = resolve(filePath.trim()); - if (!resolved.toLowerCase().endsWith(".jsonl")) { - throw new Error("无效会话路径"); - } - if (!isPathInsideRoot(sessionsRoot, resolved)) { - throw new Error("无效会话路径"); - } - return resolved; -} - -export function appendSessionName(paths: WebUiPaths, filePath: string, name: string): string { - const sessionPath = resolveSessionFile(paths, filePath); - if (!existsSync(sessionPath)) throw new Error("会话不存在"); - - const trimmed = name.trim(); - if (!trimmed) throw new Error("会话名称不能为空"); - - const lines = readFileSync(sessionPath, "utf8").trim().split("\n"); - const ids = new Set(); - let leafId: string | null = null; - for (const line of lines) { - if (!line.trim()) continue; - try { - const entry = JSON.parse(line); - if (typeof entry.id === "string") { - ids.add(entry.id); - leafId = entry.id; - } - } catch { - /* skip */ - } - } - if (!leafId) throw new Error("无效会话文件"); - - let id = randomUUID().slice(0, 8); - for (let i = 0; i < 100 && ids.has(id); i++) { - id = randomUUID().slice(0, 8); - } - - const entry = { - type: "session_info", - id, - parentId: leafId, - timestamp: new Date().toISOString(), - name: trimmed, - }; - appendFileSync(sessionPath, `\n${JSON.stringify(entry)}`, "utf8"); - return trimmed; -} - -function sortSessionSummaries( - summaries: Array>, - pinnedPaths: string[], -): Array> { - const pinnedOrder = new Map(pinnedPaths.map((path, index) => [path, index])); - return [...summaries].sort((a, b) => { - const aPath = String(a.path); - const bPath = String(b.path); - const aPin = pinnedOrder.get(aPath); - const bPin = pinnedOrder.get(bPath); - if (aPin !== undefined && bPin !== undefined) return aPin - bPin; - if (aPin !== undefined) return -1; - if (bPin !== undefined) return 1; - return ( - new Date(String(b.modified || b.created || 0)).getTime() - - new Date(String(a.modified || a.created || 0)).getTime() - ); - }); -} - -function annotatePinnedSessions( - summaries: Array>, - pinnedPaths: string[], -): Array> { - const pinnedSet = new Set(pinnedPaths); - return summaries.map((summary) => ({ - ...summary, - pinned: pinnedSet.has(String(summary.path)), - })); -} - -export function buildSessionListResponse(paths: WebUiPaths) { - const summaries = listSessionFiles(paths) - .map((filePath) => readSessionSummary(paths, filePath)) - .filter(Boolean) as Array>; - const pinnedPaths = prunePinnedSessionPaths(summaries.map((summary) => String(summary.path))); - const sorted = sortSessionSummaries(summaries, pinnedPaths); - return { - sessions: annotatePinnedSessions(sorted, pinnedPaths), - pinnedPaths, - }; -} - -export function deleteSessionFile(paths: WebUiPaths, sessionPathInput: string): void { - const sessionPath = resolveSessionFile(paths, sessionPathInput); - if (!existsSync(sessionPath)) throw new Error("会话不存在"); - unlinkSync(sessionPath); - removePinnedSessionPath(sessionPath); -} - -export function pinSession(paths: WebUiPaths, sessionPathInput: string, pinned: boolean): { - path: string; - pinned: boolean; - pinnedPaths: string[]; -} { - const sessionPath = resolveSessionFile(paths, sessionPathInput); - if (!existsSync(sessionPath)) throw new Error("会话不存在"); - const pinnedPaths = setSessionPinned(sessionPath, pinned); - return { path: sessionPath, pinned, pinnedPaths }; -} diff --git a/.pi/agent/extensions/webui/backend/services/slash-commands.ts b/.pi/agent/extensions/webui/backend/services/slash-commands.ts deleted file mode 100644 index 99b43c2a..00000000 --- a/.pi/agent/extensions/webui/backend/services/slash-commands.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { BUILTIN_SLASH_COMMANDS } from "../../../../../../packages/coding-agent/src/core/slash-commands.ts"; -import { filterWebUiSlashCommands, type SlashCommandEntry } from "../slash/dispatch.ts"; -import type { SendCmd } from "../types/context.ts"; - -export async function listSlashCommands(sendCmd: SendCmd): Promise { - const builtinNames = new Set(BUILTIN_SLASH_COMMANDS.map((command) => command.name)); - const commands: SlashCommandEntry[] = BUILTIN_SLASH_COMMANDS.map((command) => ({ - name: command.name, - description: command.description, - source: "builtin", - })); - - const response = await sendCmd({ type: "get_commands" }); - if (!response.success) throw new Error(response.error || "读取命令失败"); - - for (const command of response.data?.commands || []) { - const name = String(command?.name || ""); - if (!name) continue; - - const source = String(command?.source || ""); - if (source === "extension" && builtinNames.has(name)) continue; - - if (source === "prompt") { - commands.push({ - name, - description: String(command.description || ""), - source: "prompt", - }); - continue; - } - - if (source === "skill") { - commands.push({ - name, - description: String(command.description || ""), - source: "skill", - }); - continue; - } - - if (source === "extension") { - commands.push({ - name, - description: String(command.description || ""), - source: "extension", - }); - } - } - - return filterWebUiSlashCommands(commands).sort((a, b) => a.name.localeCompare(b.name)); -} diff --git a/.pi/agent/extensions/webui/backend/services/system-prompt.ts b/.pi/agent/extensions/webui/backend/services/system-prompt.ts deleted file mode 100644 index ba1a9611..00000000 --- a/.pi/agent/extensions/webui/backend/services/system-prompt.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; -import { dirname } from "node:path"; -import type { WebUiPaths } from "../config/paths.ts"; - -export function readSystemPrompt(paths: WebUiPaths): string { - if (!existsSync(paths.systemPromptFile)) return ""; - return readFileSync(paths.systemPromptFile, "utf8"); -} - -export function writeSystemPrompt(paths: WebUiPaths, content: string): void { - mkdirSync(dirname(paths.systemPromptFile), { recursive: true }); - writeFileSync(paths.systemPromptFile, content, "utf8"); -} diff --git a/.pi/agent/extensions/webui/backend/settings/extension-settings.ts b/.pi/agent/extensions/webui/backend/settings/extension-settings.ts deleted file mode 100644 index 57459299..00000000 --- a/.pi/agent/extensions/webui/backend/settings/extension-settings.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { basename, dirname, join, relative, resolve } from "node:path"; -import { - DefaultPackageManager, - type PathMetadata, - type ResolvedResource, -} from "../../../../../../packages/coding-agent/src/core/package-manager.ts"; -import { SettingsManager, type PackageSource } from "../../../../../../packages/coding-agent/src/core/settings-manager.ts"; - -export interface ExtensionSettingsEntry { - path: string; - resolvedPath: string; - enabled: boolean; - name: string; - scope: string; - source: string; -} - -interface ExtensionResourceItem { - path: string; - enabled: boolean; - metadata: PathMetadata; -} - -function createManagers(repoRoot: string, agentDir: string) { - const settingsManager = SettingsManager.create(repoRoot, agentDir); - const packageManager = new DefaultPackageManager({ - cwd: repoRoot, - agentDir, - settingsManager, - }); - return { settingsManager, packageManager }; -} - -function normalizeExtensionPath(pathValue: string): string { - return resolve(pathValue); -} - -function readExtensionDisplayName(pathValue: string): string { - const normalized = pathValue.replace(/\\/g, "/"); - const parts = normalized.split("/").filter(Boolean); - const file = parts[parts.length - 1] || normalized; - if (/^index\.[cm]?[tj]s$/i.test(file) && parts.length >= 2) { - return parts[parts.length - 2].replace(/\.[cm]?[tj]s$/i, ""); - } - return basename(file).replace(/\.[cm]?[tj]s$/i, ""); -} - -function toResourceItem(resource: ResolvedResource): ExtensionResourceItem { - return { - path: resource.path, - enabled: resource.enabled, - metadata: resource.metadata, - }; -} - -function getTopLevelBaseDir(scope: "user" | "project", repoRoot: string, agentDir: string): string { - return scope === "project" ? join(repoRoot, ".pi") : agentDir; -} - -function getResourcePattern(item: ExtensionResourceItem, repoRoot: string, agentDir: string): string { - if (item.metadata.origin === "package") { - const baseDir = item.metadata.baseDir ?? dirname(item.path); - return relative(baseDir, item.path); - } - const scope = item.metadata.scope as "user" | "project"; - const baseDir = getTopLevelBaseDir(scope, repoRoot, agentDir); - return relative(baseDir, item.path); -} - -function applyPatternUpdate(current: string[], pattern: string, enabled: boolean): string[] { - const disablePattern = `-${pattern}`; - const enablePattern = `+${pattern}`; - const updated = current.filter((entry) => { - const stripped = entry.startsWith("!") || entry.startsWith("+") || entry.startsWith("-") ? entry.slice(1) : entry; - return stripped !== pattern; - }); - updated.push(enabled ? enablePattern : disablePattern); - return updated; -} - -function toggleTopLevelResource( - item: ExtensionResourceItem, - enabled: boolean, - settingsManager: SettingsManager, - repoRoot: string, - agentDir: string, -): void { - const scope = item.metadata.scope as "user" | "project"; - const settings = - scope === "project" ? settingsManager.getProjectSettings() : settingsManager.getGlobalSettings(); - const current = [...(settings.extensions ?? [])]; - const pattern = getResourcePattern(item, repoRoot, agentDir); - const updated = applyPatternUpdate(current, pattern, enabled); - - if (scope === "project") { - settingsManager.setProjectExtensionPaths(updated); - } else { - settingsManager.setExtensionPaths(updated); - } -} - -function togglePackageResource( - item: ExtensionResourceItem, - enabled: boolean, - settingsManager: SettingsManager, - repoRoot: string, - agentDir: string, -): void { - const scope = item.metadata.scope as "user" | "project"; - const settings = - scope === "project" ? settingsManager.getProjectSettings() : settingsManager.getGlobalSettings(); - const packages = [...(settings.packages ?? [])] as PackageSource[]; - const pkgIndex = packages.findIndex((pkg) => { - const source = typeof pkg === "string" ? pkg : pkg.source; - return source === item.metadata.source; - }); - if (pkgIndex === -1) return; - - let pkg = packages[pkgIndex]; - if (typeof pkg === "string") { - pkg = { source: pkg }; - packages[pkgIndex] = pkg; - } - - const current = [...((pkg.extensions ?? []) as string[])]; - const pattern = getResourcePattern(item, repoRoot, agentDir); - const updated = applyPatternUpdate(current, pattern, enabled); - (pkg as Record).extensions = updated.length > 0 ? updated : undefined; - - if (!pkg.skills && !pkg.extensions && !pkg.prompts && !pkg.themes) { - packages.splice(pkgIndex, 1); - } - - if (scope === "project") { - settingsManager.setProjectPackages(packages); - } else { - settingsManager.setPackages(packages); - } -} - -function toggleExtensionResource( - item: ExtensionResourceItem, - enabled: boolean, - settingsManager: SettingsManager, - repoRoot: string, - agentDir: string, -): void { - if (item.metadata.origin === "top-level") { - toggleTopLevelResource(item, enabled, settingsManager, repoRoot, agentDir); - } else { - togglePackageResource(item, enabled, settingsManager, repoRoot, agentDir); - } -} - -function pathsMatch(a: string, b: string): boolean { - const left = normalizeExtensionPath(a); - const right = normalizeExtensionPath(b); - if (left === right) return true; - return resolve(a) === resolve(b); -} - -function mapExtensionEntry(resource: ResolvedResource): ExtensionSettingsEntry { - return { - path: normalizeExtensionPath(resource.path), - resolvedPath: normalizeExtensionPath(resource.path), - enabled: resource.enabled, - name: readExtensionDisplayName(resource.path), - scope: resource.metadata.scope || "", - source: resource.metadata.source || "", - }; -} - -export async function listExtensionSettings( - repoRoot: string, - agentDir: string, -): Promise { - const { packageManager } = createManagers(repoRoot, agentDir); - const resolved = await packageManager.resolve(async () => "skip"); - return resolved.extensions.map(mapExtensionEntry).sort((a, b) => a.name.localeCompare(b.name)); -} - -export async function setExtensionEnabled( - repoRoot: string, - agentDir: string, - pathValue: string, - enabled: boolean, -): Promise { - const { settingsManager, packageManager } = createManagers(repoRoot, agentDir); - const resolved = await packageManager.resolve(async () => "skip"); - const match = resolved.extensions.find((resource) => pathsMatch(resource.path, pathValue)); - if (!match) { - throw new Error("未找到对应扩展"); - } - - toggleExtensionResource(toResourceItem(match), enabled, settingsManager, repoRoot, agentDir); - - const refreshed = await packageManager.resolve(async () => "skip"); - const updated = refreshed.extensions.find((resource) => pathsMatch(resource.path, pathValue)); - if (!updated) { - throw new Error("更新扩展状态后未能重新解析"); - } - return mapExtensionEntry(updated); -} diff --git a/.pi/agent/extensions/webui/backend/settings/extensions-paths.ts b/.pi/agent/extensions/webui/backend/settings/extensions-paths.ts deleted file mode 100644 index 57150935..00000000 --- a/.pi/agent/extensions/webui/backend/settings/extensions-paths.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { existsSync, readFileSync } from "node:fs"; -import { join, relative, resolve, sep } from "node:path"; - -export function readConfiguredNpmPackageNames(settingsPath: string): Set { - const names = new Set(); - if (!existsSync(settingsPath)) return names; - - try { - const raw = JSON.parse(readFileSync(settingsPath, "utf8")); - const packages = raw?.packages; - if (!Array.isArray(packages)) return names; - - for (const entry of packages) { - const source = typeof entry === "string" ? entry : entry?.source; - if (typeof source === "string" && source.startsWith("npm:")) { - const name = source.slice("npm:".length).trim(); - if (name) names.add(name); - } - } - } catch { - /* ignore invalid settings */ - } - - return names; -} - -export function extractNpmPackageNameFromPath(nodeModulesRoot: string, pathValue: string): string | null { - if (!pathValue) return null; - - const root = resolve(nodeModulesRoot); - const normalized = resolve(pathValue); - if (normalized !== root && !normalized.startsWith(`${root}${sep}`)) { - return null; - } - - const rel = relative(root, normalized); - const parts = rel.split(sep).filter(Boolean); - if (parts.length === 0) return null; - if (parts[0].startsWith("@") && parts.length >= 2) { - return `${parts[0]}/${parts[1]}`; - } - return parts[0] || null; -} - -export function isLocalAgentExtension(pathValue: string, agentExtensionsDir: string): boolean { - if (!pathValue) return false; - const resolved = resolve(pathValue); - const root = resolve(agentExtensionsDir); - return resolved === root || resolved.startsWith(`${root}${sep}`); -} - -export function isConfiguredNpmExtension( - pathValue: string, - nodeModulesRoot: string, - configuredPackages: Set, -): boolean { - const packageName = extractNpmPackageNameFromPath(nodeModulesRoot, pathValue); - return packageName !== null && configuredPackages.has(packageName); -} - -export function getExtensionCategoryFromPath( - pathValue: string, - agentExtensionsDir: string, - nodeModulesRoot: string, - configuredPackages: Set, -): "local" | "npm" | null { - if (isConfiguredNpmExtension(pathValue, nodeModulesRoot, configuredPackages)) { - return "npm"; - } - if (isLocalAgentExtension(pathValue, agentExtensionsDir)) { - return "local"; - } - return null; -} - -export function resolveNpmSource(pathValue: string, nodeModulesRoot: string, fallbackSource: string): string { - if (fallbackSource.startsWith("npm:")) return fallbackSource; - const packageName = extractNpmPackageNameFromPath(nodeModulesRoot, pathValue); - return packageName ? `npm:${packageName}` : fallbackSource; -} - -export function readNpmPackageVersion( - nodeModulesRoot: string, - pathValue: string, - source: string, -): string | undefined { - let packageName = extractNpmPackageNameFromPath(nodeModulesRoot, pathValue); - if (!packageName && source.startsWith("npm:")) { - packageName = source.slice("npm:".length).trim() || null; - } - if (!packageName) return undefined; - - const pkgJsonPath = join(nodeModulesRoot, packageName, "package.json"); - if (!existsSync(pkgJsonPath)) return undefined; - - try { - const raw = JSON.parse(readFileSync(pkgJsonPath, "utf8")) as { version?: unknown }; - return typeof raw.version === "string" && raw.version.trim() ? raw.version.trim() : undefined; - } catch { - return undefined; - } -} diff --git a/.pi/agent/extensions/webui/backend/settings/mcp-settings.ts b/.pi/agent/extensions/webui/backend/settings/mcp-settings.ts deleted file mode 100644 index da26e096..00000000 --- a/.pi/agent/extensions/webui/backend/settings/mcp-settings.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs"; -import { dirname } from "node:path"; - -const DISABLED_SERVERS_KEY = "mcpServersDisabled"; - -type McpServerEntry = Record; - -export interface McpToolSettingsEntry { - server: string; - name: string; - description: string; - parameters: string[]; - required: string[]; - enabled: boolean; -} - -export interface McpServerSettingsEntry { - name: string; - configured: boolean; - enabled: boolean; - cached: boolean; - toolCount: number; - enabledToolCount: number; - resourceCount: number; - cachedAt: string; - tools: McpToolSettingsEntry[]; -} - -function readRawConfig(filePath: string): Record { - if (!existsSync(filePath)) return { mcpServers: {} }; - try { - const raw = JSON.parse(readFileSync(filePath, "utf8")); - return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : { mcpServers: {} }; - } catch { - return { mcpServers: {} }; - } -} - -function writeRawConfig(filePath: string, raw: Record): void { - mkdirSync(dirname(filePath), { recursive: true }); - const tmpPath = `${filePath}.${process.pid}.tmp`; - writeFileSync(tmpPath, `${JSON.stringify(raw, null, 2)}\n`, "utf8"); - renameSync(tmpPath, filePath); -} - -function getServersObject(raw: Record): Record { - const existing = raw.mcpServers ?? raw["mcp-servers"]; - if (!existing || typeof existing !== "object" || Array.isArray(existing)) { - return {}; - } - return existing as Record; -} - -function getDisabledServersObject(raw: Record): Record { - const existing = raw[DISABLED_SERVERS_KEY]; - if (!existing || typeof existing !== "object" || Array.isArray(existing)) { - return {}; - } - return existing as Record; -} - -function setServersObject(raw: Record, servers: Record): void { - delete raw["mcp-servers"]; - raw.mcpServers = servers; -} - -function setDisabledServersObject(raw: Record, servers: Record): void { - if (Object.keys(servers).length === 0) { - delete raw[DISABLED_SERVERS_KEY]; - return; - } - raw[DISABLED_SERVERS_KEY] = servers; -} - -function normalizeToolName(value: string): string { - return value.replace(/-/g, "_"); -} - -function isToolExcluded(toolName: string, serverName: string, excludeTools: unknown): boolean { - if (!Array.isArray(excludeTools) || excludeTools.length === 0) return false; - - const candidates = new Set([ - normalizeToolName(toolName), - normalizeToolName(`${serverName}_${toolName}`), - normalizeToolName(`${serverName.replace(/-/g, "_")}_${toolName}`), - ]); - - for (const excluded of excludeTools) { - if (typeof excluded !== "string") continue; - if (candidates.has(normalizeToolName(excluded))) { - return true; - } - } - return false; -} - -function removeToolFromExcludeList(excludeTools: string[], toolName: string, serverName: string): string[] { - return excludeTools.filter((entry) => !isToolExcluded(toolName, serverName, [entry])); -} - -function readJsonFile(filePath: string): any | null { - if (!existsSync(filePath)) return null; - try { - return JSON.parse(readFileSync(filePath, "utf8")); - } catch { - return null; - } -} - -function normalizeMcpTool(serverName: string, tool: any, serverEntry: McpServerEntry): McpToolSettingsEntry { - const schema = tool?.inputSchema && typeof tool.inputSchema === "object" ? tool.inputSchema : {}; - const properties = schema && typeof schema.properties === "object" ? Object.keys(schema.properties) : []; - const required = Array.isArray(schema.required) ? schema.required.map(String) : []; - const name = String(tool?.name || ""); - return { - server: serverName, - name, - description: String(tool?.description || ""), - parameters: properties, - required, - enabled: name ? !isToolExcluded(name, serverName, serverEntry.excludeTools) : false, - }; -} - -export function listMcpSettings(configPath: string, cachePath: string): McpServerSettingsEntry[] { - const raw = readRawConfig(configPath); - const activeServers = getServersObject(raw); - const disabledServers = getDisabledServersObject(raw); - const cache = readJsonFile(cachePath); - const cachedServers = cache?.servers && typeof cache.servers === "object" ? cache.servers : {}; - - const serverNames = Array.from( - new Set([...Object.keys(activeServers), ...Object.keys(disabledServers), ...Object.keys(cachedServers)]), - ).sort(); - - return serverNames.map((serverName) => { - const enabled = Object.prototype.hasOwnProperty.call(activeServers, serverName); - const serverEntry = (enabled ? activeServers[serverName] : disabledServers[serverName]) || {}; - const entry = cachedServers[serverName] || {}; - const tools = Array.isArray(entry.tools) - ? entry.tools - .map((tool: any) => normalizeMcpTool(serverName, tool, serverEntry)) - .filter((tool: McpToolSettingsEntry) => tool.name) - .sort((a: McpToolSettingsEntry, b: McpToolSettingsEntry) => a.name.localeCompare(b.name)) - : []; - const enabledTools = enabled ? tools.filter((tool) => tool.enabled) : []; - const resources = Array.isArray(entry.resources) ? entry.resources : []; - - return { - name: serverName, - configured: enabled || Object.prototype.hasOwnProperty.call(disabledServers, serverName), - enabled, - cached: Boolean(cachedServers[serverName]), - toolCount: tools.length, - enabledToolCount: enabledTools.length, - resourceCount: resources.length, - cachedAt: entry.cachedAt ? new Date(entry.cachedAt).toISOString() : "", - tools, - }; - }); -} - -export function setMcpServerEnabled( - configPath: string, - cachePath: string, - serverName: string, - enabled: boolean, -): McpServerSettingsEntry { - const raw = readRawConfig(configPath); - const activeServers = getServersObject(raw); - const disabledServers = getDisabledServersObject(raw); - - if (enabled) { - const entry = disabledServers[serverName]; - if (!entry) { - const current = listMcpSettings(configPath, cachePath).find((server) => server.name === serverName); - if (current?.enabled) return current; - throw new Error(`未找到已禁用的 MCP Server:${serverName}`); - } - activeServers[serverName] = entry; - delete disabledServers[serverName]; - } else { - const entry = activeServers[serverName]; - if (!entry) { - const current = listMcpSettings(configPath, cachePath).find((server) => server.name === serverName); - if (current && !current.enabled) return current; - throw new Error(`未找到 MCP Server:${serverName}`); - } - disabledServers[serverName] = entry; - delete activeServers[serverName]; - } - - setServersObject(raw, activeServers); - setDisabledServersObject(raw, disabledServers); - writeRawConfig(configPath, raw); - - const updated = listMcpSettings(configPath, cachePath).find((server) => server.name === serverName); - if (!updated) { - throw new Error(`更新 MCP Server 状态失败:${serverName}`); - } - return updated; -} - -export function setMcpToolEnabled( - configPath: string, - cachePath: string, - serverName: string, - toolName: string, - enabled: boolean, -): McpToolSettingsEntry { - const raw = readRawConfig(configPath); - const activeServers = getServersObject(raw); - const serverEntry = activeServers[serverName]; - if (!serverEntry) { - throw new Error(`MCP Server 未启用:${serverName}`); - } - - const excludeTools = Array.isArray(serverEntry.excludeTools) - ? serverEntry.excludeTools.filter((value): value is string => typeof value === "string") - : []; - - let nextExclude = excludeTools; - if (enabled) { - nextExclude = removeToolFromExcludeList(excludeTools, toolName, serverName); - } else if (!isToolExcluded(toolName, serverName, excludeTools)) { - nextExclude = [...excludeTools, toolName]; - } - - if (nextExclude.length > 0) { - serverEntry.excludeTools = nextExclude; - } else { - delete serverEntry.excludeTools; - } - - activeServers[serverName] = serverEntry; - setServersObject(raw, activeServers); - writeRawConfig(configPath, raw); - - const server = listMcpSettings(configPath, cachePath).find((item) => item.name === serverName); - const tool = server?.tools.find((item) => item.name === toolName); - if (!tool) { - throw new Error(`未找到 MCP工具:${serverName}/${toolName}`); - } - return tool; -} diff --git a/.pi/agent/extensions/webui/backend/settings/skills-settings.ts b/.pi/agent/extensions/webui/backend/settings/skills-settings.ts deleted file mode 100644 index d84f03c6..00000000 --- a/.pi/agent/extensions/webui/backend/settings/skills-settings.ts +++ /dev/null @@ -1,452 +0,0 @@ -import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync } from "node:fs"; -import { homedir } from "node:os"; -import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path"; -import { - DefaultPackageManager, - type PathMetadata, - type ResolvedResource, -} from "../../../../../../packages/coding-agent/src/core/package-manager.ts"; -import { SettingsManager, type PackageSource } from "../../../../../../packages/coding-agent/src/core/settings-manager.ts"; -import { parseFrontmatter } from "../../../../../../packages/coding-agent/src/utils/frontmatter.ts"; - -const SKILLS_DIR = "skills"; -const SKILLS_DISABLED_DIR = "skills-disabled"; - -export interface SkillSettingsEntry { - path: string; - enabled: boolean; - toggleable: boolean; - name: string; - description: string; - scope: string; - source: string; -} - -interface MovableSkillLocation { - baseDir: string; - fromPath: string; - isDirectory: boolean; - currentlyDisabled: boolean; -} - -interface SkillScanTarget { - baseDir: string; - scope: string; -} - -function createManagers(repoRoot: string, agentDir: string) { - const settingsManager = SettingsManager.create(repoRoot, agentDir); - const packageManager = new DefaultPackageManager({ - cwd: repoRoot, - agentDir, - settingsManager, - }); - return { settingsManager, packageManager }; -} - -function resolveSkillFilePath(pathValue: string): string { - const resolved = resolve(pathValue); - if (resolved.endsWith("SKILL.md")) return resolved; - const skillFile = join(resolved, "SKILL.md"); - return existsSync(skillFile) ? skillFile : resolved; -} - -function normalizeSkillPath(pathValue: string): string { - return resolveSkillFilePath(pathValue); -} - -function readSkillMeta(pathValue: string): { name: string; description: string } { - const skillFile = resolveSkillFilePath(pathValue); - const fallbackName = basename(dirname(skillFile)); - if (!existsSync(skillFile)) { - return { name: fallbackName, description: "" }; - } - try { - const content = readFileSync(skillFile, "utf8"); - const { frontmatter } = parseFrontmatter<{ name?: string; description?: string }>(content); - return { - name: String(frontmatter.name || fallbackName), - description: String(frontmatter.description || ""), - }; - } catch { - return { name: fallbackName, description: "" }; - } -} - -function isSkillToggleable(metadata: PathMetadata, skillPath: string): boolean { - if (metadata.origin === "package") return false; - if (metadata.source?.startsWith("npm:")) return false; - if (skillPath.includes("/node_modules/") || skillPath.includes("\\node_modules\\")) return false; - return metadata.origin === "top-level" && metadata.source === "auto"; -} - -function getSkillScanTargets(repoRoot: string, agentDir: string): SkillScanTarget[] { - const targets: SkillScanTarget[] = [ - { baseDir: agentDir, scope: "user" }, - { baseDir: join(repoRoot, ".pi"), scope: "project" }, - { baseDir: join(homedir(), ".agents"), scope: "user" }, - ]; - - const userAgents = join(homedir(), ".agents"); - let dir = resolve(repoRoot); - const gitRoot = (() => { - let current = dir; - while (true) { - if (existsSync(join(current, ".git"))) return current; - const parent = dirname(current); - if (parent === current) return null; - current = parent; - } - })(); - - dir = resolve(repoRoot); - while (true) { - const agentsBase = join(dir, ".agents"); - if (resolve(agentsBase) !== resolve(userAgents)) { - targets.push({ baseDir: agentsBase, scope: "project" }); - } - if (gitRoot && dir === gitRoot) break; - const parent = dirname(dir); - if (parent === dir) break; - dir = parent; - } - - const seen = new Set(); - return targets.filter((t) => { - const key = resolve(t.baseDir); - if (seen.has(key)) return false; - seen.add(key); - return true; - }); -} - -function collectSkillFilesInDir(dir: string, piRootMarkdown = false): string[] { - const entries: string[] = []; - if (!existsSync(dir)) return entries; - - const walk = (currentDir: string, isRoot: boolean): void => { - let dirEntries: ReturnType; - try { - dirEntries = readdirSync(currentDir, { withFileTypes: true }); - } catch { - return; - } - - for (const entry of dirEntries) { - if (entry.name === "SKILL.md") { - const fullPath = join(currentDir, entry.name); - try { - if (statSync(fullPath).isFile()) entries.push(fullPath); - } catch { - /* ignore */ - } - return; - } - } - - for (const entry of dirEntries) { - if (entry.name.startsWith(".") || entry.name === "node_modules") continue; - const fullPath = join(currentDir, entry.name); - let isDir = entry.isDirectory(); - let isFile = entry.isFile(); - if (entry.isSymbolicLink()) { - try { - const stats = statSync(fullPath); - isDir = stats.isDirectory(); - isFile = stats.isFile(); - } catch { - continue; - } - } - if (piRootMarkdown && isRoot && isFile && entry.name.endsWith(".md")) { - entries.push(fullPath); - continue; - } - if (isDir) walk(fullPath, false); - } - }; - - walk(dir, true); - return entries; -} - -function resolveMovableSkill(skillFilePath: string, baseDir: string): MovableSkillLocation | null { - const skillFile = resolve(skillFilePath); - const activeRoot = join(baseDir, SKILLS_DIR); - const disabledRoot = join(baseDir, SKILLS_DISABLED_DIR); - - for (const [root, currentlyDisabled] of [ - [activeRoot, false], - [disabledRoot, true], - ] as const) { - const rel = relative(root, skillFile); - if (rel.startsWith("..") || isAbsolute(rel)) continue; - - const parentRel = relative(root, dirname(skillFile)); - if (parentRel === ".") { - return { baseDir, fromPath: skillFile, isDirectory: false, currentlyDisabled }; - } - - const topSegment = rel.split(/[/\\]/)[0]; - if (!topSegment) continue; - const fromPath = join(root, topSegment); - if (!existsSync(fromPath)) continue; - return { - baseDir, - fromPath, - isDirectory: statSync(fromPath).isDirectory(), - currentlyDisabled, - }; - } - - return null; -} - -function findMovableSkill(pathValue: string, repoRoot: string, agentDir: string): MovableSkillLocation | null { - const skillFile = resolveSkillFilePath(pathValue); - for (const { baseDir } of getSkillScanTargets(repoRoot, agentDir)) { - const found = resolveMovableSkill(skillFile, baseDir); - if (found) return found; - } - return null; -} - -function moveSkillBetweenDirs(location: MovableSkillLocation, enabled: boolean): string { - const activeRoot = join(location.baseDir, SKILLS_DIR); - const disabledRoot = join(location.baseDir, SKILLS_DISABLED_DIR); - const destRoot = enabled ? activeRoot : disabledRoot; - mkdirSync(destRoot, { recursive: true }); - - const name = basename(location.fromPath); - const destPath = join(destRoot, name); - if (resolve(location.fromPath) === resolve(destPath)) { - return location.isDirectory ? join(destPath, "SKILL.md") : destPath; - } - if (existsSync(destPath)) { - throw new Error(`目标已存在: ${destPath}`); - } - - movePath(location.fromPath, destPath); - return location.isDirectory ? join(destPath, "SKILL.md") : destPath; -} - -function movePath(fromPath: string, destPath: string): void { - try { - renameSync(fromPath, destPath); - } catch (err) { - const code = err && typeof err === "object" && "code" in err ? String(err.code) : ""; - if (code !== "EXDEV") throw err; - cpSync(fromPath, destPath, { recursive: true }); - rmSync(fromPath, { recursive: true, force: true }); - } -} - -function stripSkillPatternPrefix(entry: string): string { - if (entry.startsWith("!") || entry.startsWith("+") || entry.startsWith("-")) { - return entry.slice(1); - } - return entry; -} - -function entryMatchesSkillPatterns(entry: string, patterns: Set): boolean { - const stripped = stripSkillPatternPrefix(entry); - for (const pattern of patterns) { - if (stripped === pattern) return true; - if (stripped.endsWith(`/${pattern}`)) return true; - if (pattern.endsWith(stripped)) return true; - } - return false; -} - -function patternsForSkillFile(skillFile: string, baseDir: string): Set { - const patterns = new Set(); - for (const dirName of [SKILLS_DIR, SKILLS_DISABLED_DIR]) { - const root = join(baseDir, dirName); - const rel = relative(root, skillFile).replace(/\\/g, "/"); - if (rel.startsWith("..") || isAbsolute(rel)) continue; - patterns.add(`${SKILLS_DIR}/${rel}`); - const top = rel.split("/")[0]; - if (top && top !== rel) patterns.add(`${SKILLS_DIR}/${top}`); - if (rel.endsWith("/SKILL.md")) { - patterns.add(`${SKILLS_DIR}/${dirname(rel)}`); - } - } - return patterns; -} - -function removeLegacySkillPatterns( - settingsManager: SettingsManager, - skillFilePath: string, - repoRoot: string, - agentDir: string, -): void { - const skillFile = normalizeSkillPath(skillFilePath); - const patterns = new Set(); - for (const { baseDir } of getSkillScanTargets(repoRoot, agentDir)) { - for (const p of patternsForSkillFile(skillFile, baseDir)) { - patterns.add(p); - } - } - - const cleanList = (entries: string[]): string[] => - entries.filter((entry) => !entryMatchesSkillPatterns(entry, patterns)); - - const globalSettings = settingsManager.getGlobalSettings(); - const cleanedGlobal = cleanList([...(globalSettings.skills ?? [])]); - if (cleanedGlobal.length !== (globalSettings.skills ?? []).length) { - settingsManager.setSkillPaths(cleanedGlobal); - } - - const projectSettings = settingsManager.getProjectSettings(); - const cleanedProject = cleanList([...(projectSettings.skills ?? [])]); - if (cleanedProject.length !== (projectSettings.skills ?? []).length) { - settingsManager.setProjectSkillPaths(cleanedProject); - } - - const cleanPackages = (packages: PackageSource[], setter: (pkgs: PackageSource[]) => void): void => { - let changed = false; - const updated = packages.map((pkg) => { - if (typeof pkg === "string") return pkg; - if (!pkg.skills?.length) return pkg; - const cleaned = cleanList([...pkg.skills]); - if (cleaned.length === pkg.skills.length) return pkg; - changed = true; - const next = { ...pkg, skills: cleaned.length > 0 ? cleaned : undefined }; - if (!next.skills && !next.extensions && !next.prompts && !next.themes) { - return pkg.source; - } - return next; - }); - if (changed) setter(updated); - }; - - cleanPackages([...(globalSettings.packages ?? [])], (pkgs) => settingsManager.setPackages(pkgs)); - cleanPackages([...(projectSettings.packages ?? [])], (pkgs) => settingsManager.setProjectPackages(pkgs)); -} - -function toggleSkillByMove( - pathValue: string, - enabled: boolean, - repoRoot: string, - agentDir: string, - settingsManager: SettingsManager, -): string { - const location = findMovableSkill(pathValue, repoRoot, agentDir); - if (!location) { - throw new Error("仅支持切换 skills 目录下的 skill"); - } - - let newPath = normalizeSkillPath(pathValue); - if (enabled && location.currentlyDisabled) { - newPath = normalizeSkillPath(moveSkillBetweenDirs(location, true)); - } else if (!enabled && !location.currentlyDisabled) { - newPath = normalizeSkillPath(moveSkillBetweenDirs(location, false)); - } - - removeLegacySkillPatterns(settingsManager, newPath, repoRoot, agentDir); - return newPath; -} - -function mapSkillEntry(resource: ResolvedResource): SkillSettingsEntry { - const meta = readSkillMeta(resource.path); - const toggleable = isSkillToggleable(resource.metadata, resource.path); - return { - path: normalizeSkillPath(resource.path), - enabled: resource.enabled, - toggleable, - name: meta.name, - description: meta.description, - scope: resource.metadata.scope || "", - source: resource.metadata.source || "", - }; -} - -function mapDisabledSkillEntry(skillPath: string, scope: string): SkillSettingsEntry { - const meta = readSkillMeta(skillPath); - return { - path: normalizeSkillPath(skillPath), - enabled: false, - toggleable: true, - name: meta.name, - description: meta.description, - scope, - source: "auto", - }; -} - -function collectDisabledSkillEntries(repoRoot: string, agentDir: string): SkillSettingsEntry[] { - const entries: SkillSettingsEntry[] = []; - for (const { baseDir, scope } of getSkillScanTargets(repoRoot, agentDir)) { - const disabledDir = join(baseDir, SKILLS_DISABLED_DIR); - const piRootMarkdown = - resolve(baseDir) === resolve(agentDir) || resolve(baseDir) === resolve(join(repoRoot, ".pi")); - for (const skillPath of collectSkillFilesInDir(disabledDir, piRootMarkdown)) { - entries.push(mapDisabledSkillEntry(skillPath, scope)); - } - } - return entries; -} - -function pathsMatch(a: string, b: string): boolean { - const left = normalizeSkillPath(a); - const right = normalizeSkillPath(b); - if (left === right) return true; - return resolve(a) === resolve(b); -} - -function mergeSkillEntries(resolved: SkillSettingsEntry[], disabled: SkillSettingsEntry[]): SkillSettingsEntry[] { - const merged = [...resolved]; - for (const entry of disabled) { - if (!merged.some((item) => pathsMatch(item.path, entry.path))) { - merged.push(entry); - } - } - return merged.sort((a, b) => a.name.localeCompare(b.name)); -} - -export async function listSkillSettings(repoRoot: string, agentDir: string): Promise { - const { packageManager } = createManagers(repoRoot, agentDir); - const resolved = await packageManager.resolve(async () => "skip"); - const active = resolved.skills.map(mapSkillEntry); - const disabled = collectDisabledSkillEntries(repoRoot, agentDir); - return mergeSkillEntries(active, disabled); -} - -export async function setSkillEnabled( - repoRoot: string, - agentDir: string, - pathValue: string, - enabled: boolean, -): Promise { - const { settingsManager, packageManager } = createManagers(repoRoot, agentDir); - const resolved = await packageManager.resolve(async () => "skip"); - const match = resolved.skills.find((resource) => pathsMatch(resource.path, pathValue)); - const disabledOnly = collectDisabledSkillEntries(repoRoot, agentDir).find((entry) => - pathsMatch(entry.path, pathValue), - ); - - if (match && !isSkillToggleable(match.metadata, match.path)) { - throw new Error("npm 包内的 skill 由包管理器控制,无法在此禁用"); - } - if (!match && !disabledOnly) { - throw new Error("未找到对应 skill"); - } - if (!findMovableSkill(pathValue, repoRoot, agentDir)) { - throw new Error("仅支持切换 skills 目录下的 skill"); - } - - const newPath = toggleSkillByMove(pathValue, enabled, repoRoot, agentDir, settingsManager); - const meta = readSkillMeta(newPath); - const scope = match?.metadata.scope || disabledOnly?.scope || ""; - const source = match?.metadata.source || disabledOnly?.source || "auto"; - - return { - path: newPath, - enabled, - toggleable: true, - name: meta.name, - description: meta.description, - scope, - source, - }; -} diff --git a/.pi/agent/extensions/webui/backend/slash/dispatch.ts b/.pi/agent/extensions/webui/backend/slash/dispatch.ts deleted file mode 100644 index e8be9f0a..00000000 --- a/.pi/agent/extensions/webui/backend/slash/dispatch.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { BUILTIN_SLASH_COMMANDS } from "../../../../../../packages/coding-agent/src/core/slash-commands.ts"; - -const BUILTIN_NAMES = new Set(BUILTIN_SLASH_COMMANDS.map((command) => command.name)); - -/** Built-in slash commands that WebUI executes (not TUI-only hints). */ -export const WEBUI_BUILTIN_SLASH_NAMES = new Set([ - "compact", - "new", - "reload", - "clone", - "name", - "model", - "session", - "export", - "copy", -]); - -export function isWebUiSlashCommand(source: "builtin" | "extension" | "prompt" | "skill", name: string): boolean { - if (source === "extension" || source === "prompt" || source === "skill") { - return true; - } - return WEBUI_BUILTIN_SLASH_NAMES.has(name); -} - -export interface SlashCommandEntry { - name: string; - description: string; - source: "builtin" | "extension" | "prompt" | "skill"; -} - -export function filterWebUiSlashCommands(commands: SlashCommandEntry[]): SlashCommandEntry[] { - return commands.filter((command) => isWebUiSlashCommand(command.source, command.name)); -} - -export interface SlashDispatchResult { - handled: boolean; - message?: string; - action?: "new_session" | "reload_messages" | "reload_sessions" | "copy"; - sessionFile?: string; -} - -type SendCmd = (command: Record) => Promise; - -interface ParsedSlash { - name: string; - args: string; -} - -function parseSlashInput(text: string): ParsedSlash | null { - const trimmed = text.trim(); - if (!trimmed.startsWith("/")) return null; - const body = trimmed.slice(1); - const spaceIndex = body.indexOf(" "); - if (spaceIndex === -1) { - return { name: body, args: "" }; - } - return { - name: body.slice(0, spaceIndex), - args: body.slice(spaceIndex + 1).trim(), - }; -} - -function webuiOnlyMessage(command: string): SlashDispatchResult { - const hints: Record = { - settings: "请使用 WebUI 顶栏或设置页修改配置。", - "scoped-models": "该命令仅在终端交互模式可用。", - changelog: "该命令仅在终端交互模式可用。", - hotkeys: "该命令仅在终端交互模式可用。", - fork: "该命令仅在终端交互模式可用(需选择消息节点)。", - tree: "该命令仅在终端交互模式可用。", - login: "请在 pi 终端模式中执行 /login 配置认证。", - logout: "请在 pi 终端模式中执行 /logout 移除认证。", - resume: "请使用左侧会话列表切换会话。", - import: "请使用终端模式 /import,或通过会话列表管理历史会话。", - share: "该命令仅在终端交互模式可用。", - quit: "WebUI 不会退出 pi 进程。", - }; - return { - handled: true, - message: hints[command] || "该命令在 WebUI 中不可用,请在终端模式使用。", - }; -} - -async function findModelMatch(sendCmd: SendCmd, searchTerm: string): Promise<{ provider: string; modelId: string } | null> { - const response = await sendCmd({ type: "get_available_models" }); - if (!response.success) return null; - const models = response.data?.models || []; - const term = searchTerm.trim().toLowerCase(); - if (!term) return null; - - if (term.includes("/")) { - const slashIndex = term.indexOf("/"); - const provider = term.slice(0, slashIndex); - const modelId = term.slice(slashIndex + 1); - const match = models.find( - (model: any) => - String(model.provider || "").toLowerCase() === provider && - String(model.id || "").toLowerCase() === modelId, - ); - if (match) { - return { provider: match.provider, modelId: match.id }; - } - } - - const byId = models.filter((model: any) => String(model.id || "").toLowerCase() === term); - if (byId.length === 1) { - return { provider: byId[0].provider, modelId: byId[0].id }; - } - - return null; -} - -export function isBuiltinSlashCommand(text: string): boolean { - const parsed = parseSlashInput(text); - return parsed ? BUILTIN_NAMES.has(parsed.name) : false; -} - -export async function dispatchSlashCommand(text: string, sendCmd: SendCmd): Promise { - const parsed = parseSlashInput(text); - if (!parsed) return null; - if (!BUILTIN_NAMES.has(parsed.name)) return null; - - const { name, args } = parsed; - - switch (name) { - case "compact": { - const response = await sendCmd({ type: "compact", customInstructions: args || undefined }); - if (!response.success) throw new Error(response.error || "压缩失败"); - return { handled: true, action: "reload_messages" }; - } - - case "new": { - const response = await sendCmd({ type: "new_session" }); - if (!response.success) throw new Error(response.error || "新建会话失败"); - if (response.data?.cancelled) { - return { handled: true, message: "已取消新建会话" }; - } - const state = await sendCmd({ type: "get_state" }); - if (!state.success) throw new Error(state.error || "读取会话状态失败"); - return { - handled: true, - action: "new_session", - sessionFile: state.data?.sessionFile, - message: "已开始新会话", - }; - } - - case "reload": { - const response = await sendCmd({ type: "reload" }); - if (!response.success) throw new Error(response.error || "重新加载失败"); - return { handled: true, action: "reload_sessions", message: "已重新加载配置与扩展" }; - } - - case "clone": { - const response = await sendCmd({ type: "clone" }); - if (!response.success) throw new Error(response.error || "克隆会话失败"); - const state = await sendCmd({ type: "get_state" }); - return { - handled: true, - action: "new_session", - sessionFile: state.success ? state.data?.sessionFile : undefined, - message: "已克隆当前会话", - }; - } - - case "name": { - if (!args) { - const state = await sendCmd({ type: "get_state" }); - if (!state.success) throw new Error(state.error || "读取会话状态失败"); - const currentName = state.data?.sessionName; - return { - handled: true, - message: currentName ? `当前会话名称:${currentName}` : "用法:/name <名称>", - }; - } - const response = await sendCmd({ type: "set_session_name", name: args }); - if (!response.success) throw new Error(response.error || "设置会话名称失败"); - return { handled: true, message: `会话名称已设为:${args}` }; - } - - case "model": { - if (!args) { - return { handled: true, message: "请使用顶栏模型选择器切换模型,或输入 /model provider/modelId。" }; - } - const match = await findModelMatch(sendCmd, args); - if (!match) { - throw new Error(`未找到模型:${args}`); - } - const response = await sendCmd({ type: "set_model", provider: match.provider, modelId: match.modelId }); - if (!response.success) throw new Error(response.error || "切换模型失败"); - return { handled: true, message: `已切换模型:${match.provider}/${match.modelId}` }; - } - - case "session": { - const response = await sendCmd({ type: "get_session_stats" }); - if (!response.success) throw new Error(response.error || "读取会话信息失败"); - const stats = response.data || {}; - const state = await sendCmd({ type: "get_state" }); - const sessionName = state.success ? state.data?.sessionName : undefined; - const lines = [ - sessionName ? `名称:${sessionName}` : null, - stats.sessionFile ? `文件:${stats.sessionFile}` : null, - stats.sessionId ? `ID:${stats.sessionId}` : null, - `用户消息:${stats.userMessages ?? 0}`, - `助手消息:${stats.assistantMessages ?? 0}`, - `工具调用:${stats.toolCalls ?? 0}`, - `总计:${stats.totalMessages ?? 0}`, - ].filter(Boolean); - return { handled: true, message: lines.join("\n") }; - } - - case "export": { - const response = await sendCmd({ type: "export_html", outputPath: args || undefined }); - if (!response.success) throw new Error(response.error || "导出失败"); - const outputPath = response.data?.path || response.data?.filePath || args || "默认路径"; - return { handled: true, message: `会话已导出:${outputPath}` }; - } - - case "copy": { - const response = await sendCmd({ type: "get_last_assistant_text" }); - if (!response.success) throw new Error(response.error || "读取助手消息失败"); - const copyText = String(response.data?.text || "").trim(); - if (!copyText) { - return { handled: true, message: "暂无可复制的助手消息。" }; - } - return { handled: true, action: "copy", message: copyText }; - } - - case "settings": - case "scoped-models": - case "changelog": - case "hotkeys": - case "fork": - case "tree": - case "login": - case "logout": - case "resume": - case "import": - case "share": - case "quit": - return webuiOnlyMessage(name); - - default: - return null; - } -} diff --git a/.pi/agent/extensions/webui/backend/types/context.ts b/.pi/agent/extensions/webui/backend/types/context.ts deleted file mode 100644 index 742bd6a6..00000000 --- a/.pi/agent/extensions/webui/backend/types/context.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { ServerResponse } from "node:http"; -import type { WebUiPaths } from "../config/paths.ts"; -import type { WebuiDbInfo } from "../db/index.ts"; - -export type SendCmd = (command: Record) => Promise; - -export interface SubmitPromptOptions { - message: string; - images?: Array<{ type: "image"; data: string; mimeType: string }>; - streamingBehavior?: "steer" | "followUp"; -} - -export interface RunSnapshot { - isStreaming: boolean; - sessionFile?: string; - replay: Record[]; -} - -export interface WebUiContext { - config: { - paths: WebUiPaths; - port: number; - }; - rpc: { - sendCmd: SendCmd; - submitPrompt: (options: SubmitPromptOptions) => void; - sendExtensionUiResponse: (id: string, response: Record) => void; - getRunSnapshot: () => RunSnapshot; - connectSseClient: (res: ServerResponse) => void; - removeSseClient: (res: ServerResponse) => void; - }; - db: WebuiDbInfo; -} diff --git a/.pi/agent/extensions/webui/backend/utils/paths.ts b/.pi/agent/extensions/webui/backend/utils/paths.ts deleted file mode 100644 index 5cd4720d..00000000 --- a/.pi/agent/extensions/webui/backend/utils/paths.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { relative, resolve } from "node:path"; - -/** True when `candidate` resolves to a path under `rootDir` (not the root dir itself). */ -export function isPathInsideRoot(rootDir: string, candidate: string): boolean { - const root = resolve(rootDir); - const target = resolve(candidate); - const rel = relative(root, target); - if (rel === "" || rel === ".") return false; - if (rel.startsWith("..")) return false; - // Cross-drive relative paths on Windows are absolute (e.g. D:\other\...) - if (/^[A-Za-z]:[\\/]/.test(rel)) return false; - return true; -} - -export function isSameResolvedPath(a: string, b: string): boolean { - const left = resolve(a); - const right = resolve(b); - if (process.platform === "win32") { - return left.toLowerCase() === right.toLowerCase(); - } - return left === right; -} diff --git a/.pi/agent/extensions/webui/frontend/.gitignore b/.pi/agent/extensions/webui/frontend/.gitignore deleted file mode 100644 index 91391561..00000000 --- a/.pi/agent/extensions/webui/frontend/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -dist/ -dist-desketop/ diff --git a/.pi/agent/extensions/webui/frontend/index.html b/.pi/agent/extensions/webui/frontend/index.html deleted file mode 100644 index 38d63cb2..00000000 --- a/.pi/agent/extensions/webui/frontend/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - 萌小芽 - - - - -
- - - diff --git a/.pi/agent/extensions/webui/frontend/package-lock.json b/.pi/agent/extensions/webui/frontend/package-lock.json deleted file mode 100644 index 1b785a0d..00000000 --- a/.pi/agent/extensions/webui/frontend/package-lock.json +++ /dev/null @@ -1,6816 +0,0 @@ -{ - "name": "sproutclaw-webui-frontend", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "sproutclaw-webui-frontend", - "version": "0.0.0", - "dependencies": { - "highlight.js": "11.11.1", - "marked": "15.0.12", - "react": "19.2.6", - "react-dom": "19.2.6", - "react-router-dom": "7.15.1" - }, - "devDependencies": { - "@mogeko/maple-mono-cn": "7.9.0", - "@types/react": "19.2.15", - "@types/react-dom": "19.2.3", - "@vitejs/plugin-react": "4.7.0", - "sharp": "0.34.5", - "typescript": "5.9.3", - "vite": "6.4.2", - "vite-plugin-pwa": "1.3.0" - } - }, - "node_modules/@apideck/better-ajv-errors": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.7.tgz", - "integrity": "sha512-TajUJwGWbDwkCx/CZi7tRE8PVB7simCvKJfHUsSdvps+aTM/PDPP4gkLmKnc+x3CE//y9i/nj74GqdL/hwk7Iw==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsonpointer": "^5.0.1", - "leven": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "ajv": ">=8" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", - "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz", - "integrity": "sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.28.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.29.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", - "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "regexpu-core": "^6.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", - "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "debug": "^4.4.3", - "lodash.debounce": "^4.0.8", - "resolve": "^1.22.11" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", - "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-wrap-function": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", - "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", - "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", - "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", - "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", - "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", - "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.3.tgz", - "integrity": "sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", - "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", - "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", - "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", - "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", - "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.29.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", - "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-remap-async-to-generator": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", - "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", - "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", - "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", - "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", - "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-globals": "^7.28.0", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-replace-supers": "^7.28.6", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", - "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/template": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", - "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", - "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", - "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", - "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", - "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-explicit-resource-management": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", - "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/plugin-transform-destructuring": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", - "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", - "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", - "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", - "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", - "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", - "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.29.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz", - "integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.29.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", - "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", - "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", - "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", - "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", - "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", - "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/plugin-transform-destructuring": "^7.28.5", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", - "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", - "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", - "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", - "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", - "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", - "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", - "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", - "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", - "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", - "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", - "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", - "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", - "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", - "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", - "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", - "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", - "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", - "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.29.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.5.tgz", - "integrity": "sha512-/69t2aEzGKHD76DyLbHysF/QH2LJOB8iFnYO37unDTKBTubzcMRv0f3H5EiN1Q6ajOd/eB7dAInF0qdFVS06kA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.29.3", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", - "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.28.6", - "@babel/plugin-syntax-import-attributes": "^7.28.6", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.29.0", - "@babel/plugin-transform-async-to-generator": "^7.28.6", - "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.28.6", - "@babel/plugin-transform-class-properties": "^7.28.6", - "@babel/plugin-transform-class-static-block": "^7.28.6", - "@babel/plugin-transform-classes": "^7.28.6", - "@babel/plugin-transform-computed-properties": "^7.28.6", - "@babel/plugin-transform-destructuring": "^7.28.5", - "@babel/plugin-transform-dotall-regex": "^7.28.6", - "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", - "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-explicit-resource-management": "^7.28.6", - "@babel/plugin-transform-exponentiation-operator": "^7.28.6", - "@babel/plugin-transform-export-namespace-from": "^7.27.1", - "@babel/plugin-transform-for-of": "^7.27.1", - "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.28.6", - "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", - "@babel/plugin-transform-member-expression-literals": "^7.27.1", - "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.28.6", - "@babel/plugin-transform-modules-systemjs": "^7.29.4", - "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", - "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", - "@babel/plugin-transform-numeric-separator": "^7.28.6", - "@babel/plugin-transform-object-rest-spread": "^7.28.6", - "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.28.6", - "@babel/plugin-transform-optional-chaining": "^7.28.6", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/plugin-transform-private-methods": "^7.28.6", - "@babel/plugin-transform-private-property-in-object": "^7.28.6", - "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.29.0", - "@babel/plugin-transform-regexp-modifiers": "^7.28.6", - "@babel/plugin-transform-reserved-words": "^7.27.1", - "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.28.6", - "@babel/plugin-transform-sticky-regex": "^7.27.1", - "@babel/plugin-transform-template-literals": "^7.27.1", - "@babel/plugin-transform-typeof-symbol": "^7.27.1", - "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.28.6", - "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.15", - "babel-plugin-polyfill-corejs3": "^0.14.0", - "babel-plugin-polyfill-regenerator": "^0.6.6", - "core-js-compat": "^3.48.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", - "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/colour": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", - "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.7.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@isaacs/cliui": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", - "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@mogeko/maple-mono-cn": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@mogeko/maple-mono-cn/-/maple-mono-cn-7.9.0.tgz", - "integrity": "sha512-NZls63+8Q4+17saZqhN5sFB9UqIfyI73q+NNyXNQFmdzivzSYAKLCuo2yvheyEm95kuH8VEhwTl4YvbMoqIbFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.27", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", - "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/plugin-babel": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.1.0.tgz", - "integrity": "sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@rollup/pluginutils": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "@types/babel__core": { - "optional": true - }, - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz", - "integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-replace": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-6.0.3.tgz", - "integrity": "sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "magic-string": "^0.30.3" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-terser": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-1.0.0.tgz", - "integrity": "sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "serialize-javascript": "^7.0.3", - "smob": "^1.0.0", - "terser": "^5.17.4" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "rollup": "^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", - "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.4.tgz", - "integrity": "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.4.tgz", - "integrity": "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.4.tgz", - "integrity": "sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.4.tgz", - "integrity": "sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.4.tgz", - "integrity": "sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.4.tgz", - "integrity": "sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.4.tgz", - "integrity": "sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.4.tgz", - "integrity": "sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.4.tgz", - "integrity": "sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.4.tgz", - "integrity": "sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.4.tgz", - "integrity": "sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.4.tgz", - "integrity": "sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.4.tgz", - "integrity": "sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.4.tgz", - "integrity": "sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.4.tgz", - "integrity": "sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.4.tgz", - "integrity": "sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.4.tgz", - "integrity": "sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz", - "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.4.tgz", - "integrity": "sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.4.tgz", - "integrity": "sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.4.tgz", - "integrity": "sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.4.tgz", - "integrity": "sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.4.tgz", - "integrity": "sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.4.tgz", - "integrity": "sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.4.tgz", - "integrity": "sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@trickfilm400/rollup-plugin-off-main-thread": { - "version": "3.0.0-pre1", - "resolved": "https://registry.npmjs.org/@trickfilm400/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-3.0.0-pre1.tgz", - "integrity": "sha512-/67zpWDBLV+oYAEL682s1ktXL0HgqX76f6gaVGkGnVZlBbm1zd0v4Bz8MFF2GGhoX9rvfq3KSQHubFHwa6w6/Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "ejs": "^3.1.10", - "json5": "^2.2.3", - "magic-string": "^0.30.21", - "string.prototype.matchall": "^4.0.12" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.15.tgz", - "integrity": "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vitejs/plugin-react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", - "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.28.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.27", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.17.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "node_modules/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", - "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-define-polyfill-provider": "^0.6.8", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", - "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.8", - "core-js-compat": "^3.48.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", - "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.8" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.31", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.31.tgz", - "integrity": "sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", - "update-browserslist-db": "^1.2.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/call-bind": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", - "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "get-intrinsic": "^1.3.0", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001793", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", - "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/core-js-compat": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", - "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserslist": "^4.28.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/inspect-js" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.360", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.360.tgz", - "integrity": "sha512-GkcBt6YYAw9SxFWn+xVar4cLVGlXVuswwtRLBozi2zp0GjXs4ZnOrqV4zbXzg35n7w81hCkyJNYicgXlVHAmBA==", - "dev": true, - "license": "ISC" - }, - "node_modules/es-abstract": { - "version": "1.24.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", - "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.3.0", - "get-proto": "^1.0.1", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.1", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.4", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.4", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "stop-iteration-iterator": "^1.1.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.19" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eta": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-4.6.0.tgz", - "integrity": "sha512-lW6is4T1NFOYnmqGZIfvixqj7A7sSvScF+DN8EK6K58xI5MZ5UvYe0GjopxOXQtZvUn4eDdVuZ8XSoYWTMEKwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/bgub/eta?sponsor=1" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/filelist": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", - "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/generator-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", - "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "dev": true, - "license": "ISC" - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", - "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "foreground-child": "^3.3.1", - "jackspeak": "^4.1.1", - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", - "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/highlight.js": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", - "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-async-function": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", - "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-generator-function": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", - "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.4", - "generator-function": "^2.0.0", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/jackspeak": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", - "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^9.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jake": { - "version": "10.9.4", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", - "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.6", - "filelist": "^1.0.4", - "picocolors": "^1.1.1" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", - "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/marked": { - "version": "15.0.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", - "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/node-releases": { - "version": "2.0.44", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz", - "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.5.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.0.tgz", - "integrity": "sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.12", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/pretty-bytes": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", - "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/react": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", - "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", - "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.27.0" - }, - "peerDependencies": { - "react": "^19.2.6" - } - }, - "node_modules/react-refresh": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", - "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-router": { - "version": "7.15.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.15.1.tgz", - "integrity": "sha512-R8rl9HhgikFYoPJymnUtPXWbnDb3oget6lQnfIoupbt61aT9aOhRkDsY2XRhZRyX1Z/8a5sL74fXmFNm3NRK5A==", - "license": "MIT", - "dependencies": { - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - } - } - }, - "node_modules/react-router-dom": { - "version": "7.15.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.15.1.tgz", - "integrity": "sha512-AzF62gjY6U9rkMq4RfP/r2EVtQ7DMfNMjyOp/flLTCrtRylLiK4wT4pSq6O8rOXZ2eXdZYJPEYe+ifomiv+Igg==", - "license": "MIT", - "dependencies": { - "react-router": "7.15.1" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", - "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpu-core": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", - "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.2", - "regjsgen": "^0.8.0", - "regjsparser": "^0.13.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.2.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/regjsparser": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", - "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~3.1.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/rollup": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.4.tgz", - "integrity": "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.4", - "@rollup/rollup-android-arm64": "4.60.4", - "@rollup/rollup-darwin-arm64": "4.60.4", - "@rollup/rollup-darwin-x64": "4.60.4", - "@rollup/rollup-freebsd-arm64": "4.60.4", - "@rollup/rollup-freebsd-x64": "4.60.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.4", - "@rollup/rollup-linux-arm-musleabihf": "4.60.4", - "@rollup/rollup-linux-arm64-gnu": "4.60.4", - "@rollup/rollup-linux-arm64-musl": "4.60.4", - "@rollup/rollup-linux-loong64-gnu": "4.60.4", - "@rollup/rollup-linux-loong64-musl": "4.60.4", - "@rollup/rollup-linux-ppc64-gnu": "4.60.4", - "@rollup/rollup-linux-ppc64-musl": "4.60.4", - "@rollup/rollup-linux-riscv64-gnu": "4.60.4", - "@rollup/rollup-linux-riscv64-musl": "4.60.4", - "@rollup/rollup-linux-s390x-gnu": "4.60.4", - "@rollup/rollup-linux-x64-gnu": "4.60.4", - "@rollup/rollup-linux-x64-musl": "4.60.4", - "@rollup/rollup-openbsd-x64": "4.60.4", - "@rollup/rollup-openharmony-arm64": "4.60.4", - "@rollup/rollup-win32-arm64-msvc": "4.60.4", - "@rollup/rollup-win32-ia32-msvc": "4.60.4", - "@rollup/rollup-win32-x64-gnu": "4.60.4", - "@rollup/rollup-win32-x64-msvc": "4.60.4", - "fsevents": "~2.3.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", - "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "get-intrinsic": "^1.3.0", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT" - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", - "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", - "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", - "license": "MIT" - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@img/colour": "^1.0.0", - "detect-libc": "^2.1.2", - "semver": "^7.7.3" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.5", - "@img/sharp-darwin-x64": "0.34.5", - "@img/sharp-libvips-darwin-arm64": "1.2.4", - "@img/sharp-libvips-darwin-x64": "1.2.4", - "@img/sharp-libvips-linux-arm": "1.2.4", - "@img/sharp-libvips-linux-arm64": "1.2.4", - "@img/sharp-libvips-linux-ppc64": "1.2.4", - "@img/sharp-libvips-linux-riscv64": "1.2.4", - "@img/sharp-libvips-linux-s390x": "1.2.4", - "@img/sharp-libvips-linux-x64": "1.2.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", - "@img/sharp-libvips-linuxmusl-x64": "1.2.4", - "@img/sharp-linux-arm": "0.34.5", - "@img/sharp-linux-arm64": "0.34.5", - "@img/sharp-linux-ppc64": "0.34.5", - "@img/sharp-linux-riscv64": "0.34.5", - "@img/sharp-linux-s390x": "0.34.5", - "@img/sharp-linux-x64": "0.34.5", - "@img/sharp-linuxmusl-arm64": "0.34.5", - "@img/sharp-linuxmusl-x64": "0.34.5", - "@img/sharp-wasm32": "0.34.5", - "@img/sharp-win32-arm64": "0.34.5", - "@img/sharp-win32-ia32": "0.34.5", - "@img/sharp-win32-x64": "0.34.5" - } - }, - "node_modules/sharp/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", - "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/smob": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.2.tgz", - "integrity": "sha512-RQsvleCbF8cVHEv+xuDGaA4pOizFqJ0GgjtMSRo6oP8pnN7WsigHgVGey6aILRBKv4W2YOMHLqbKdnB6hpB9fw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "deprecated": "The work that was done in this beta branch won't be included in future versions", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "whatwg-url": "^7.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", - "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "regexp.prototype.flags": "^1.5.3", - "set-function-name": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-data-property": "^1.1.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", - "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/tempy": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", - "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.47.1.tgz", - "integrity": "sha512-tPbLXTI6ohPASb/1YViL428oEHu6/qv1OxqYnfaonVCFHqx4+wCd95pHrQWsL5X4pl90CTyW9piSAsS2L0VoMw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", - "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD", - "optional": true - }, - "node_modules/type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", - "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", - "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/vite": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz", - "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vite-plugin-pwa": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.3.0.tgz", - "integrity": "sha512-c5kMgN+ITrOtHXp8PAtk2uOIEea6XjP/unCGxOWWBzQ6qa65qj/awHg0wf+QF9E/2u9vh86LqxPwzEPNbM2r5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.6", - "pretty-bytes": "^6.1.1", - "tinyglobby": "^0.2.10", - "workbox-build": "^7.4.1", - "workbox-window": "^7.4.1" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vite-pwa/assets-generator": "^1.0.0", - "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "workbox-build": "^7.4.1", - "workbox-window": "^7.4.1" - }, - "peerDependenciesMeta": { - "@vite-pwa/assets-generator": { - "optional": true - } - } - }, - "node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.20", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", - "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/workbox-background-sync": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.4.1.tgz", - "integrity": "sha512-HhT7KE8tOWDm02wRNshXUnUPofMlhenF2DBdUnDPOubhizzPeItkYTmAB6td1Z2cjYPa98vzEiPLEuzn5hN66g==", - "dev": true, - "license": "MIT", - "dependencies": { - "idb": "^7.0.1", - "workbox-core": "7.4.1" - } - }, - "node_modules/workbox-broadcast-update": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.4.1.tgz", - "integrity": "sha512-uAlgslKLvbQY+suirIdnBCSYrcgBhjp81Nj4l1lj/Jmj0MJO2CJERnCJjT0GFVwmReV0N+zs78K6gqd5gr9/+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.1" - } - }, - "node_modules/workbox-build": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.4.1.tgz", - "integrity": "sha512-SDhxIvEAde9Gy/5w4Yo1Jh/M49Z0qE3q0oteyE8zGq0DScxFqVBcCtIXFuLtmtxRQZCMbf0prco4VyEu3KBQuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@apideck/better-ajv-errors": "^0.3.1", - "@babel/core": "^7.24.4", - "@babel/preset-env": "^7.11.0", - "@babel/runtime": "^7.11.2", - "@rollup/plugin-babel": "^6.1.0", - "@rollup/plugin-node-resolve": "^16.0.3", - "@rollup/plugin-replace": "^6.0.3", - "@rollup/plugin-terser": "^1.0.0", - "@trickfilm400/rollup-plugin-off-main-thread": "^3.0.0-pre1", - "ajv": "^8.6.0", - "common-tags": "^1.8.0", - "eta": "^4.5.1", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^9.0.1", - "glob": "^11.0.1", - "pretty-bytes": "^5.3.0", - "rollup": "^4.53.3", - "source-map": "^0.8.0-beta.0", - "stringify-object": "^3.3.0", - "strip-comments": "^2.0.1", - "tempy": "^0.6.0", - "upath": "^1.2.0", - "workbox-background-sync": "7.4.1", - "workbox-broadcast-update": "7.4.1", - "workbox-cacheable-response": "7.4.1", - "workbox-core": "7.4.1", - "workbox-expiration": "7.4.1", - "workbox-google-analytics": "7.4.1", - "workbox-navigation-preload": "7.4.1", - "workbox-precaching": "7.4.1", - "workbox-range-requests": "7.4.1", - "workbox-recipes": "7.4.1", - "workbox-routing": "7.4.1", - "workbox-strategies": "7.4.1", - "workbox-streams": "7.4.1", - "workbox-sw": "7.4.1", - "workbox-window": "7.4.1" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/workbox-build/node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/workbox-cacheable-response": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.4.1.tgz", - "integrity": "sha512-8xaFoJdDc2OjrlbbL3gEeBO1WKcMwRqwLRupgqahYXu75yXajPLuwrbXMrIGZuWYXrQwk0xDjOxZ/ujCy/oJYw==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.1" - } - }, - "node_modules/workbox-core": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.4.1.tgz", - "integrity": "sha512-DT+vu46eh/2vRsSHTY4Xmc32Z1rr9PRlQUXr1Dx30ZuXRWwOsvZgGgcwxcasubQLQmbTNYZjv44LkBAQ4tT5tQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/workbox-expiration": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.4.1.tgz", - "integrity": "sha512-lRKUF7b+OGbeXkQk1s6MHXOa3d7Xxf7Of31W6c6hCfipfIyrtdWZ89stq21AHZMaoG7VNFoHply4Ox+rU31TWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "idb": "^7.0.1", - "workbox-core": "7.4.1" - } - }, - "node_modules/workbox-google-analytics": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.4.1.tgz", - "integrity": "sha512-Mks1JwLEt++ZAkF6sS1OpSh9RtAMIsiDgRpK+codiHGIPXeaUOgi4cPc3GFadUl8V5QPeypEk8Oxgl3HlwVzHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-background-sync": "7.4.1", - "workbox-core": "7.4.1", - "workbox-routing": "7.4.1", - "workbox-strategies": "7.4.1" - } - }, - "node_modules/workbox-navigation-preload": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.4.1.tgz", - "integrity": "sha512-C4KVsjPcYKJOhr631AxR9XoG2rLF3QiTk5aMv36MXOjtWvm8axwNFAtKUPGsWUwLXXAMgYM1En7fsvndaXeXRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.1" - } - }, - "node_modules/workbox-precaching": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.4.1.tgz", - "integrity": "sha512-cdr/9qByww7yzEp7zg/qI4ukUrrNjQLgN+ONQRpjy/VqGQXwkgHwr00KksGJK8v0VifwDXBb8a4cWNZH71jn3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.1", - "workbox-routing": "7.4.1", - "workbox-strategies": "7.4.1" - } - }, - "node_modules/workbox-range-requests": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.4.1.tgz", - "integrity": "sha512-7i2oxAUE82gHdAJBCAQ04JzNOdRPqzuOzGfoUyJpFSmeqBNYGPrAH8GPoPjUQTfp+NycwrD2H68VtuF8qxv0vQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.1" - } - }, - "node_modules/workbox-recipes": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.4.1.tgz", - "integrity": "sha512-gnbVfmV4/TtmQaM4x9AtuXhcdstJsep3XMVeztOrQVPT+R6+6DeBjGTCQ7fFCXm+4GEHUA5VEBTyi5+4gWGeog==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-cacheable-response": "7.4.1", - "workbox-core": "7.4.1", - "workbox-expiration": "7.4.1", - "workbox-precaching": "7.4.1", - "workbox-routing": "7.4.1", - "workbox-strategies": "7.4.1" - } - }, - "node_modules/workbox-routing": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.4.1.tgz", - "integrity": "sha512-yubJGErZOusuidAenaL5ypfhQOa7urxP/f8E0ws7FPb4039RiWXUWBAyUkmUoOL/BcQGen3h0J8872d51IYxtA==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.1" - } - }, - "node_modules/workbox-strategies": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.4.1.tgz", - "integrity": "sha512-GZxpaw9NbmOelj7667uZ2kpk5BFpOGbO4X0qjwh5ls8XQ8C+Lha5LQchTiUzsTFSS+NlUpftYAyOVXvQUrcqOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.1" - } - }, - "node_modules/workbox-streams": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.4.1.tgz", - "integrity": "sha512-HWWtraKUbJknd9kgqGcpQ3G114HOPYvqs8HaJMDs2ebLNAimDkVDaWfAXE6Ybl+m8U6KsCE6pWyLYuigWmnAXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "workbox-core": "7.4.1", - "workbox-routing": "7.4.1" - } - }, - "node_modules/workbox-sw": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.4.1.tgz", - "integrity": "sha512-fez5f2DUlDJWTFYkCWQpY10N8gtztd849NswCbVFk0QlcSM4HT5A8x4g4ii650yem4I8tHY0R7JZahwp3ltIPw==", - "dev": true, - "license": "MIT" - }, - "node_modules/workbox-window": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.4.1.tgz", - "integrity": "sha512-notZDH2u8VXaqyuD7xaqIfEFi6SRM4SUSd7ewe9PDsVqADuepxX2ZMY3uvuZGxzY5ZOsGC/vD3A/3smFtJt4/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/trusted-types": "^2.0.2", - "workbox-core": "7.4.1" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - } - } -} diff --git a/.pi/agent/extensions/webui/frontend/package.json b/.pi/agent/extensions/webui/frontend/package.json deleted file mode 100644 index 3fe915d3..00000000 --- a/.pi/agent/extensions/webui/frontend/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "sproutclaw-webui-frontend", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "generate-icons": "node scripts/generate-icons.mjs", - "dev": "vite", - "build": "npm run generate-icons && tsc -b && vite build && vite build --mode desktop", - "build:web": "npm run generate-icons && tsc -b && vite build", - "build:desktop": "npm run generate-icons && tsc -b && vite build --mode desktop", - "preview": "vite preview" - }, - "dependencies": { - "highlight.js": "11.11.1", - "marked": "15.0.12", - "react": "19.2.6", - "react-dom": "19.2.6", - "react-router-dom": "7.15.1" - }, - "devDependencies": { - "@mogeko/maple-mono-cn": "7.9.0", - "@types/react": "19.2.15", - "@types/react-dom": "19.2.3", - "@vitejs/plugin-react": "4.7.0", - "sharp": "0.34.5", - "typescript": "5.9.3", - "vite": "6.4.2", - "vite-plugin-pwa": "1.3.0" - } -} diff --git a/.pi/agent/extensions/webui/frontend/public/logo.png b/.pi/agent/extensions/webui/frontend/public/logo.png deleted file mode 100644 index 2914e6d6..00000000 Binary files a/.pi/agent/extensions/webui/frontend/public/logo.png and /dev/null differ diff --git a/.pi/agent/extensions/webui/frontend/public/logo192.png b/.pi/agent/extensions/webui/frontend/public/logo192.png deleted file mode 100644 index 9dad33f8..00000000 Binary files a/.pi/agent/extensions/webui/frontend/public/logo192.png and /dev/null differ diff --git a/.pi/agent/extensions/webui/frontend/public/logo512.png b/.pi/agent/extensions/webui/frontend/public/logo512.png deleted file mode 100644 index 37407af8..00000000 Binary files a/.pi/agent/extensions/webui/frontend/public/logo512.png and /dev/null differ diff --git a/.pi/agent/extensions/webui/frontend/scripts/generate-icons.mjs b/.pi/agent/extensions/webui/frontend/scripts/generate-icons.mjs deleted file mode 100644 index 5aee7286..00000000 --- a/.pi/agent/extensions/webui/frontend/scripts/generate-icons.mjs +++ /dev/null @@ -1,22 +0,0 @@ -import { existsSync } from "node:fs"; -import { dirname, join } from "node:path"; -import { fileURLToPath } from "node:url"; -import sharp from "sharp"; - -const __dirname = dirname(fileURLToPath(import.meta.url)); -const publicDir = join(__dirname, "..", "public"); -const source = join(publicDir, "logo.png"); - -if (!existsSync(source)) { - console.warn("[generate-icons] logo.png not found, skipping"); - process.exit(0); -} - -for (const size of [192, 512]) { - const out = join(publicDir, `logo${size}.png`); - await sharp(source) - .resize(size, size, { fit: "contain", background: { r: 0, g: 0, b: 0, alpha: 0 } }) - .png() - .toFile(out); - console.log(`[generate-icons] wrote ${out}`); -} diff --git a/.pi/agent/extensions/webui/frontend/src/App.tsx b/.pi/agent/extensions/webui/frontend/src/App.tsx deleted file mode 100644 index 244f79e5..00000000 --- a/.pi/agent/extensions/webui/frontend/src/App.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { BrowserRouter, Route, Routes } from "react-router-dom"; -import { PwaUpdatePrompt } from "./components/pwa/PwaUpdatePrompt"; -import { ChatLayout } from "./components/layout/ChatLayout"; -import { AvatarProvider } from "./context/AvatarContext"; -import { BootstrapProvider } from "./context/BootstrapContext"; -import { ChatProvider } from "./context/ChatContext"; -import { ChatPage } from "./routes/ChatPage"; -import { SettingsPage } from "./routes/SettingsPage"; - -export function App() { - return ( - - - - - - }> - } /> - - } /> - - - - - - - ); -} diff --git a/.pi/agent/extensions/webui/frontend/src/api/base.ts b/.pi/agent/extensions/webui/frontend/src/api/base.ts deleted file mode 100644 index 3943a09c..00000000 --- a/.pi/agent/extensions/webui/frontend/src/api/base.ts +++ /dev/null @@ -1,13 +0,0 @@ -const API_BASE = (import.meta.env.VITE_API_BASE ?? "").trim().replace(/\/$/, ""); - -/** Resolve an API path. Empty base keeps same-origin relative paths for web `dist/`. */ -export function apiUrl(path: string): string { - if (!path.startsWith("/")) { - throw new Error(`API path must start with /: ${path}`); - } - return API_BASE ? `${API_BASE}${path}` : path; -} - -export function getApiBase(): string { - return API_BASE; -} diff --git a/.pi/agent/extensions/webui/frontend/src/api/chat.ts b/.pi/agent/extensions/webui/frontend/src/api/chat.ts deleted file mode 100644 index b60d8459..00000000 --- a/.pi/agent/extensions/webui/frontend/src/api/chat.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { apiGet, apiPost } from "./client"; -import type { ImageContent, ModelInfo, SessionState } from "../types/message"; -import type { BashResult } from "../utils/bash"; -import type { NewSessionResponse } from "../types/session"; - -export interface ChatResponse { - ok?: boolean; - accepted?: boolean; - slash?: boolean; - message?: string; - action?: "new_session" | "reload_messages" | "reload_sessions" | "copy"; - sessionFile?: string; - error?: string; -} - -export type SendMode = "prompt" | "steer" | "follow_up"; - -export function sendChat( - message: string, - images?: ImageContent[], - options?: { streamingBehavior?: "steer" | "followUp" }, -): Promise { - return apiPost("/api/chat", { message, images, streamingBehavior: options?.streamingBehavior }); -} - -export function sendSteer(message: string, images?: ImageContent[]): Promise<{ ok: boolean }> { - return apiPost("/api/steer", { message, images }); -} - -export function sendFollowUp(message: string, images?: ImageContent[]): Promise<{ ok: boolean }> { - return apiPost("/api/follow-up", { message, images }); -} - -export function runBash(command: string, options?: { excludeFromContext?: boolean }): Promise { - return apiPost("/api/bash", { command, excludeFromContext: options?.excludeFromContext }); -} - -export function abortChat(): Promise<{ ok: boolean }> { - return apiPost("/api/abort"); -} - -export function abortRetry(): Promise<{ ok: boolean }> { - return apiPost("/api/abort-retry"); -} - -export function sendExtensionUiResponse( - id: string, - response: Record, -): Promise<{ ok: boolean }> { - return apiPost("/api/extension-ui-response", { id, response }); -} - -export function fetchSessionState(): Promise { - return apiGet("/api/session-state"); -} - -export function fetchModels(): Promise<{ models: ModelInfo[] }> { - return apiGet("/api/models"); -} - -export function setModel(provider: string, modelId: string): Promise<{ ok: boolean }> { - return apiPost("/api/model", { provider, modelId }); -} - -export function setThinkingLevel(level: string): Promise<{ ok: boolean }> { - return apiPost("/api/thinking", { level }); -} - -export function createNewSession(): Promise { - return apiPost("/api/new-session"); -} diff --git a/.pi/agent/extensions/webui/frontend/src/api/client.ts b/.pi/agent/extensions/webui/frontend/src/api/client.ts deleted file mode 100644 index 1cfabec4..00000000 --- a/.pi/agent/extensions/webui/frontend/src/api/client.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { apiUrl } from "./base"; - -export class ApiError extends Error { - constructor( - message: string, - public status?: number, - ) { - super(message); - this.name = "ApiError"; - } -} - -export async function apiFetch(url: string, init?: RequestInit): Promise { - const res = await fetch(apiUrl(url), init); - const data = (await res.json().catch(() => ({}))) as T & { error?: string }; - if (!res.ok || (data && "error" in data && data.error)) { - throw new ApiError((data as { error?: string }).error || res.statusText, res.status); - } - return data; -} - -export async function apiPost(url: string, body?: unknown): Promise { - return apiFetch(url, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: body !== undefined ? JSON.stringify(body) : undefined, - }); -} - -export async function apiGet(url: string): Promise { - return apiFetch(url); -} diff --git a/.pi/agent/extensions/webui/frontend/src/api/commands.ts b/.pi/agent/extensions/webui/frontend/src/api/commands.ts deleted file mode 100644 index 7c3144d6..00000000 --- a/.pi/agent/extensions/webui/frontend/src/api/commands.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { apiGet } from "./client"; -import type { SlashCommandsResponse } from "../types/commands"; - -export function fetchSlashCommands(): Promise { - return apiGet("/api/commands"); -} diff --git a/.pi/agent/extensions/webui/frontend/src/api/sessions.ts b/.pi/agent/extensions/webui/frontend/src/api/sessions.ts deleted file mode 100644 index f62f181b..00000000 --- a/.pi/agent/extensions/webui/frontend/src/api/sessions.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { apiGet, apiPost } from "./client"; -import { apiUrl } from "./base"; -import type { SessionState } from "../types/message"; -import type { SessionHistoryPayload, SessionSummary } from "../types/session"; - -export function fetchSessions(): Promise<{ sessions: SessionSummary[] }> { - return apiGet("/api/sessions"); -} - -export function fetchSessionHistory(path: string): Promise { - return apiPost("/api/sessions/history", { path }); -} - -export async function activateSessionBackend(path: string): Promise { - const activateRes = await fetch(apiUrl("/api/sessions/activate"), { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ path }), - }); - const activateData = (await activateRes.json().catch(() => ({}))) as { - error?: string; - state?: SessionState; - }; - if (activateRes.ok && !activateData.error) { - return activateData.state ?? null; - } - - const activateError = activateData.error || activateRes.statusText || "Unknown error"; - if (activateRes.status !== 404 && !/not found/i.test(activateError)) { - throw new Error(activateError); - } - - const fallbackRes = await fetch(apiUrl("/api/sessions/load"), { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ path }), - }); - const fallbackData = (await fallbackRes.json().catch(() => ({}))) as { error?: string }; - if (!fallbackRes.ok || fallbackData.error) { - throw new Error(fallbackData.error || fallbackRes.statusText); - } - return null; -} - -export function loadSession(path: string): Promise<{ ok?: boolean; error?: string }> { - return apiPost("/api/sessions/load", { path }); -} - -export function deleteSession(path: string): Promise<{ ok?: boolean }> { - return apiPost("/api/sessions/delete", { path }); -} - -export function renameSession(path: string, name: string): Promise<{ ok?: boolean }> { - return apiPost("/api/sessions/name", { path, name }); -} - -export function setSessionPinned(path: string, pinned: boolean): Promise<{ ok?: boolean; pinned?: boolean; pinnedPaths?: string[] }> { - return apiPost("/api/sessions/pin", { path, pinned }); -} diff --git a/.pi/agent/extensions/webui/frontend/src/api/settings.ts b/.pi/agent/extensions/webui/frontend/src/api/settings.ts deleted file mode 100644 index cb58dac3..00000000 --- a/.pi/agent/extensions/webui/frontend/src/api/settings.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { apiGet, apiPost } from "./client"; -import type { AvatarSettings, EnvironmentInfo, ExtensionInfo, McpServerInfo, McpToolInfo, SettingsData, SkillInfo } from "../types/events"; - -export function fetchSettings(): Promise { - return apiGet("/api/settings"); -} - -export function toggleSkill(path: string, enabled: boolean): Promise<{ ok?: boolean; skill?: SkillInfo }> { - return apiPost("/api/settings/skills/toggle", { path, enabled }); -} - -export function toggleExtension( - path: string, - enabled: boolean, -): Promise<{ ok?: boolean; extension?: ExtensionInfo }> { - return apiPost("/api/settings/extensions/toggle", { path, enabled }); -} - -export function toggleMcpServer( - server: string, - enabled: boolean, -): Promise<{ ok?: boolean; server?: McpServerInfo }> { - return apiPost("/api/settings/mcp/server/toggle", { server, enabled }); -} - -export function toggleMcpTool( - server: string, - tool: string, - enabled: boolean, -): Promise<{ ok?: boolean; tool?: McpToolInfo }> { - return apiPost("/api/settings/mcp/tool/toggle", { server, tool, enabled }); -} - -export function fetchAvatars(): Promise { - return apiGet("/api/avatars"); -} - -export function reloadSettings(): Promise<{ ok?: boolean }> { - return apiPost("/api/settings/reload"); -} - -export function saveSystemPrompt(systemPrompt: string): Promise<{ systemPromptPath?: string }> { - return apiPost("/api/settings/system-prompt", { systemPrompt }); -} - -export function saveModelsConfig(modelsConfig: string): Promise<{ modelsConfigPath?: string }> { - return apiPost("/api/settings/models-config", { modelsConfig }); -} - -export function saveAvatars(avatars: AvatarSettings): Promise { - return apiPost("/api/settings/avatars", avatars); -} - -export function fetchEnvironment(): Promise { - return apiGet("/api/environment"); -} diff --git a/.pi/agent/extensions/webui/frontend/src/api/webuiConfig.ts b/.pi/agent/extensions/webui/frontend/src/api/webuiConfig.ts deleted file mode 100644 index c12a0929..00000000 --- a/.pi/agent/extensions/webui/frontend/src/api/webuiConfig.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { apiGet, apiPost } from "./client"; - -export interface WebuiConfigResponse { - config?: Record; - dbPath?: string; - key?: string; - value?: string | null; -} - -export function fetchWebuiConfig(key?: string): Promise { - const query = key ? `?key=${encodeURIComponent(key)}` : ""; - return apiGet(`/api/webui/config${query}`); -} - -export function saveWebuiConfig(key: string, value: string): Promise<{ ok?: boolean; key?: string; value?: string }> { - return apiPost("/api/webui/config", { key, value }); -} - -export function saveWebuiConfigMany(entries: Record): Promise<{ ok?: boolean; config?: Record }> { - return apiPost("/api/webui/config", { entries }); -} - -export function deleteWebuiConfig(key: string): Promise<{ ok?: boolean; deleted?: boolean; key?: string }> { - return apiPost("/api/webui/config/delete", { key }); -} diff --git a/.pi/agent/extensions/webui/frontend/src/components/chat/BashOutputBlock.module.css b/.pi/agent/extensions/webui/frontend/src/components/chat/BashOutputBlock.module.css deleted file mode 100644 index 4e1b3bb5..00000000 --- a/.pi/agent/extensions/webui/frontend/src/components/chat/BashOutputBlock.module.css +++ /dev/null @@ -1,93 +0,0 @@ -.block { - margin: 0; -} - -.blockDim .header { - opacity: 0.75; -} - -.blockDim .command, -.blockDim .output { - color: #6b7280; -} - -.header { - display: flex; - align-items: center; - gap: 8px; - padding: 8px 12px; - background: #f8fafc; - border-bottom: 1px solid #e8ecf0; -} - -.icon { - display: flex; - align-items: center; - justify-content: center; - width: 22px; - height: 22px; - flex-shrink: 0; - border-radius: 6px; - background: #eef2ff; - color: #4f46e5; -} - -.prompt { - font-family: var(--font-mono); - font-size: inherit; - font-weight: 600; - color: #6366f1; - flex-shrink: 0; -} - -.command { - min-width: 0; - flex: 1; - font-family: var(--font-mono); - font-size: inherit; - color: #374151; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.output { - margin: 0; - padding: 10px 12px; - font-family: var(--font-mono); - font-size: inherit; - line-height: inherit; - color: #4b5563; - background: #fff; - white-space: pre-wrap; - word-break: break-word; - overflow-x: auto; - max-height: min(420px, 50vh); -} - -.outputEmpty { - color: #9ca3af; - font-style: italic; -} - -.outputStreaming::after { - content: "▊"; - animation: blink 0.8s step-end infinite; - color: #6366f1; - margin-left: 1px; -} - -.exit { - padding: 6px 12px; - border-top: 1px solid #fecaca; - background: #fef2f2; - font-family: var(--font-mono); - font-size: inherit; - color: #b91c1c; -} - -@keyframes blink { - 50% { - opacity: 0; - } -} diff --git a/.pi/agent/extensions/webui/frontend/src/components/chat/BashOutputBlock.tsx b/.pi/agent/extensions/webui/frontend/src/components/chat/BashOutputBlock.tsx deleted file mode 100644 index 9a0719c2..00000000 --- a/.pi/agent/extensions/webui/frontend/src/components/chat/BashOutputBlock.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import styles from "./BashOutputBlock.module.css"; - -interface BashOutputBlockProps { - command?: string; - content: string; - exitCode?: number; - streaming?: boolean; - excludeFromContext?: boolean; -} - -export function BashOutputBlock({ - command, - content, - exitCode, - streaming, - excludeFromContext, -}: BashOutputBlockProps) { - const hasOutput = Boolean(content.trim()); - const showExit = exitCode !== undefined && exitCode !== 0 && !streaming; - - return ( -
-
- - $ - {command || "shell"} -
-
-				{hasOutput ? content : streaming ? "执行中..." : "(无输出)"}
-			
- {showExit ?
退出码 {exitCode}
: null} -
- ); -} diff --git a/.pi/agent/extensions/webui/frontend/src/components/chat/ChatInput.module.css b/.pi/agent/extensions/webui/frontend/src/components/chat/ChatInput.module.css deleted file mode 100644 index 056d891a..00000000 --- a/.pi/agent/extensions/webui/frontend/src/components/chat/ChatInput.module.css +++ /dev/null @@ -1,153 +0,0 @@ -.inputArea { - padding: 10px 16px 12px; - border-top: 1px solid #f0f0f0; - flex-shrink: 0; - background: rgba(255, 255, 255, 0.92); - backdrop-filter: blur(10px); -} - -.inputAreaDragOver { - background: rgba(239, 246, 255, 0.96); -} - -.attachments { - display: flex; - flex-wrap: wrap; - gap: 8px; - max-width: 720px; - margin: 0 auto 8px; -} - -.attachmentItem { - position: relative; - width: 72px; - height: 72px; -} - -.attachmentThumb { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 10px; - border: 1px solid #e5e7eb; - background: #f9fafb; -} - -.attachmentRemove { - position: absolute; - top: -6px; - right: -6px; - width: 20px; - height: 20px; - border: none; - border-radius: 999px; - background: rgba(15, 23, 42, 0.78); - color: #fff; - font-size: 14px; - line-height: 1; - cursor: pointer; -} - -.fileInput { - display: none; -} - -.wrapper { - display: flex; - gap: 8px; - align-items: flex-end; - max-width: 720px; - margin: 0 auto; - background: #f6f7fb; - border: 1px solid #e5e5e5; - border-radius: 14px; - padding: 4px 4px 4px 8px; - transition: border-color 0.15s; -} - -.wrapper:focus-within { - border-color: #2563eb; - background: #fff; -} - -.input { - flex: 1; - background: transparent; - border: none; - color: #1a1a1a; - padding: 8px 0; - font-size: 16px; - font-family: inherit; - resize: none; - outline: none; - min-height: 24px; - max-height: 120px; - line-height: 1.45; -} - -.input::placeholder { - color: #bbb; -} - -.attachBtn { - width: 36px; - height: 36px; - display: flex; - align-items: center; - justify-content: center; - background: transparent; - border: none; - border-radius: 11px; - color: #64748b; - cursor: pointer; - flex-shrink: 0; - transition: background 0.15s, color 0.15s; -} - -.attachBtn:hover:not(:disabled) { - background: #eef2ff; - color: #2563eb; -} - -.attachBtn:disabled { - opacity: 0.45; - cursor: not-allowed; -} - -.sendBtn { - width: 36px; - height: 36px; - display: flex; - align-items: center; - justify-content: center; - background: #2563eb; - border: none; - border-radius: 11px; - color: #fff; - cursor: pointer; - flex-shrink: 0; - transition: background 0.15s, opacity 0.15s; - touch-action: manipulation; -} - -.sendBtn:hover { - background: #1d4ed8; -} - -.sendBtn:disabled { - background: #d1d5db; - cursor: not-allowed; -} - -@media (max-width: 768px) { - .inputArea { - position: sticky; - bottom: 0; - z-index: 5; - padding: 8px 10px calc(10px + env(safe-area-inset-bottom)); - } - - .wrapper { - padding: 2px 2px 2px 10px; - } -} diff --git a/.pi/agent/extensions/webui/frontend/src/components/chat/ChatInput.tsx b/.pi/agent/extensions/webui/frontend/src/components/chat/ChatInput.tsx deleted file mode 100644 index 38ebc0c3..00000000 --- a/.pi/agent/extensions/webui/frontend/src/components/chat/ChatInput.tsx +++ /dev/null @@ -1,345 +0,0 @@ -import { useEffect, useMemo, useRef, useState, type ClipboardEvent, type DragEvent, type KeyboardEvent } from "react"; -import { fetchSlashCommands } from "../../api/commands"; -import { useChatContext } from "../../context/ChatContext"; -import type { SlashCommand } from "../../types/commands"; -import type { ImageContent } from "../../types/message"; -import { isTouchLike } from "../../utils/format"; -import { - clipboardItemsToImages, - fileToImageContent, - imageToDataUrl, - MAX_CHAT_IMAGES, -} from "../../utils/images"; -import { parseBashInput } from "../../utils/bash"; -import { - applySlashCompletion, - filterSlashCommands, - filterWebUiSlashCommands, - parseSlashCommandInput, -} from "../../utils/slashCommands"; -import { SlashCommandMenu } from "./SlashCommandMenu"; -import styles from "./ChatInput.module.css"; - -export function ChatInput() { - const { - isStreaming, - sendMessage, - runBashCommand, - addSystemMessage, - abortStream, - toggleToolsExpanded, - } = useChatContext(); - const [value, setValue] = useState(""); - const [pendingImages, setPendingImages] = useState([]); - const [dragOver, setDragOver] = useState(false); - const [slashCommands, setSlashCommands] = useState([]); - const [selectedSlashIndex, setSelectedSlashIndex] = useState(0); - const inputRef = useRef(null); - const fileInputRef = useRef(null); - const touchLike = isTouchLike(); - - useEffect(() => { - let cancelled = false; - void fetchSlashCommands() - .then((data) => { - if (!cancelled) setSlashCommands(filterWebUiSlashCommands(data.commands || [])); - }) - .catch((err) => { - if (!cancelled) { - addSystemMessage(err instanceof Error ? err.message : String(err)); - } - }); - return () => { - cancelled = true; - }; - }, [addSystemMessage]); - - useEffect(() => { - const onKeyDown = (e: globalThis.KeyboardEvent) => { - if (!inputRef.current || document.activeElement !== inputRef.current) return; - if (e.key === "Escape" && isStreaming) { - e.preventDefault(); - void abortStream(); - } - if (e.key === "o" && (e.ctrlKey || e.metaKey)) { - e.preventDefault(); - toggleToolsExpanded(); - } - }; - document.addEventListener("keydown", onKeyDown); - return () => document.removeEventListener("keydown", onKeyDown); - }, [isStreaming, abortStream, toggleToolsExpanded]); - - const slashContext = useMemo(() => parseSlashCommandInput(value), [value]); - const filteredSlashCommands = useMemo( - () => (slashContext ? filterSlashCommands(slashCommands, slashContext.query) : []), - [slashCommands, slashContext], - ); - const slashMenuOpen = Boolean(slashContext && filteredSlashCommands.length > 0); - - useEffect(() => { - setSelectedSlashIndex(0); - }, [value, slashMenuOpen]); - - const canSend = value.trim().length > 0 || pendingImages.length > 0; - - const applySlashSelection = (command: SlashCommand) => { - const nextValue = applySlashCompletion(value, command.name); - setValue(nextValue); - requestAnimationFrame(() => { - const el = inputRef.current; - if (!el) return; - el.focus(); - el.setSelectionRange(nextValue.length, nextValue.length); - el.style.height = "auto"; - el.style.height = `${Math.min(el.scrollHeight, 150)}px`; - }); - }; - - const addImages = async (files: FileList | File[]) => { - const list = Array.from(files); - if (!list.length) return; - - const remaining = MAX_CHAT_IMAGES - pendingImages.length; - if (remaining <= 0) { - addSystemMessage(`最多只能附加 ${MAX_CHAT_IMAGES} 张图片`); - return; - } - - const next: ImageContent[] = []; - for (const file of list.slice(0, remaining)) { - try { - next.push(await fileToImageContent(file)); - } catch (err) { - addSystemMessage(err instanceof Error ? err.message : String(err)); - } - } - if (next.length) { - setPendingImages((prev) => [...prev, ...next].slice(0, MAX_CHAT_IMAGES)); - } - }; - - const removePendingImage = (index: number) => { - setPendingImages((prev) => prev.filter((_, i) => i !== index)); - }; - - const handleSend = async (mode: "prompt" | "steer" | "follow_up" = "prompt") => { - const text = value.trim(); - if (!text && pendingImages.length === 0) return; - - const images = pendingImages.length ? pendingImages : undefined; - setValue(""); - setPendingImages([]); - if (inputRef.current) inputRef.current.style.height = "auto"; - - if (text.startsWith("!") && parseBashInput(text)) { - await runBashCommand(text); - } else { - const sendMode = isStreaming && mode === "prompt" ? "steer" : mode; - await sendMessage(text, images, { mode: sendMode }); - } - - if (touchLike) inputRef.current?.blur(); - }; - - const handleKeyDown = (e: KeyboardEvent) => { - if (e.nativeEvent.isComposing) return; - - if (slashMenuOpen) { - if (e.key === "ArrowDown") { - e.preventDefault(); - setSelectedSlashIndex((prev) => (prev + 1) % filteredSlashCommands.length); - return; - } - if (e.key === "ArrowUp") { - e.preventDefault(); - setSelectedSlashIndex( - (prev) => (prev - 1 + filteredSlashCommands.length) % filteredSlashCommands.length, - ); - return; - } - if (e.key === "Tab") { - e.preventDefault(); - const command = filteredSlashCommands[selectedSlashIndex]; - if (command) applySlashSelection(command); - return; - } - if (e.key === "Escape") { - e.preventDefault(); - setValue((prev) => { - const trimmed = prev.trimStart(); - if (!trimmed.startsWith("/")) return prev; - return prev.replace(/^\s*\//, ""); - }); - return; - } - if (e.key === "Enter" && !e.shiftKey) { - e.preventDefault(); - const command = filteredSlashCommands[selectedSlashIndex]; - if (command) applySlashSelection(command); - return; - } - } - - if (e.key === "Enter" && e.shiftKey) { - e.preventDefault(); - void handleSend("follow_up"); - return; - } - - if (e.key === "Enter" && !e.shiftKey) { - e.preventDefault(); - void handleSend(isStreaming ? "steer" : "prompt"); - } - }; - - const handleBeforeInput = (e: React.FormEvent) => { - const native = e.nativeEvent as InputEvent; - if (touchLike && native.inputType === "insertLineBreak") { - e.preventDefault(); - void handleSend(isStreaming ? "steer" : "prompt"); - } - }; - - const handleInput = () => { - const el = inputRef.current; - if (!el) return; - el.style.height = "auto"; - el.style.height = `${Math.min(el.scrollHeight, 150)}px`; - }; - - const handlePaste = (e: ClipboardEvent) => { - const items = e.clipboardData?.items; - if (!items) return; - - const hasImage = Array.from(items).some((item) => item.type.startsWith("image/")); - if (!hasImage) return; - - e.preventDefault(); - void clipboardItemsToImages(items) - .then((images) => { - if (!images.length) return; - setPendingImages((prev) => { - const remaining = MAX_CHAT_IMAGES - prev.length; - if (remaining <= 0) { - addSystemMessage(`最多只能附加 ${MAX_CHAT_IMAGES} 张图片`); - return prev; - } - return [...prev, ...images.slice(0, remaining)]; - }); - }) - .catch((err) => { - addSystemMessage(err instanceof Error ? err.message : String(err)); - }); - }; - - const handleFileChange = (e: React.ChangeEvent) => { - const files = e.target.files; - if (files?.length) void addImages(files); - e.target.value = ""; - }; - - const handleDragOver = (e: DragEvent) => { - if (!e.dataTransfer.types.includes("Files")) return; - e.preventDefault(); - setDragOver(true); - }; - - const handleDragLeave = (e: DragEvent) => { - if (e.currentTarget.contains(e.relatedTarget as Node)) return; - setDragOver(false); - }; - - const handleDrop = (e: DragEvent) => { - e.preventDefault(); - setDragOver(false); - const files = Array.from(e.dataTransfer.files).filter((f) => f.type.startsWith("image/")); - if (files.length) void addImages(files); - }; - - return ( -
- {pendingImages.length > 0 ? ( -
- {pendingImages.map((img, index) => ( -
- - -
- ))} -
- ) : null} - {slashMenuOpen ? ( - - ) : null} -
- - -